diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-03-14 11:10:36 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-03-14 11:10:36 +0000 |
| commit | ead6cf7c729693451a19983ac165126f807a83d6 (patch) | |
| tree | bbe7ff9c08cc6615ec86b4d7625e35e4657481c0 | |
| parent | 83e7622df61865859a854fe410c38c2e6a6741e1 (diff) | |
| download | bcm5719-llvm-ead6cf7c729693451a19983ac165126f807a83d6.tar.gz bcm5719-llvm-ead6cf7c729693451a19983ac165126f807a83d6.zip | |
[msan] Intercept __strdup, strndup, __strndup.
llvm-svn: 177052
| -rw-r--r-- | compiler-rt/lib/msan/lit_tests/c-strdup.c | 17 | ||||
| -rw-r--r-- | compiler-rt/lib/msan/lit_tests/lit.cfg | 19 | ||||
| -rw-r--r-- | compiler-rt/lib/msan/msan_interceptors.cc | 29 | ||||
| -rw-r--r-- | compiler-rt/lib/msan/tests/msan_test.cc | 32 |
4 files changed, 87 insertions, 10 deletions
diff --git a/compiler-rt/lib/msan/lit_tests/c-strdup.c b/compiler-rt/lib/msan/lit_tests/c-strdup.c new file mode 100644 index 00000000000..7772f0f307b --- /dev/null +++ b/compiler-rt/lib/msan/lit_tests/c-strdup.c @@ -0,0 +1,17 @@ +// RUN: %clang_msan -m64 -O0 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O1 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O2 %s -o %t && %t >%t.out 2>&1 +// RUN: %clang_msan -m64 -O3 %s -o %t && %t >%t.out 2>&1 + +// Test that strdup in C programs is intercepted. +// GLibC headers translate strdup to __strdup at -O1 and higher. + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char buf[] = "abc"; + char *p = strdup(buf); + if (*p) + exit(0); + return 0; +} diff --git a/compiler-rt/lib/msan/lit_tests/lit.cfg b/compiler-rt/lib/msan/lit_tests/lit.cfg index 94290503530..07b5cbe970c 100644 --- a/compiler-rt/lib/msan/lit_tests/lit.cfg +++ b/compiler-rt/lib/msan/lit_tests/lit.cfg @@ -57,14 +57,17 @@ if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)): lit.load_config(config, compiler_rt_lit_cfg) # Setup default compiler flags used with -fsanitize=memory option. -clang_msan_cxxflags = ["-ccc-cxx ", - "-fsanitize=memory", - "-mno-omit-leaf-frame-pointer", - "-fno-omit-frame-pointer", - "-fno-optimize-sibling-calls", - "-g", - "-fPIE", - "-pie"] +clang_msan_cflags = ["-fsanitize=memory", + "-mno-omit-leaf-frame-pointer", + "-fno-omit-frame-pointer", + "-fno-optimize-sibling-calls", + "-g", + "-fPIE", + "-pie"] +clang_msan_cxxflags = ["-ccc-cxx "] + clang_msan_cflags +config.substitutions.append( ("%clang_msan ", + " ".join([config.clang] + clang_msan_cflags) + + " ") ) config.substitutions.append( ("%clangxx_msan ", " ".join([config.clang] + clang_msan_cxxflags) + " ") ) diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 4a03ddea1f3..afe45d54f2f 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -161,6 +161,32 @@ INTERCEPTOR(char *, strdup, char *src) { return res; } +INTERCEPTOR(char *, __strdup, char *src) { + ENSURE_MSAN_INITED(); + SIZE_T n = REAL(strlen)(src); + char *res = REAL(__strdup)(src); + __msan_copy_poison(res, src, n + 1); + return res; +} + +INTERCEPTOR(char *, strndup, char *src, SIZE_T n) { + ENSURE_MSAN_INITED(); + SIZE_T copy_size = REAL(strnlen)(src, n); + char *res = REAL(strndup)(src, n); + __msan_copy_poison(res, src, copy_size); + __msan_unpoison(res + copy_size, 1); // \0 + return res; +} + +INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) { + ENSURE_MSAN_INITED(); + SIZE_T copy_size = REAL(strnlen)(src, n); + char *res = REAL(__strndup)(src, n); + __msan_copy_poison(res, src, copy_size); + __msan_unpoison(res + copy_size, 1); // \0 + return res; +} + INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { ENSURE_MSAN_INITED(); char *res = REAL(gcvt)(number, ndigit, buf); @@ -965,6 +991,9 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(wmemmove); INTERCEPT_FUNCTION(strcpy); // NOLINT INTERCEPT_FUNCTION(strdup); + INTERCEPT_FUNCTION(__strdup); + INTERCEPT_FUNCTION(strndup); + INTERCEPT_FUNCTION(__strndup); INTERCEPT_FUNCTION(strncpy); // NOLINT INTERCEPT_FUNCTION(strlen); INTERCEPT_FUNCTION(strnlen); diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index 4a2909c0d40..6a433d4b627 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -641,11 +641,39 @@ TEST(MemorySanitizer, memmove) { } TEST(MemorySanitizer, strdup) { - char *x = strdup("zzz"); - EXPECT_NOT_POISONED(*x); + char buf[4] = "abc"; + __msan_poison(buf + 2, sizeof(*buf)); + char *x = strdup(buf); + EXPECT_NOT_POISONED(x[0]); + EXPECT_NOT_POISONED(x[1]); + EXPECT_POISONED(x[2]); + EXPECT_NOT_POISONED(x[3]); + free(x); +} + +TEST(MemorySanitizer, strndup) { + char buf[4] = "abc"; + __msan_poison(buf + 2, sizeof(*buf)); + char *x = strndup(buf, 3); + EXPECT_NOT_POISONED(x[0]); + EXPECT_NOT_POISONED(x[1]); + EXPECT_POISONED(x[2]); + EXPECT_NOT_POISONED(x[3]); + free(x); +} + +TEST(MemorySanitizer, strndup_short) { + char buf[4] = "abc"; + __msan_poison(buf + 1, sizeof(*buf)); + __msan_poison(buf + 2, sizeof(*buf)); + char *x = strndup(buf, 2); + EXPECT_NOT_POISONED(x[0]); + EXPECT_POISONED(x[1]); + EXPECT_NOT_POISONED(x[3]); free(x); } + template<class T, int size> void TestOverlapMemmove() { T *x = new T[size]; |

