summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>2019-08-26 18:34:02 +0300
committerSlava Barinov <v.barinov@samsung.com>2019-08-29 13:03:38 +0300
commit316d5c2986eec03e2ffea99f9facfb3dcb60dee7 (patch)
treebf543d96dac5e58995017f6e6205121f66f4e98d
parent51f79148b70b2792d9b0cd48ad5ac1e4e4dc07a4 (diff)
downloadlinaro-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.cc14
-rw-r--r--libsanitizer/asan/asan_new_delete.cc16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_forward_calls.h8
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