[llvm-commits] [compiler-rt] r158198 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc tests/asan_test.cc

Alexey Samsonov samsonov at google.com
Fri Jun 8 06:27:47 PDT 2012


Author: samsonov
Date: Fri Jun  8 08:27:46 2012
New Revision: 158198

URL: http://llvm.org/viewvc/llvm-project?rev=158198&view=rev
Log:
[ASan] add interceptor for strncat

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/tests/asan_test.cc

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=158198&r1=158197&r2=158198&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Jun  8 08:27:46 2012
@@ -71,6 +71,7 @@
 char* index(const char *string, int c);
 # endif
 char* strcat(char *to, const char* from);  // NOLINT
+char *strncat(char *to, const char* from, uptr size);
 char* strcpy(char *to, const char* from);  // NOLINT
 char* strncpy(char *to, const char* from, uptr size);
 int strcmp(const char *s1, const char* s2);
@@ -504,6 +505,22 @@
   return REAL(strcat)(to, from);  // NOLINT
 }
 
+INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
+  ENSURE_ASAN_INITED();
+  if (FLAG_replace_str && size > 0) {
+    uptr from_length = internal_strnlen(from, size);
+    ASAN_READ_RANGE(from, Min(size, from_length + 1));
+    uptr to_length = REAL(strlen)(to);
+    ASAN_READ_RANGE(to, to_length);
+    ASAN_WRITE_RANGE(to + to_length, from_length + 1);
+    if (from_length > 0) {
+      CHECK_RANGES_OVERLAP("strncat", to, to_length + 1,
+                           from, Min(size, from_length + 1));
+    }
+  }
+  return REAL(strncat)(to, from, size);
+}
+
 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
   if (!asan_inited) {
     return internal_strcmp(s1, s2);
@@ -759,6 +776,7 @@
   ASAN_INTERCEPT_FUNC(strcmp);
   ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
   ASAN_INTERCEPT_FUNC(strlen);
+  ASAN_INTERCEPT_FUNC(strncat);
   ASAN_INTERCEPT_FUNC(strncmp);
   ASAN_INTERCEPT_FUNC(strncpy);
 #if !defined(_WIN32)

Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=158198&r1=158197&r2=158198&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Fri Jun  8 08:27:46 2012
@@ -1252,6 +1252,47 @@
   EXPECT_DEATH(strcat(to, from), RightOOBErrorMessage(0));
   // length of "to" is just enough.
   strcat(to, from + 1);
+
+  free(to);
+  free(from);
+}
+
+TEST(AddressSanitizer, StrNCatOOBTest) {
+  size_t to_size = Ident(100);
+  char *to = MallocAndMemsetString(to_size);
+  to[0] = '\0';
+  size_t from_size = Ident(20);
+  char *from = MallocAndMemsetString(from_size);
+  // Normal strncat calls.
+  strncat(to, from, 0);
+  strncat(to, from, from_size);
+  from[from_size - 1] = '\0';
+  strncat(to, from, 2 * from_size);
+  // Catenating empty string is not an error.
+  strncat(to - 1, from, 0);
+  strncat(to, from + from_size - 1, 10);
+  // One of arguments points to not allocated memory.
+  EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBErrorMessage(1));
+  EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBErrorMessage(1));
+  EXPECT_DEATH(strncat(to + to_size, from, 2), RightOOBErrorMessage(0));
+  EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBErrorMessage(0));
+
+  memset(from, 'z', from_size);
+  memset(to, 'z', to_size);
+  to[0] = '\0';
+  // "from" is too short.
+  EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBErrorMessage(0));
+  // "to" is not zero-terminated.
+  EXPECT_DEATH(strncat(to + 1, from, 1), RightOOBErrorMessage(0));
+  // "to" is too short to fit "from".
+  to[0] = 'z';
+  to[to_size - from_size + 1] = '\0';
+  EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBErrorMessage(0));
+  // "to" is just enough.
+  strncat(to, from, from_size - 2);
+
+  free(to);
+  free(from);
 }
 
 static string OverlapErrorMessage(const string &func) {
@@ -1308,6 +1349,18 @@
   EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
   EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
 
+  // Check "strncat".
+  memset(str, 'z', size);
+  str[10] = '\0';
+  strncat(str, str + 10, 10);  // from is empty
+  strncat(str, str + 11, 10);
+  str[10] = '\0';
+  str[20] = '\0';
+  strncat(str + 5, str, 5);
+  str[10] = '\0';
+  EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
+  EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
+
   free(str);
 }
 





More information about the llvm-commits mailing list