[libcxx-commits] [PATCH] D155873: [libc++][hardening] Categorize more assertions.
Louis Dionne via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jul 20 12:35:38 PDT 2023
ldionne added inline comments.
================
Comment at: libcxx/include/__config:279
// clang-format off
# if _LIBCPP_ENABLE_HARDENED_MODE
----------------
It would be great to rebase this on top of D155866.
================
Comment at: libcxx/include/__config:287
// Disabled checks.
+# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
----------------
Here we could add a short comment rationalizing the choice: `Nullptr conditions are generally meant to protect against dereferencing a null pointer, which generally results in a crash`.
================
Comment at: libcxx/include/__hash_table:1112
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__n < bucket_count(),
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(),
"unordered container::begin(n) called with n >= bucket_count()");
----------------
It would be nice to make sure that all the non-internal assertions we add are tested. In some cases this will mean removing `XFAIL` on an existing test, in other cases we'll need to add some tests but it should be easy.
================
Comment at: libcxx/include/__string/char_traits.h:145
if (!__libcpp_is_constant_evaluated()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
}
----------------
Maybe `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES`? Both ranges can technically be valid ranges yet still be overlapping. Also, the result of the algo will be incorrect if the ranges overlap but I don't think this can directly cause bad stuff to happen, so I don't think we want this in the hardened mode. Using another category would allow excluding it.
================
Comment at: libcxx/include/string:956
: __r_(__default_init_tag(), __default_init_tag()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
+ _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
__init(__s, __n);
----------------
I think a lot of these `NON_NULL` checks are actually `VALID_RANGE` checks. http://eel.is/c++draft/iterators#iterator.requirements.general-11
Here we seem to be using `__s != nullptr` as a way to say `__s` is dereferenceable. Do we want to move these checks to `ASSERT_VALID_RANGE`? Do we want these checks in hardened mode? I'm not sure, I think we should probably review this with a security specialist.
================
Comment at: libcxx/include/string:963
: __r_(__default_init_tag(), __a) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr,
- "basic_string(const char*, n, allocator) detected nullptr");
+ _LIBCPP_ASSERT_NON_NULL(__n == 0 || __s != nullptr,
+ "basic_string(const char*, n, allocator) detected nullptr");
----------------
Separate from the `ASSERT_VALID_RANGE` question, do we want to introduce helper functions to help checking whether a range is valid?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D155873/new/
https://reviews.llvm.org/D155873
More information about the libcxx-commits
mailing list