Skip to content

Commit

Permalink
[libc++][hardening] Add _LIBCPP_ASSERT_NON_NULL to check for null p…
Browse files Browse the repository at this point in the history
…ointers (llvm#71428)
  • Loading branch information
var-const authored Nov 8, 2023
1 parent c86d35a commit b85fdc4
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 76 deletions.
10 changes: 10 additions & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@
// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like
// `optional` and `function` are considered one-element containers for the purposes of this check.
//
// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero
// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the
// memory security of a program (however, it is still undefined behavior that can result in strange errors due to
// compiler optimizations).
//
// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the
// given ranges do not overlap.
//
Expand Down Expand Up @@ -306,6 +311,8 @@
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
// Disabled checks.
// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access.
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security
// vulnerability.
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
Expand All @@ -320,6 +327,7 @@
// Enabled checks.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message)
Expand All @@ -333,6 +341,7 @@
// All checks enabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message)
Expand All @@ -345,6 +354,7 @@
// All checks disabled.
# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression)
# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression)
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/__memory/construct_at.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) {
_LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at");
_LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at");
return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
}

Expand All @@ -48,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Ar
#if _LIBCPP_STD_VER >= 20
return std::construct_at(__location, std::forward<_Args>(__args)...);
#else
return _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at"),
return _LIBCPP_ASSERT_NON_NULL(__location != nullptr, "null pointer given to construct_at"),
::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
#endif
}
Expand All @@ -65,15 +65,15 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
template <class _Tp, __enable_if_t<!is_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __destroy_at(_Tp* __loc) {
_LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
_LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
__loc->~_Tp();
}

#if _LIBCPP_STD_VER >= 20
template <class _Tp, __enable_if_t<is_array<_Tp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __destroy_at(_Tp* __loc) {
_LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at");
_LIBCPP_ASSERT_NON_NULL(__loc != nullptr, "null pointer given to destroy_at");
std::__destroy(std::begin(*__loc), std::end(*__loc));
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/__ranges/lazy_split_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>

_LIBCPP_HIDE_FROM_ABI
friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
_LIBCPP_ASSERT_UNCATEGORIZED(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
_LIBCPP_ASSERT_NON_NULL(__x.__parent_ != nullptr, "Cannot call comparison on a default-constructed iterator.");
return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_;
}
};
Expand Down Expand Up @@ -311,7 +311,7 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>

_LIBCPP_HIDE_FROM_ABI
constexpr bool __is_done() const {
_LIBCPP_ASSERT_UNCATEGORIZED(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
_LIBCPP_ASSERT_NON_NULL(__i_.__parent_ != nullptr, "Cannot call comparison on a default-constructed iterator.");

auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_};
auto __end = ranges::end(__i_.__parent_->__base_);
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/fstream
Original file line number Diff line number Diff line change
Expand Up @@ -750,8 +750,8 @@ basic_filebuf<_CharT, _Traits>::underflow()
else
{
if (__extbufend_ != __extbufnext_) {
_LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
_LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
_LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
_LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
_VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
}
__extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/future
Original file line number Diff line number Diff line change
Expand Up @@ -1387,7 +1387,7 @@ template <class _Rp>
void
promise<_Rp>::set_exception(exception_ptr __p)
{
_LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
_LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception: received nullptr" );
if (__state_ == nullptr)
__throw_future_error(future_errc::no_state);
__state_->set_exception(__p);
Expand Down Expand Up @@ -1415,7 +1415,7 @@ template <class _Rp>
void
promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
{
_LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
_LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
if (__state_ == nullptr)
__throw_future_error(future_errc::no_state);
__state_->set_exception_at_thread_exit(__p);
Expand Down Expand Up @@ -1519,7 +1519,7 @@ template <class _Rp>
void
promise<_Rp&>::set_exception(exception_ptr __p)
{
_LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" );
_LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception: received nullptr" );
if (__state_ == nullptr)
__throw_future_error(future_errc::no_state);
__state_->set_exception(__p);
Expand All @@ -1538,7 +1538,7 @@ template <class _Rp>
void
promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
{
_LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
_LIBCPP_ASSERT_NON_NULL( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" );
if (__state_ == nullptr)
__throw_future_error(future_errc::no_state);
__state_->set_exception_at_thread_exit(__p);
Expand Down
4 changes: 2 additions & 2 deletions libcxx/include/locale
Original file line number Diff line number Diff line change
Expand Up @@ -3997,8 +3997,8 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP
else
{
if (__extbufend_ != __extbufnext_) {
_LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr");
_LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr");
_LIBCPP_ASSERT_NON_NULL(__extbufnext_ != nullptr, "underflow moving from nullptr");
_LIBCPP_ASSERT_NON_NULL(__extbuf_ != nullptr, "underflow moving into nullptr");
_VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_);
}
__extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_);
Expand Down
Loading

0 comments on commit b85fdc4

Please sign in to comment.