summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cc5
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc39
2 files changed, 41 insertions, 3 deletions
diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc
index 13c922841eb..d6ae53d1d5c 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cc
+++ b/compiler-rt/lib/msan/msan_interceptors.cc
@@ -284,11 +284,10 @@ INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT
INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT
ENSURE_MSAN_INITED();
SIZE_T dest_size = REAL(strlen)(dest);
- SIZE_T copy_size = REAL(strlen)(src);
- if (copy_size < n)
- copy_size++; // trailing \0
+ SIZE_T copy_size = REAL(strnlen)(src, n);
char *res = REAL(strncat)(dest, src, n); // NOLINT
__msan_copy_poison(dest + dest_size, src, copy_size);
+ __msan_unpoison(dest + dest_size + copy_size, 1); // \0
return res;
}
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc
index a60a232110e..66e5274e588 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cc
+++ b/compiler-rt/lib/msan/tests/msan_test.cc
@@ -1470,6 +1470,45 @@ TEST(MemorySanitizer, stpcpy) { // NOLINT
EXPECT_NOT_POISONED(y[2]);
}
+TEST(MemorySanitizer, strcat) { // NOLINT
+ char a[10];
+ char b[] = "def";
+ strcpy(a, "abc");
+ __msan_poison(b + 1, 1);
+ strcat(a, b);
+ EXPECT_NOT_POISONED(a[3]);
+ EXPECT_POISONED(a[4]);
+ EXPECT_NOT_POISONED(a[5]);
+ EXPECT_NOT_POISONED(a[6]);
+ EXPECT_POISONED(a[7]);
+}
+
+TEST(MemorySanitizer, strncat) { // NOLINT
+ char a[10];
+ char b[] = "def";
+ strcpy(a, "abc");
+ __msan_poison(b + 1, 1);
+ strncat(a, b, 5);
+ EXPECT_NOT_POISONED(a[3]);
+ EXPECT_POISONED(a[4]);
+ EXPECT_NOT_POISONED(a[5]);
+ EXPECT_NOT_POISONED(a[6]);
+ EXPECT_POISONED(a[7]);
+}
+
+TEST(MemorySanitizer, strncat_overflow) { // NOLINT
+ char a[10];
+ char b[] = "def";
+ strcpy(a, "abc");
+ __msan_poison(b + 1, 1);
+ strncat(a, b, 2);
+ EXPECT_NOT_POISONED(a[3]);
+ EXPECT_POISONED(a[4]);
+ EXPECT_NOT_POISONED(a[5]);
+ EXPECT_POISONED(a[6]);
+ EXPECT_POISONED(a[7]);
+}
+
TEST(MemorySanitizer, strtol) {
char *e;
assert(1 == strtol("1", &e, 10));
OpenPOWER on IntegriCloud