summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-03-14 11:10:36 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-03-14 11:10:36 +0000
commitead6cf7c729693451a19983ac165126f807a83d6 (patch)
treebbe7ff9c08cc6615ec86b4d7625e35e4657481c0
parent83e7622df61865859a854fe410c38c2e6a6741e1 (diff)
downloadbcm5719-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.c17
-rw-r--r--compiler-rt/lib/msan/lit_tests/lit.cfg19
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cc29
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc32
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];
OpenPOWER on IntegriCloud