summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-01 23:49:48 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-01 23:49:48 +0000
commit5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9 (patch)
tree7d6cefe35705b4c4ce3586903070a5fe80625f84
parent8aa3d18712dec51d771523867305133ee41e006d (diff)
downloadcompiler-rt-5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9.tar.gz
compiler-rt-5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9.tar.bz2
compiler-rt-5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9.tar.xz
[msan] Intercept memccpy.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193897 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/msan_interceptors.cc11
-rw-r--r--lib/msan/tests/msan_test.cc47
2 files changed, 58 insertions, 0 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index b96e4b3f..de22f850 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -120,6 +120,16 @@ INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
return (char *)__msan_memcpy(dest, src, n) + n;
}
+INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
+ ENSURE_MSAN_INITED();
+ void *res = REAL(memccpy)(dest, src, c, n);
+ CHECK(!res || (res >= dest && res <= (char *)dest + n));
+ SIZE_T sz = res ? (char *)res - (char *)dest : n;
+ CHECK_UNPOISONED(src, sz);
+ __msan_unpoison(dest, sz);
+ return res;
+}
+
INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
return __msan_memmove(dest, src, n);
}
@@ -1428,6 +1438,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(fread_unlocked);
INTERCEPT_FUNCTION(readlink);
INTERCEPT_FUNCTION(memcpy);
+ INTERCEPT_FUNCTION(memccpy);
INTERCEPT_FUNCTION(mempcpy);
INTERCEPT_FUNCTION(memset);
INTERCEPT_FUNCTION(memmove);
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index ab109874..c387567d 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -1318,6 +1318,53 @@ TEST(MemorySanitizer, memmove) {
EXPECT_POISONED(y[1]);
}
+TEST(MemorySanitizer, memccpy_nomatch) {
+ char* x = new char[5];
+ char* y = new char[5];
+ strcpy(x, "abc");
+ memccpy(y, x, 'd', 4);
+ EXPECT_NOT_POISONED(y[0]);
+ EXPECT_NOT_POISONED(y[1]);
+ EXPECT_NOT_POISONED(y[2]);
+ EXPECT_NOT_POISONED(y[3]);
+ EXPECT_POISONED(y[4]);
+ delete[] x;
+ delete[] y;
+}
+
+TEST(MemorySanitizer, memccpy_match) {
+ char* x = new char[5];
+ char* y = new char[5];
+ strcpy(x, "abc");
+ memccpy(y, x, 'b', 4);
+ EXPECT_NOT_POISONED(y[0]);
+ EXPECT_NOT_POISONED(y[1]);
+ EXPECT_POISONED(y[2]);
+ EXPECT_POISONED(y[3]);
+ EXPECT_POISONED(y[4]);
+ delete[] x;
+ delete[] y;
+}
+
+TEST(MemorySanitizer, memccpy_nomatch_positive) {
+ char* x = new char[5];
+ char* y = new char[5];
+ strcpy(x, "abc");
+ EXPECT_UMR(memccpy(y, x, 'd', 5));
+ delete[] x;
+ delete[] y;
+}
+
+TEST(MemorySanitizer, memccpy_match_positive) {
+ char* x = new char[5];
+ char* y = new char[5];
+ x[0] = 'a';
+ x[2] = 'b';
+ EXPECT_UMR(memccpy(y, x, 'b', 5));
+ delete[] x;
+ delete[] y;
+}
+
TEST(MemorySanitizer, bcopy) {
char* x = new char[2];
char* y = new char[2];