summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-03-27 13:29:29 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2014-03-27 13:29:29 +0000
commit8dfc941e62ff9bcb71cfaddffda524674bbb0c53 (patch)
tree02761403fe0764f6300ca2f05e0253e9b3e17111
parent2139b3e34adc58abc802783325150b4a8b45fc86 (diff)
[msan] Intercept several malloc-related functions.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@204923 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/msan_interceptors.cc31
-rw-r--r--lib/msan/tests/msan_test.cc24
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h10
-rw-r--r--test/msan/mallinfo.cc12
5 files changed, 73 insertions, 9 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index c4e58d78e..0bac746f2 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -188,6 +188,32 @@ INTERCEPTOR(void, free, void *ptr) {
MsanDeallocate(&stack, ptr);
}
+INTERCEPTOR(void, cfree, void *ptr) {
+ GET_MALLOC_STACK_TRACE;
+ if (ptr == 0) return;
+ MsanDeallocate(&stack, ptr);
+}
+
+INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
+ return __msan_get_allocated_size(ptr);
+}
+
+// This function actually returns a struct by value, but we can't unpoison a
+// temporary! The following is equivalent on all supported platforms, and we
+// have a test to confirm that.
+INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
+ REAL(memset)(sret, 0, sizeof(*sret));
+ __msan_unpoison(sret, sizeof(*sret));
+}
+
+INTERCEPTOR(int, mallopt, int cmd, int value) {
+ return -1;
+}
+
+INTERCEPTOR(void, malloc_stats, void) {
+ // FIXME: implement, but don't call REAL(malloc_stats)!
+}
+
INTERCEPTOR(SIZE_T, strlen, const char *s) {
ENSURE_MSAN_INITED();
SIZE_T res = REAL(strlen)(s);
@@ -1464,6 +1490,11 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(realloc);
INTERCEPT_FUNCTION(free);
+ INTERCEPT_FUNCTION(cfree);
+ INTERCEPT_FUNCTION(malloc_usable_size);
+ INTERCEPT_FUNCTION(mallinfo);
+ INTERCEPT_FUNCTION(mallopt);
+ INTERCEPT_FUNCTION(malloc_stats);
INTERCEPT_FUNCTION(fread);
INTERCEPT_FUNCTION(fread_unlocked);
INTERCEPT_FUNCTION(readlink);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 4ffc97505..3ebd211ee 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -16,6 +16,8 @@
#include "msan_test_config.h"
#endif // MSAN_EXTERNAL_TEST_CONFIG
+#include "sanitizer_common/tests/sanitizer_test_utils.h"
+
#include "sanitizer/msan_interface.h"
#include "msandr_test_so.h"
@@ -174,15 +176,6 @@ T *GetPoisonedO(int i, U4 origin, T val = 0) {
return res;
}
-// This function returns its parameter but in such a way that compiler
-// can not prove it.
-template<class T>
-NOINLINE
-static T Ident(T t) {
- volatile T ret = t;
- return ret;
-}
-
template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
static volatile int g_one = 1;
@@ -3880,3 +3873,16 @@ TEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) {
munmap(q, 4096);
}
+
+#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
+TEST(MemorySanitizer, MallocUsableSizeTest) {
+ const size_t kArraySize = 100;
+ char *array = Ident((char*)malloc(kArraySize));
+ int *int_ptr = Ident(new int);
+ EXPECT_EQ(0U, malloc_usable_size(NULL));
+ EXPECT_EQ(kArraySize, malloc_usable_size(array));
+ EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));
+ free(array);
+ delete int_ptr;
+}
+#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 922f44105..cfa9117a6 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -47,6 +47,7 @@
#endif
#if SANITIZER_LINUX
+#include <malloc.h>
#include <mntent.h>
#include <netinet/ether.h>
#include <sys/sysinfo.h>
@@ -1074,4 +1075,8 @@ CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
#endif
+#if SANITIZER_LINUX
+COMPILER_CHECK(sizeof(__sanitizer_mallinfo) == sizeof(struct mallinfo));
+#endif
+
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 1e2c4da26..0d8fbc88a 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -138,7 +138,17 @@ namespace __sanitizer {
const unsigned old_sigset_t_sz = sizeof(unsigned long);
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_ANDROID
+ struct __sanitizer_mallinfo {
+ size_t v[10];
+ };
+#endif
+
#if SANITIZER_LINUX && !SANITIZER_ANDROID
+ struct __sanitizer_mallinfo {
+ int v[10];
+ };
+
extern unsigned struct_ustat_sz;
extern unsigned struct_rlimit64_sz;
extern unsigned struct_statvfs64_sz;
diff --git a/test/msan/mallinfo.cc b/test/msan/mallinfo.cc
new file mode 100644
index 000000000..ddd218b7d
--- /dev/null
+++ b/test/msan/mallinfo.cc
@@ -0,0 +1,12 @@
+// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t
+
+#include <assert.h>
+#include <malloc.h>
+
+#include <sanitizer/msan_interface.h>
+
+int main(void) {
+ struct mallinfo mi = mallinfo();
+ assert(__msan_test_shadow(&mi, sizeof(mi)) == -1);
+ return 0;
+}