intel / intel/confidential-computing.sgx.sdk
Asan crash in libcxx detected during research
- Dominant language
- C++
- Stars
- 2
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
We recently developed an auto testing tool, which supports the address sanitizer (Asan), for the sgx application. For the testing of Cxx11SGXDemo, we added -fsanitize=address into the Enclave_C_Flags, -lasan -lm into Enclave_Link_Flags. And we found three unknown Asan crashes in the libcxx/include:
1. The error is reported as:
```
==21995==ERROR: AddressSanitizer: unknown-crash on address 0x7ffff4f9f0d0 at pc 0x7ffff4131f39 bp 0x7ffff5509330 sp 0x7ffff5509320
WRITE of size 8 at 0x7ffff4f9f0d0 thread T0
```
when the unordered_set constructs itself:
`std::unordered_set set_of_numbers = { 0, 1, 2, 3, 4, 5 }; `
from
`void ecall_new_container_classes_demo()` in Enclave/TrustedLibrary/Libcxx.cpp
To be more specific:
The _Nodeptr ` __next_` could not be accessed when running `__h->__next_ = nullptr;` inside
```
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(
size_t __hash, _First&& __f, _Rest&& ...__rest)
{
__new_node->__left_ = nullptr;
__new_node->__right_ = nullptr;
__new_node->__parent_ = __parent;
// __new_node->__is_black_ is initialized in __tree_balance_after_insert
__child = __new_node;
if (__begin_node()->__left_ != nullptr)
__begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_);
__tree_balance_after_insert(__end_node()->__left_, __child);
++size();
}
```
in libcxx/__hash_table
2. The error is reported as:
```
==17585==ERROR: AddressSanitizer: unknown-crash on address 0x7ffff4f9f0f8 at pc 0x7ffff413cdd7 bp 0x7ffff55099e0 sp 0x7ffff55099d0
WRITE of size 8 at 0x7ffff4f9f0f8 thread T0
```
when the map constructs itself:
`std::map map_of_letters = { {'B','b' } }; `
from
`void ecall_tuple_demo()` in Enclave/TrustedLibrary/Libcxx.cpp
To be more specific:
The pointer `__right_` could not be accessed when running `__new_node->__right_ = nullptr;` inside
```
void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
__parent_pointer __parent, __node_base_pointer& __child,
__node_base_pointer __new_node){
static_assert(!__is_hash_value_type<_First, _Rest...>::value,
"Construct cannot be called with a hash value type");
__node_allocator& __na = __node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_),
_VSTD::forward<_First>(__f),
_VSTD::forward<_Rest>(__rest)...);
__h.get_deleter().__value_constructed = true;
__h->__hash_ = __hash;
__h->__next_ = nullptr;
return __h;
}
```
in libcxx/__tree
3. The error is reported as:
```
==11433==ERROR: AddressSanitizer: unknown-crash on address 0x7ffff4f9f0d0 at pc 0x7ffff412d223 bp 0x7ffff550a7c0 sp 0x7ffff550a7b0
WRITE of size 8 at 0x7ffff4f9f0d0 thread T0
```
when the shared_ptr constructs itself:
` auto shared_ptr = std::make_shared("smart_ptr."); `
from
`void ecall_shared_ptr_demo()` in Enclave/TrustedLibrary/Libcxx.cpp
To be more specific:
The function _`shared_count(long __refs = 0)` could not be accessed in
```
class _LIBCPP_TYPE_VIS __shared_count
{
__shared_count(const __shared_count&);
__shared_count& operator=(const __shared_count&);
protected:
long __shared_owners_;
virtual ~__shared_count();
private:
virtual void __on_zero_shared() _NOEXCEPT = 0;
public:
_LIBCPP_INLINE_VISIBILITY
explicit __shared_count(long __refs = 0) _NOEXCEPT
: __shared_owners_(__refs) {}
```
For the debugging, here is what we have tried:
1. We tried to run the same code using the libc++ without the sgx-sdk, there is not crash reported by the sanitizer. And we believed, with high probability, it is not a false positive relating with the sanitizer.
2. We checked the process of the ./app running, the malloc (sbrk) being called during the allocation is inside the tlibc/stdlib/malloc.c (tlibc/gen/sbrk.c).
3. Since some of the codes of libcxx have not been updated for few years, we compared two files, map and __tree, in sgxsdk/include/llibcxx with the llvm's (https://github.com/llvm/llvm-project/tree/master/libcxx/include). We patched them with the current version of llvm's besides the function/class relating with _NodeTypes and unique_ptr and the crash still exists.
We suspect that something inside the unique_ptr causes the crash, since the make_shared also refers the unique_ptr. However, we have limited knowledge about the how unique_ptr and shared_ptr are constructed. We hope the information provided could help you find some potential bugs in this project.
For the detailed back trace info:
1.
```
Breakpoint 1, libsfuzz_ocall_isatty (retval=0x7ffff5507fd8, fd=2) at Enclave/Enclave_t.c:834
834 sgx_status_t status = SGX_SUCCESS;
#0 libsfuzz_ocall_isatty (retval=0x7ffff5507fd8, fd=2) at Enclave/Enclave_t.c:834
intel/confidential-computing.sgx#1 0x00007ffff4149d68 in isatty (fd=2) at libsgx_tsgxfuzz.c:782
intel/confidential-computing.sgx#2 0x00007ffff4294e19 in __sanitizer::SupportsColoredOutput(int) ()
intel/confidential-computing.sgx#3 0x00007ffff42a15af in __sanitizer::ReportFile::SupportsColors() ()
intel/confidential-computing.sgx#4 0x00007ffff42bbdcc in __asan::ErrorGeneric::Print() ()
intel/confidential-computing.sgx#5 0x00007ffff428cf60 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
intel/confidential-computing.sgx#6 0x00007ffff428e28a in __asan_report_store8 ()
intel/confidential-computing.sgx#7 0x00007ffff4131f39 in std::__1::__hash_table, std::__1::equal_to, std::__1::allocator >::__construct_node_hash (this=0x7ffff550b450, __hash=0,
__f=@0x7ffff42d7d80: 0) at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__hash_table:2284
intel/confidential-computing.sgx#8 0x00007ffff4122557 in std::__1::__hash_table, std::__1::equal_to, std::__1::allocator >::__emplace_unique_key_args (__k=@0x7ffff42d7d80: 0,
this=0x7ffff550b450) at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__hash_table:2000
intel/confidential-computing.sgx#9 std::__1::__hash_table, std::__1::equal_to, std::__1::allocator >::__insert_unique (__x=@0x7ffff42d7d80: 0, this=0x7ffff550b450)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__hash_table:1140
intel/confidential-computing.sgx#10 std::__1::unordered_set, std::__1::equal_to, std::__1::allocator >::insert (__last=0x7ffff42d7d98, __first=0x7ffff42d7d80 <._38>, this=0x7ffff550b450)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/unordered_set:833
intel/confidential-computing.sgx#11 std::__1::unordered_set, std::__1::equal_to, std::__1::allocator >::unordered_set (this=0x7ffff550b450, __il=...)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/unordered_set:766
intel/confidential-computing.sgx#12 0x00007ffff410d85e in ecall_new_container_classes_demo ()
at Enclave/TrustedLibrary/Libcxx.cpp:594
```
2.
```
Breakpoint 1, libsfuzz_ocall_isatty (retval=0x7ffff5508218, fd=2) at Enclave/Enclave_t.c:834
834 sgx_status_t status = SGX_SUCCESS;
#0 libsfuzz_ocall_isatty (retval=0x7ffff5508218, fd=2) at Enclave/Enclave_t.c:834
intel/confidential-computing.sgx#1 0x00007ffff4149d68 in isatty (fd=2) at libsgx_tsgxfuzz.c:782
intel/confidential-computing.sgx#2 0x00007ffff4294e19 in __sanitizer::SupportsColoredOutput(int) ()
intel/confidential-computing.sgx#3 0x00007ffff42a15af in __sanitizer::ReportFile::SupportsColors() ()
intel/confidential-computing.sgx#4 0x00007ffff42bbdcc in __asan::ErrorGeneric::Print() ()
intel/confidential-computing.sgx#5 0x00007ffff428cf60 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
intel/confidential-computing.sgx#6 0x00007ffff428e28a in __asan_report_store8 ()
intel/confidential-computing.sgx#7 0x00007ffff413cdd7 in std::__1::__tree, std::__1::__map_value_compare, std::__1::less, true>, std::__1::allocator > >::__insert_node_at (this=0x7ffff550b550,
__parent=0x7ffff550b558, __child=@0x7ffff550b558: 0x0, __new_node=0x7ffff4f9f0f0)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__tree:2058
intel/confidential-computing.sgx#8 0x00007ffff413823a in std::__1::__tree, std::__1::__map_value_compare, std::__1::less, true>, std::__1::allocator > >::__emplace_hint_unique_key_args const&> (this=0x7ffff550b550, __p=..., __k=@0x7ffff550a790: 66 'B')
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__tree:2124
intel/confidential-computing.sgx#9 0x00007ffff4111c9f in std::__1::__tree, std::__1::__map_value_compare, std::__1::less, true>, std::__1::allocator > >::__insert_unique (__v=..., __p=..., this=0x7ffff550b550)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/__tree:1242
intel/confidential-computing.sgx#10 std::__1::map, std::__1::allocator > >::insert (__v=..., __p=..., this=0x7ffff550b550)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/map:1126
intel/confidential-computing.sgx#11 std::__1::map, std::__1::allocator > >::insert const*> (__l=0x7ffff550a792, __f=0x7ffff550a790,
this=0x7ffff550b550) at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/map:1147
intel/confidential-computing.sgx#12 std::__1::map, std::__1::allocator > >::map (__comp=..., __il=..., this=)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/map:1002
intel/confidential-computing.sgx#13 ecall_tuple_demo () at Enclave/TrustedLibrary/Libcxx.cpp:638
```
3.
```
Breakpoint 1, libsfuzz_ocall_isatty (retval=0x7ffff5509078, fd=2) at Enclave/Enclave_t.c:834
834 sgx_status_t status = SGX_SUCCESS;
#0 libsfuzz_ocall_isatty (retval=0x7ffff5509078, fd=2) at Enclave/Enclave_t.c:834
intel/confidential-computing.sgx#1 0x00007ffff4149d68 in isatty (fd=2) at libsgx_tsgxfuzz.c:782
intel/confidential-computing.sgx#2 0x00007ffff4294e19 in __sanitizer::SupportsColoredOutput(int) ()
intel/confidential-computing.sgx#3 0x00007ffff42a15af in __sanitizer::ReportFile::SupportsColors() ()
intel/confidential-computing.sgx#4 0x00007ffff42bbdcc in __asan::ErrorGeneric::Print() ()
intel/confidential-computing.sgx#5 0x00007ffff428cf60 in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
intel/confidential-computing.sgx#6 0x00007ffff428e28a in __asan_report_store8 ()
intel/confidential-computing.sgx#7 0x00007ffff412d223 in std::__1::__shared_count::__shared_count (__refs=0, this=0x7ffff4f9f0d0)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/memory:3722
intel/confidential-computing.sgx#8 std::__1::__shared_weak_count::__shared_weak_count (__refs=0, this=0x7ffff4f9f0d0)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/memory:3741
intel/confidential-computing.sgx#9 std::__1::__shared_ptr_emplace >::__shared_ptr_emplace (__a=..., this=0x7ffff4f9f0d0)
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/memory:3832
intel/confidential-computing.sgx#10 std::__1::shared_ptr::make_shared ()
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/memory:4447
intel/confidential-computing.sgx#11 0x00007ffff41146d7 in std::__1::make_shared ()
at /mnt/data/muqi/patchedSDK/sgxsdk//include/libcxx/memory:4811
intel/confidential-computing.sgx#12 ecall_shared_ptr_demo () at Enclave/TrustedLibrary/Libcxx.cpp:691
intel/confidential-computing.sgx#13 0x00007ffff41025b9 in sgx_ecall_shared_ptr_demo (pms=0x0) at Enclave/Enclave_t.c:419
```
Contributor guide
Assessment
This issue has not been assessed yet.