aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/filesystem/operations.cpp
diff options
context:
space:
mode:
authorKonstantin Varlamov <varconsteq@gmail.com>2024-01-22 18:12:58 -0800
committerGitHub <noreply@github.com>2024-01-22 18:12:58 -0800
commit6082478e1a5bde8ac03ac7220b733313a5417a13 (patch)
tree93ca6809da22f7ffd0c0fa2986c439da7529226b /libcxx/src/filesystem/operations.cpp
parent8c680451a5eff02dd7e5004b69e05b3744f4e1aa (diff)
downloadllvm-6082478e1a5bde8ac03ac7220b733313a5417a13.zip
llvm-6082478e1a5bde8ac03ac7220b733313a5417a13.tar.gz
llvm-6082478e1a5bde8ac03ac7220b733313a5417a13.tar.bz2
[libc++][hardening] Classify assertions related to leaks and syscalls. (#77164)
Introduce two new categories: - `_LIBCPP_ASSERT_VALID_DEALLOCATION`; - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL`.
Diffstat (limited to 'libcxx/src/filesystem/operations.cpp')
-rw-r--r--libcxx/src/filesystem/operations.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp
index 8a7d6cc..6253d15 100644
--- a/libcxx/src/filesystem/operations.cpp
+++ b/libcxx/src/filesystem/operations.cpp
@@ -460,8 +460,21 @@ path __current_path(error_code* ec) {
typedef decltype(&::free) Deleter;
Deleter deleter = &::free;
#else
+ errno = 0; // Note: POSIX mandates that modifying `errno` is thread-safe.
auto size = ::pathconf(".", _PC_PATH_MAX);
- _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size");
+ if (size == -1) {
+ if (errno != 0) {
+ return err.report(capture_errno(), "call to pathconf failed");
+
+ // `pathconf` returns `-1` without an error to indicate no limit.
+ } else {
+# if defined(__MVS__) && !defined(PATH_MAX)
+ size = _XOPEN_PATH_MAX + 1;
+# else
+ size = PATH_MAX + 1;
+# endif
+ }
+ }
auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]);
path::value_type* ptr = buff.get();
@@ -620,7 +633,9 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec)
set_sym_perms = is_symlink(st);
if (m_ec)
return err.report(m_ec);
- _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown, "Permissions unexpectedly unknown");
+ // TODO(hardening): double-check this assertion -- it might be a valid (if rare) case when the permissions are
+ // unknown.
+ _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(st.permissions() != perms::unknown, "Permissions unexpectedly unknown");
if (add_perms)
prms |= st.permissions();
else if (remove_perms)
@@ -667,7 +682,7 @@ path __read_symlink(const path& p, error_code* ec) {
detail::SSizeT ret;
if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1)
return err.report(capture_errno());
- _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO");
+ // Note that `ret` returning `0` would work, resulting in a valid empty string being returned.
if (static_cast<size_t>(ret) >= size)
return err.report(errc::value_too_large);
buff[ret] = 0;