[PATCH] D30384: [asan] Add an interceptor for strtok

Manuel Rigger via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 26 11:15:23 PST 2017


mrigger created this revision.

This change addresses https://github.com/google/sanitizers/issues/766. I tested the change with `make check-asan` and the newly added test case.


https://reviews.llvm.org/D30384

Files:
  asan_interceptors.cc
  tests/asan_str_test.cc


Index: tests/asan_str_test.cc
===================================================================
--- tests/asan_str_test.cc
+++ tests/asan_str_test.cc
@@ -107,6 +107,27 @@
   free(heap_string);
 }
 
+TEST(AddressSanitizer, StrTokTest) {
+  size_t size = Ident(100);
+  char *s = MallocAndMemsetString(size, 'o');
+  s[size - 1] = '\0';
+  char *delim = Ident((char*)malloc(2));
+  delim[0] = ' ';
+  delim[1] = '\n';
+  // Normal call.
+  strtok(s, s);
+  // Cause out-of-bounds read by missing NULL terminator.
+  EXPECT_DEATH(Ident(strtok(s, delim)), RightOOBReadMessage(0));
+  EXPECT_DEATH(Ident(strtok(delim, s)), RightOOBReadMessage(0));
+  s[size - 1] = 'a';
+  EXPECT_DEATH(Ident(strtok(s, s)), RightOOBReadMessage(0));
+  // Argument points to not-allocated memory.
+  EXPECT_DEATH(Ident(strtok(delim-1, delim-1)), LeftOOBReadMessage(1));
+  free(s);
+  free(delim);
+}
+
+
 #if SANITIZER_TEST_HAS_STRNLEN
 TEST(AddressSanitizer, StrNLenOOBTest) {
   size_t size = Ident(123);
Index: asan_interceptors.cc
===================================================================
--- asan_interceptors.cc
+++ asan_interceptors.cc
@@ -538,6 +538,19 @@
   return REAL(strcpy)(to, from);  // NOLINT
 }
 
+INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
+  void *ctx;
+  ASAN_INTERCEPTOR_ENTER(ctx, strtok);
+  ENSURE_ASAN_INITED();
+  if (flags()->replace_str) {
+    uptr del_size = REAL(strlen)(delimiters) + 1;
+    uptr str_size = REAL(strlen)(str) + 1;
+    ASAN_READ_RANGE(ctx, delimiters, del_size);
+    ASAN_READ_RANGE(ctx, str, str_size);
+  }
+  return REAL(strtok)(str, delimiters);
+}
+
 INTERCEPTOR(char*, strdup, const char *s) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, strdup);
@@ -716,6 +729,7 @@
   ASAN_INTERCEPT_FUNC(strcat);  // NOLINT
   ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
   ASAN_INTERCEPT_FUNC(wcslen);
+  ASAN_INTERCEPT_FUNC(strtok);
   ASAN_INTERCEPT_FUNC(strncat);
   ASAN_INTERCEPT_FUNC(strncpy);
   ASAN_INTERCEPT_FUNC(strdup);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30384.89814.patch
Type: text/x-patch
Size: 1983 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170226/51ee3e47/attachment.bin>


More information about the llvm-commits mailing list