diff options
author | Vyacheslav Cherkashin <v.cherkashin@samsung.com> | 2019-08-26 18:34:02 +0300 |
---|---|---|
committer | Slava Barinov <v.barinov@samsung.com> | 2019-08-29 13:03:38 +0300 |
commit | 316d5c2986eec03e2ffea99f9facfb3dcb60dee7 (patch) | |
tree | bf543d96dac5e58995017f6e6205121f66f4e98d | |
parent | 51f79148b70b2792d9b0cd48ad5ac1e4e4dc07a4 (diff) | |
download | linaro-gcc-accepted/tizen/base/20190901.121342.tar.gz linaro-gcc-accepted/tizen/base/20190901.121342.tar.bz2 linaro-gcc-accepted/tizen/base/20190901.121342.zip |
libsanitizer: Make delete safe via 'pointer_is_mine'submit/tizen_base/20190829.163531accepted/tizen/base/20190901.121342
* libsanitizer/asan/asan_new_delete.cc: check pointers
before calling forwarding.
Part 2 for: 30255a5854a11a5e67c13b640d65a80411a34a39
This change will lead to possible failures inside glibc in cases of
delete'ing wild pointers.
In usual case ASan should handle this case and provide appropriate
backtrace and error report, but this mode is not compatible with
interceptor switching functional, so we explicitly disabling it.
Change-Id: Ic1f2a70bbc156420c27067bae8eb5097bbc477d6
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
Signed-off-by: Slava Barinov <v.barinov@samsung.com>
-rw-r--r-- | libsanitizer/asan/asan_malloc_linux.cc | 14 | ||||
-rw-r--r-- | libsanitizer/asan/asan_new_delete.cc | 16 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_forward_calls.h | 8 |
3 files changed, 19 insertions, 19 deletions
diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cc index 914c21a6adf..59ad01e2015 100644 --- a/libsanitizer/asan/asan_malloc_linux.cc +++ b/libsanitizer/asan/asan_malloc_linux.cc @@ -46,10 +46,7 @@ INTERCEPTOR(void, free, void *ptr) { GET_STACK_TRACE_FREE; if (UNLIKELY(IsInDlsymAllocPool(ptr))) return; - if (UNLIKELY(!asan_pointer_is_mine(ptr))) { - REAL(free)(ptr); - return; - } + FORWARD_IF_MINE(free, ptr); asan_free(ptr, &stack, FROM_MALLOC); } @@ -57,10 +54,7 @@ INTERCEPTOR(void, cfree, void *ptr) { GET_STACK_TRACE_FREE; if (UNLIKELY(IsInDlsymAllocPool(ptr))) return; - if (UNLIKELY(!asan_pointer_is_mine(ptr))) { - REAL(cfree)(ptr); - return; - } + FORWARD_IF_MINE(cfree, ptr); asan_free(ptr, &stack, FROM_MALLOC); } @@ -102,9 +96,7 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) { if (UNLIKELY(asan_init_is_running)) return AllocateFromLocalPool(size); ENSURE_ASAN_INITED(); - if (UNLIKELY(!asan_pointer_is_mine(ptr))) { - return REAL(realloc)(ptr, size); - } + FORWARD_IF_MINE(realloc, ptr, size); GET_STACK_TRACE_MALLOC; return asan_realloc(ptr, size, &stack); } diff --git a/libsanitizer/asan/asan_new_delete.cc b/libsanitizer/asan/asan_new_delete.cc index 53b4a638a67..97c8bd44d73 100644 --- a/libsanitizer/asan/asan_new_delete.cc +++ b/libsanitizer/asan/asan_new_delete.cc @@ -188,44 +188,44 @@ void operator delete[](void *ptr, size_t size) NOEXCEPT { #else // SANITIZER_CALLS_FORWARDING // operator delete(void*) INTERCEPTOR(void, _ZdlPv, void *ptr) { - MAYBE_FORWARD_TO_REAL(_ZdlPv, ptr); + FORWARD_IF_MINE(_ZdlPv, ptr); OPERATOR_DELETE_BODY(FROM_NEW); } // operator delete[](void*) INTERCEPTOR(void, _ZdaPv, void *ptr) { - MAYBE_FORWARD_TO_REAL(_ZdaPv, ptr); + FORWARD_IF_MINE(_ZdaPv, ptr); OPERATOR_DELETE_BODY(FROM_NEW_BR); } // operator delete(void*, std::nothrow_t const&) INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const& tag) { - MAYBE_FORWARD_TO_REAL(_ZdlPvRKSt9nothrow_t, ptr, tag); + FORWARD_IF_MINE(_ZdlPvRKSt9nothrow_t, ptr, tag); OPERATOR_DELETE_BODY(FROM_NEW); } // operator delete[](void*, std::nothrow_t const&) INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const& tag) { - MAYBE_FORWARD_TO_REAL(_ZdaPvRKSt9nothrow_t, ptr, tag); + FORWARD_IF_MINE(_ZdaPvRKSt9nothrow_t, ptr, tag); OPERATOR_DELETE_BODY(FROM_NEW_BR); } // operator delete(void*, unsigned long) INTERCEPTOR(void, _ZdlPvm, void *ptr, size_t size) { - MAYBE_FORWARD_TO_REAL(_ZdlPvm, ptr, size); + FORWARD_IF_MINE(_ZdlPvm, ptr, size); OPERATOR_SIZED_DELETE_BODY(FROM_NEW); } // operator delete(void*, unsigned int) INTERCEPTOR(void, _ZdlPvj, void *ptr, size_t size) { - MAYBE_FORWARD_TO_REAL(_ZdlPvj, ptr, size); + FORWARD_IF_MINE(_ZdlPvj, ptr, size); OPERATOR_SIZED_DELETE_BODY(FROM_NEW); } // operator delete[](void*, unsigned long) INTERCEPTOR(void, _ZdaPvm, void *ptr, size_t size) { - MAYBE_FORWARD_TO_REAL(_ZdaPvm, ptr, size); + FORWARD_IF_MINE(_ZdaPvm, ptr, size); OPERATOR_SIZED_DELETE_BODY(FROM_NEW_BR); } // operator delete[](void*, unsigned int) INTERCEPTOR(void, _ZdaPvj, void *ptr, size_t size) { - MAYBE_FORWARD_TO_REAL(_ZdaPvj, ptr, size); + FORWARD_IF_MINE(_ZdaPvj, ptr, size); OPERATOR_SIZED_DELETE_BODY(FROM_NEW_BR); } #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_forward_calls.h b/libsanitizer/sanitizer_common/sanitizer_forward_calls.h index 92c29bc1765..646626b25fa 100644 --- a/libsanitizer/sanitizer_common/sanitizer_forward_calls.h +++ b/libsanitizer/sanitizer_common/sanitizer_forward_calls.h @@ -49,9 +49,17 @@ bool ForwardCalls(); } \ } while (0) +#define FORWARD_IF_MINE(func, ptr, ...) \ + do { \ + if (UNLIKELY(!asan_pointer_is_mine(ptr))) { \ + return REAL(func)(ptr, ##__VA_ARGS__); \ + } \ + } while (0) + #else #define MAYBE_FORWARD_TO_REAL(func, ...) {} +#define FORWARD_IF_MINE(func, ...) {} #endif // SANITIZER_CALLS_FORWARDING |