[msan] Intercept several malloc-related functions.

llvm-svn: 204923
This commit is contained in:
Evgeniy Stepanov 2014-03-27 13:29:29 +00:00
parent bd0e39079a
commit 9dcd5a353a
5 changed files with 73 additions and 9 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}