diff options
author | Konstantin Varlamov <varconsteq@gmail.com> | 2024-01-22 18:12:58 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-22 18:12:58 -0800 |
commit | 6082478e1a5bde8ac03ac7220b733313a5417a13 (patch) | |
tree | 93ca6809da22f7ffd0c0fa2986c439da7529226b /libcxx/src/filesystem/operations.cpp | |
parent | 8c680451a5eff02dd7e5004b69e05b3744f4e1aa (diff) | |
download | llvm-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.cpp | 21 |
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; |