Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc++] Add an ABI setting to harden unique_ptr<T[]>::operator[] #91798

Merged
merged 1 commit into from
Sep 27, 2024

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented May 10, 2024

This allows catching OOB accesses inside unique_ptr<T[]> when the size
of the allocation is known. The size of the allocation can be known when
the unique_ptr has been created with make_unique & friends or when the
type necessitates an array cookie before the allocation.

@ldionne ldionne requested a review from a team as a code owner May 10, 2024 19:41
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label May 10, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 10, 2024

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/91798.diff

5 Files Affected:

  • (modified) libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake (+1-1)
  • (modified) libcxx/include/__config (+3)
  • (modified) libcxx/include/__memory/unique_ptr.h (+34-2)
  • (added) libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp (+42)
  • (modified) libcxx/utils/libcxx/test/features.py (+1)
diff --git a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
index 4860b590dcde9..e9c90cc6bedf8 100644
--- a/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
+++ b/libcxx/cmake/caches/Generic-hardening-mode-fast-with-abi-breaks.cmake
@@ -1,2 +1,2 @@
 set(LIBCXX_HARDENING_MODE "fast" CACHE STRING "")
-set(LIBCXX_ABI_DEFINES "_LIBCPP_ABI_BOUNDED_ITERATORS" CACHE STRING "")
+set(LIBCXX_ABI_DEFINES "_LIBCPP_ABI_BOUNDED_ITERATORS;_LIBCPP_ABI_BOUNDED_UNIQUE_PTR" CACHE STRING "")
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 104a244cc82cc..26b3a1e4c1115 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -206,6 +206,9 @@
 // - `array`.
 // #define _LIBCPP_ABI_BOUNDED_ITERATORS
 
+// Tracks the bounds of the array owned by std::unique_ptr<T[]>, allowing it to trap when accessed out-of-bounds.
+// #define _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
+
 // } ABI
 
 // HARDENING {
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 46d9405e31596..2ad28e25a7af7 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -39,6 +39,7 @@
 #include <__type_traits/type_identity.h>
 #include <__utility/forward.h>
 #include <__utility/move.h>
+#include <__utility/private_constructor_tag.h>
 #include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -301,6 +302,21 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
 
 private:
   __compressed_pair<pointer, deleter_type> __ptr_;
+#ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
+  // Under the "bounded unique_ptr" ABI, we store the size of the allocation when it is known.
+  // The size of the allocation can be known when unique_ptr is created via make_unique or a
+  // similar API, however it can't be known when constructed with e.g.
+  //
+  //    unique_ptr<T[]> ptr(new T[3]);
+  //
+  // In that case, we don't know the size of the allocation from within the unique_ptr.
+  // Semantically, we'd need to store `optional<size_t>`. However, since that is really
+  // heavy weight, we instead store a size_t and use 0 as a magic value meaning that we
+  // don't know the size. This means that we can't catch OOB accesses inside a unique_ptr
+  // with a 0-sized allocation, however since this is a degenerate case, it doesn't matter
+  // in practice.
+  size_t __size_ = 0;
+#endif
 
   template <class _From>
   struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
@@ -397,6 +413,18 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr(unique_ptr&& __u) _NOEXCEPT
       : __ptr_(__u.release(), std::forward<deleter_type>(__u.get_deleter())) {}
 
+  // Constructor used by make_unique & friends to pass the size that was allocated
+  template <class _Ptr>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit unique_ptr(
+      __private_constructor_tag, _Ptr __ptr, size_t __size) _NOEXCEPT
+      : __ptr_(__ptr, __value_init_tag())
+#ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
+      ,
+        __size_(__size)
+#endif
+  {
+  }
+
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
     reset(__u.release());
     __ptr_.second() = std::forward<deleter_type>(__u.get_deleter());
@@ -434,6 +462,10 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp>
   }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 __add_lvalue_reference_t<_Tp> operator[](size_t __i) const {
+#ifdef _LIBCPP_ABI_BOUNDED_UNIQUE_PTR
+    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+        __size_ == 0 || __i < __size_, "unique_ptr<T[]>::operator[](index): index out of range");
+#endif
     return __ptr_.first()[__i];
   }
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 pointer get() const _NOEXCEPT { return __ptr_.first(); }
@@ -624,7 +656,7 @@ template <class _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
 make_unique(size_t __n) {
   typedef __remove_extent_t<_Tp> _Up;
-  return unique_ptr<_Tp>(new _Up[__n]());
+  return unique_ptr<_Tp>(__private_constructor_tag(), new _Up[__n](), __n);
 }
 
 template <class _Tp, class... _Args>
@@ -643,7 +675,7 @@ make_unique_for_overwrite() {
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __unique_if<_Tp>::__unique_array_unknown_bound
 make_unique_for_overwrite(size_t __n) {
-  return unique_ptr<_Tp>(new __remove_extent_t<_Tp>[__n]);
+  return unique_ptr<_Tp>(__private_constructor_tag(), new __remove_extent_t<_Tp>[__n], __n);
 }
 
 template <class _Tp, class... _Args>
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
new file mode 100644
index 0000000000000..dd722f0c838ef
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: has-unix-headers
+// UNSUPPORTED: c++03, c++11
+// UNSUPPORTED: libcpp-hardening-mode=none
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+// REQUIRES: libcpp-has-abi-bounded-unique_ptr
+
+// <memory>
+//
+// unique_ptr<T[]>
+//
+// T& operator[](std::size_t);
+
+// This test ensures that we catch an out-of-bounds access in std::unique_ptr<T[]>::operator[]
+// when unique_ptr has the appropriate ABI configuration.
+
+#include <memory>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+  {
+    std::unique_ptr<int[]> ptr = std::make_unique<int[]>(5);
+    TEST_LIBCPP_ASSERT_FAILURE(ptr[6] = 42, "unique_ptr<T[]>::operator[](index): index out of range");
+  }
+
+#if TEST_STD_VER >= 20
+  {
+    std::unique_ptr<int[]> ptr = std::make_unique_for_overwrite<int[]>(5);
+    TEST_LIBCPP_ASSERT_FAILURE(ptr[6] = 42, "unique_ptr<T[]>::operator[](index): index out of range");
+  }
+#endif
+
+  return 0;
+}
diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index c81b56b1af547..f154840430ec5 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -312,6 +312,7 @@ def _getAndroidDeviceApi(cfg):
     "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime",
     "_LIBCPP_ABI_VERSION": "libcpp-abi-version",
     "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators",
+    "_LIBCPP_ABI_BOUNDED_UNIQUE_PTR": "libcpp-has-abi-bounded-unique_ptr",
     "_LIBCPP_HAS_NO_FILESYSTEM": "no-filesystem",
     "_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device",
     "_LIBCPP_HAS_NO_LOCALIZATION": "no-localization",

@ldionne
Copy link
Member Author

ldionne commented May 10, 2024

Note that this patch is kind of a WIP. Another approach could be to query the compiler or the system allocator for the size of the allocation. I actually think the compiler knows the size of the allocation cause it encodes it at the front of the allocation when calling operator new[], but I have to refresh my memory on this.

Copy link

github-actions bot commented May 10, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@efriedma-quic
Copy link
Collaborator

I actually think the compiler knows the size of the allocation cause it encodes it at the front of the allocation

Only when the element type has a non-trivial destructor.

@EricWF
Copy link
Member

EricWF commented May 10, 2024

A couple of things I would like us to investigate:

  1. Can we stash the size before the the array we allocate?
  2. What effect does this have on unique_ptr being passed in registers?

@jkorous-apple
Copy link
Contributor

jkorous-apple commented May 14, 2024

I actually think the compiler knows the size of the allocation cause it encodes it at the front of the allocation

Only when the element type has a non-trivial destructor.

That sounds like for such types we could use it for runtime check in operator[] without changing the layout. Is that right?
Do you see any catch?

EDIT: How crazy would it be to allow this for all types?

@efriedma-quic
Copy link
Collaborator

https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies describes array cookies. If the cookie is present, I can't think of any reason it would be a problem for libc++ to read it.

If the cookie isn't present, though, we can't access it, and forcing the compiler to generate a cookie where it normally wouldn't generate one is ABI break.

@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from 4841e1a to 253485d Compare August 23, 2024 19:23
@ldionne
Copy link
Member Author

ldionne commented Aug 23, 2024

I updated the patch with a WIP attempt to use the array cookie when one is present. There are still things to fix and comments to address (e.g. maybe using SIZE_MAX is better to eliminate a branch), but I wanted to get this draft out there for comments. I think it's a pretty clever improvement to unique_ptr.

@ldionne
Copy link
Member Author

ldionne commented Aug 26, 2024

@vitalybuka I just stumbled upon -fno-sanitize-address-poison-custom-array-cookie and learned that ASAN sometimes poisons array cookies when a custom operator new is in use. I'm not certain I understand why poisoning the array cookie is legal even when we have a custom operator new[], but it seems like poisoning array cookies would interact badly with this patch. Do you have thoughts?

@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from 253485d to 4a453cf Compare August 26, 2024 21:23
// TODO: Use a builtin instead
// TODO: We should factor in the choice of the usual deallocation function in this determination.
template <class _Tp>
struct __has_array_cookie : _Not<is_trivially_destructible<_Tp> > {};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@efriedma-quic What do you think about this? It is a bit more conservative than we could be, but I don't really want to start trying to implement the resolution of operator delete[] in the library. It looks like a compiler builtin should be fairly easy to provide for both getting the array cookie and telling us whether an array cookie is available.

I'm curious to know whether you think this is a reasonable first implementation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable for now.

@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from 4a453cf to 0f56d47 Compare August 28, 2024 18:04
@vitalybuka
Copy link
Collaborator

vitalybuka commented Aug 29, 2024

@vitalybuka I just stumbled upon -fno-sanitize-address-poison-custom-array-cookie and learned that ASAN sometimes poisons array cookies when a custom operator new is in use. I'm not certain I understand why poisoning the array cookie is legal even when we have a custom operator new[], but it seems like poisoning array cookies would interact badly with this patch. Do you have thoughts?

I see this feature for the first time :)

Looks like @filcab added the feature. Before that custom new was omitted, then
https://reviews.llvm.org/D41301 made it more aggressive
https://reviews.llvm.org/D52615 added a flag to protect the behavior change from the patch above

And the doc string was gone with https://reviews.llvm.org/D133349

I believe this is off by default "use at your own risk" feature.

I guess it should be easy to support this case by __attribute__((no_sanitize("address"))) on __get_array_cookie

@ldionne ldionne added the hardening Issues related to the hardening effort label Sep 11, 2024
@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from 3aae45d to ffd681f Compare September 17, 2024 18:20
@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from ffd681f to c37a05e Compare September 25, 2024 18:51
This patch adds an ABI configuration that allows bounds-checking in
unique_ptr<T[]>::operator[] when it has been constructed with bounds
information in the API.

The patch also adds support for bounds-checking when an array cookie
is known to exist, which allows validating bounds without even changing
the ABI.

Drive-by changes:
- Improve the tests for `operator[]`
- Improve the tests for `.get()`
- Add a test for incomplete types support
@ldionne ldionne force-pushed the review/harden-unique_ptr-array branch from b23d82d to 76fc808 Compare September 26, 2024 17:23
@ldionne ldionne merged commit 45a09d1 into llvm:main Sep 27, 2024
65 checks passed
@ldionne ldionne deleted the review/harden-unique_ptr-array branch September 27, 2024 12:49
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 27, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux-android running on sanitizer-buildbot-android while building libcxx at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/186/builds/2730

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
PASS: SanitizerCommon-asan-aarch64-Android :: Posix/posix_memalign-alignment.cpp (218 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Linux/odr-vtable.cpp (219 of 1709)
PASS: HWAddressSanitizer-aarch64 :: TestCases/mem-intrinsics.c (220 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/atol_strict.c (221 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Linux/clone_test.cpp (222 of 1709)
PASS: HWAddressSanitizer-aarch64 :: TestCases/use-after-free.c (223 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Posix/halt_on_error-torture.cpp (224 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/global-overflow.cpp (225 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/atoll_strict.c (226 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/double-free.cpp (227 of 1709)
FAIL: HWAddressSanitizer-aarch64 :: TestCases/hwasan_symbolize_stack_overflow.cpp (228 of 1709)
******************** TEST 'HWAddressSanitizer-aarch64 :: TestCases/hwasan_symbolize_stack_overflow.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: rm -rf /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp; mkdir /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
+ rm -rf /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
+ mkdir /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
RUN: at line 2: /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang   --target=aarch64-linux-android24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64  -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  -fuse-ld=lld  -gline-tables-only -fsanitize=hwaddress -fuse-ld=lld -mllvm -hwasan-globals -mllvm -hwasan-use-short-granules -mllvm -hwasan-instrument-landing-pads=0 -mllvm -hwasan-instrument-personality-functions -Wl,--build-id -g /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow
+ /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang --target=aarch64-linux-android24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -fuse-ld=lld -gline-tables-only -fsanitize=hwaddress -fuse-ld=lld -mllvm -hwasan-globals -mllvm -hwasan-use-short-granules -mllvm -hwasan-instrument-landing-pads=0 -mllvm -hwasan-instrument-personality-functions -Wl,--build-id -g /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow
RUN: at line 3: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 16 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER0
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 16
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER0
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 4: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 17 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER1
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 17
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER1
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 5: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -1 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE1
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -1
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE1
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 6: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -17 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE17
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -17
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE17
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
Step 31 (run lit tests [aarch64/bluejay-userdebug/TQ3A.230805.001]) failure: run lit tests [aarch64/bluejay-userdebug/TQ3A.230805.001] (failure)
...
PASS: SanitizerCommon-asan-aarch64-Android :: Posix/posix_memalign-alignment.cpp (218 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Linux/odr-vtable.cpp (219 of 1709)
PASS: HWAddressSanitizer-aarch64 :: TestCases/mem-intrinsics.c (220 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/atol_strict.c (221 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Linux/clone_test.cpp (222 of 1709)
PASS: HWAddressSanitizer-aarch64 :: TestCases/use-after-free.c (223 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/Posix/halt_on_error-torture.cpp (224 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/global-overflow.cpp (225 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/atoll_strict.c (226 of 1709)
PASS: AddressSanitizer-aarch64-android :: TestCases/double-free.cpp (227 of 1709)
FAIL: HWAddressSanitizer-aarch64 :: TestCases/hwasan_symbolize_stack_overflow.cpp (228 of 1709)
******************** TEST 'HWAddressSanitizer-aarch64 :: TestCases/hwasan_symbolize_stack_overflow.cpp' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: rm -rf /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp; mkdir /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
+ rm -rf /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
+ mkdir /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp
RUN: at line 2: /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang   --target=aarch64-linux-android24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64  -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta  -fuse-ld=lld  -gline-tables-only -fsanitize=hwaddress -fuse-ld=lld -mllvm -hwasan-globals -mllvm -hwasan-use-short-granules -mllvm -hwasan-instrument-landing-pads=0 -mllvm -hwasan-instrument-personality-functions -Wl,--build-id -g /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow
+ /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/sanitizer_common/android_commands/android_compile.py /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/bin/clang --target=aarch64-linux-android24 --sysroot=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot --gcc-toolchain=/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -B/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/android_ndk/toolchains/llvm/prebuilt/linux-x86_64 -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -fuse-ld=lld -gline-tables-only -fsanitize=hwaddress -fuse-ld=lld -mllvm -hwasan-globals -mllvm -hwasan-use-short-granules -mllvm -hwasan-instrument-landing-pads=0 -mllvm -hwasan-instrument-personality-functions -Wl,--build-id -g /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp -o /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow
RUN: at line 3: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 16 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER0
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 16
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER0
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 4: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 17 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER1
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow 17
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,AFTER1
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 5: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -1 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE1
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -1
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE1
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so
RUN: at line 6: env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not  /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -17 2>&1 | hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index | FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE17
+ env HWASAN_OPTIONS=disable_allocator_tagging=1:random_tags=0:fail_without_syscall_abi=0:abort_on_error=0:symbolize=0 not /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp/hwasan_overflow -17
+ hwasan_symbolize --symbols /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/compiler_rt_build_android_aarch64/test/hwasan/AARCH64/TestCases/Output/hwasan_symbolize_stack_overflow.cpp.tmp --index
+ FileCheck /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm-project/compiler-rt/test/hwasan/TestCases/hwasan_symbolize_stack_overflow.cpp --check-prefixes=CHECK,BEFORE17
/var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux-android/build/llvm_build64/./bin/hwasan_symbolize:319: SyntaxWarning: invalid escape sequence '\['
  m = re.match(r'.*?(0x[0-9a-f]+):' + '([ ]*[\[ ][0-9a-f][0-9a-f]\]?)' * 16, line)
Could not find symbols for apex/com.android.runtime/lib64/bionic/libc.so

@ldionne
Copy link
Member Author

ldionne commented Sep 27, 2024

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux-android running on sanitizer-buildbot-android while building libcxx at step 2 "annotate".
[...]

I looked into it and I don't think this is caused by the patch, since the test doesn't use unique_ptr.

Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
…vm#91798)

This allows catching OOB accesses inside `unique_ptr<T[]>` when the size
of the allocation is known. The size of the allocation can be known when
the unique_ptr has been created with make_unique & friends or when the
type necessitates an array cookie before the allocation.
llvm-beanz added a commit to llvm-beanz/llvm-project that referenced this pull request Sep 28, 2024
ldionne added a commit that referenced this pull request Sep 30, 2024
…1798)

This allows catching OOB accesses inside `unique_ptr<T[]>` when the size
of the allocation is known. The size of the allocation can be known when
the unique_ptr has been created with make_unique & friends or when the
type necessitates an array cookie before the allocation.

This is a re-aplpication of 45a09d1 which had been reverted in
f11abac due to unrelated CI failures.
@nico
Copy link
Contributor

nico commented Sep 30, 2024

This makes the attached program crash (…in most runs, not 100% of the time):

unique.cc.zip

 % out/gn/bin/clang++ unique.cc -isysroot $(xcrun -show-sdk-path) -std=c++20 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE     
% ./a.out
zsh: trace trap  ./a.out

lldb shows that this indeed this check:

    frame #0: 0x00000001000029e4 a.out`std::__1::unique_ptr<std::__1::vector<int, std::__1::allocator<int>> [], AlignedDeleter<std::__1::vector<int, std::__1::allocator<int>>>>::operator[][abi:se200000](unsigned long) const [inlined] __clang_trap_msg$libc++$/Users/thakis/src/llvm-project/out/gn/bin/../include/c++/v1/__memory/unique_ptr.h:566: assertion __checker_.__in_bounds(std::__to_address(__ptr_), __i) failed: unique_ptr<T[]>::operator[](index): index out of range

The program uses a unique_ptr with a custom deleter to refer to raw malloc-ed memory, "to allow having uninitialized entries inside it".

It has this typedef:

template <typename T>
using AlignedUniquePtr =
    std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;

It uses this typedef with an array type:

  // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
  // to allow having uninitialized entries inside it.
  AlignedUniquePtr<T[]> entries_;

It creates objects of this unique_ptr like so:

template <typename T>
AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
  using TU = typename std::remove_extent<T>::type;
  return AlignedUniquePtr<T>(
      static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
}

AlignedAlloc() is basically malloc – in particular, nothing calls new[], so it doesn't write an array cookie.

The custom deleter looks like so (AlignedFree() is just free()):

template <typename T>
struct AlignedDeleter {
  inline void operator()(T* ptr) const { AlignedFree(ptr); }
};

The class containing entries_ calls dtors as needed, and the deleter really only needs to free memory. delete [] is never called.

Is this a valid use of unique_ptr<T[]>? If so, should this hardening only be used for unique_ptrs that don't have a custom deleter?

@nico
Copy link
Contributor

nico commented Oct 1, 2024

Looking through 20.3.1.4 unique_ptr for array objects with a runtime length [unique.ptr.runtime], it says "— The default deleter will call delete[]." which implies that looking for the array cookie on itanium is ok with the default deleter, but other than that it doesn't say anything. So I think the code in the example is probably correct, and this diagnostic isn't – with a custom deleter, it can introduce an out-of-bounds read for valid code.

@ldionne
Copy link
Member Author

ldionne commented Oct 1, 2024

I think you're entirely correct. I'm working on a patch.

@ldionne
Copy link
Member Author

ldionne commented Oct 1, 2024

In fact, the memory held by the unique_ptr would not even have to be allocated. It could point to a stack variable and the deleter could be a no-op. In that sense, unique_ptr with a custom deleter is a bit closer to a scope_guard. I think I had that in mind when I made the first implementation a few months, but when I picked it back up recently I remember thinking "oh well it works for custom deleters as well" -- but that was a mistake.

VitaNuo pushed a commit to VitaNuo/llvm-project that referenced this pull request Oct 2, 2024
…vm#91798)

This allows catching OOB accesses inside `unique_ptr<T[]>` when the size
of the allocation is known. The size of the allocation can be known when
the unique_ptr has been created with make_unique & friends or when the
type necessitates an array cookie before the allocation.

This is a re-aplpication of 45a09d1 which had been reverted in
f11abac due to unrelated CI failures.
VitaNuo pushed a commit to VitaNuo/llvm-project that referenced this pull request Oct 2, 2024
…vm#91798)

This allows catching OOB accesses inside `unique_ptr<T[]>` when the size
of the allocation is known. The size of the allocation can be known when
the unique_ptr has been created with make_unique & friends or when the
type necessitates an array cookie before the allocation.

This is a re-aplpication of 45a09d1 which had been reverted in
f11abac due to unrelated CI failures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hardening Issues related to the hardening effort libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants