[compiler-rt] r299061 - [sanitizer] Move fread and fwrite interceptors to sanitizer_common

Maxim Ostapenko via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 30 00:25:33 PDT 2017


Author: chefmax
Date: Thu Mar 30 02:25:33 2017
New Revision: 299061

URL: http://llvm.org/viewvc/llvm-project?rev=299061&view=rev
Log:
[sanitizer] Move fread and fwrite interceptors to sanitizer_common

{M, T, E}San have fread and fwrite interceptors, let's move them to sanitizer_common to enable ASan checks as well.

Differential Revision: https://reviews.llvm.org/D31456

Added:
    compiler-rt/trunk/test/asan/TestCases/Posix/fread_fwrite.cc
    compiler-rt/trunk/test/msan/fread_fwrite.cc
Modified:
    compiler-rt/trunk/lib/esan/esan_interceptors.cpp
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc

Modified: compiler-rt/trunk/lib/esan/esan_interceptors.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/esan/esan_interceptors.cpp?rev=299061&r1=299060&r2=299061&view=diff
==============================================================================
--- compiler-rt/trunk/lib/esan/esan_interceptors.cpp (original)
+++ compiler-rt/trunk/lib/esan/esan_interceptors.cpp Thu Mar 30 02:25:33 2017
@@ -304,20 +304,6 @@ INTERCEPTOR(int, unlink, char *path) {
   return REAL(unlink)(path);
 }
 
-INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, f);
-  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size * nmemb);
-  return REAL(fread)(ptr, size, nmemb, f);
-}
-
-INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) {
-  void *ctx;
-  COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, f);
-  COMMON_INTERCEPTOR_READ_RANGE(ctx, p, size * nmemb);
-  return REAL(fwrite)(p, size, nmemb, f);
-}
-
 INTERCEPTOR(int, puts, const char *s) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, puts, s);

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=299061&r1=299060&r2=299061&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Thu Mar 30 02:25:33 2017
@@ -123,14 +123,6 @@ static void *AllocateFromLocalPool(uptr
 #define CHECK_UNPOISONED_STRING(x, n)                           \
     CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
 
-INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
-  ENSURE_MSAN_INITED();
-  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
-  if (res > 0)
-    __msan_unpoison(ptr, res *size);
-  return res;
-}
-
 #if !SANITIZER_FREEBSD
 INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
             void *file) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=299061&r1=299060&r2=299061&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Mar 30 02:25:33 2017
@@ -888,6 +888,23 @@ INTERCEPTOR(SSIZE_T, read, int fd, void
 #define INIT_READ
 #endif
 
+#if SANITIZER_INTERCEPT_FREAD
+INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
+  // libc file streams can call user-supplied functions, see fopencookie.
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
+  // FIXME: under ASan the call below may write to freed memory and corrupt
+  // its metadata. See
+  // https://github.com/google/sanitizers/issues/321.
+  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
+  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
+  return res;
+}
+#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
+#else
+#define INIT_FREAD
+#endif
+
 #if SANITIZER_INTERCEPT_PREAD
 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
   void *ctx;
@@ -988,6 +1005,20 @@ INTERCEPTOR(SSIZE_T, write, int fd, void
 #define INIT_WRITE
 #endif
 
+#if SANITIZER_INTERCEPT_FWRITE
+INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) {
+  // libc file streams can call user-supplied functions, see fopencookie.
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
+  SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
+  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
+  return res;
+}
+#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
+#else
+#define INIT_FWRITE
+#endif
+
 #if SANITIZER_INTERCEPT_PWRITE
 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
   void *ctx;
@@ -6142,12 +6173,14 @@ static void InitializeCommonInterceptors
   INIT_MEMRCHR;
   INIT_MEMMEM;
   INIT_READ;
+  INIT_FREAD;
   INIT_PREAD;
   INIT_PREAD64;
   INIT_READV;
   INIT_PREADV;
   INIT_PREADV64;
   INIT_WRITE;
+  INIT_FWRITE;
   INIT_PWRITE;
   INIT_PWRITE64;
   INIT_WRITEV;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=299061&r1=299060&r2=299061&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Mar 30 02:25:33 2017
@@ -104,6 +104,9 @@
 #define SANITIZER_INTERCEPT_WRITE  SI_NOT_WINDOWS
 #define SANITIZER_INTERCEPT_PWRITE SI_NOT_WINDOWS
 
+#define SANITIZER_INTERCEPT_FREAD SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_FWRITE SI_NOT_WINDOWS
+
 #define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=299061&r1=299060&r2=299061&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Thu Mar 30 02:25:33 2017
@@ -1648,24 +1648,6 @@ TSAN_INTERCEPTOR(void*, tmpfile64, int f
 #define TSAN_MAYBE_INTERCEPT_TMPFILE64
 #endif
 
-TSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) {
-  // libc file streams can call user-supplied functions, see fopencookie.
-  {
-    SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f);
-    MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true);
-  }
-  return REAL(fread)(ptr, size, nmemb, f);
-}
-
-TSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) {
-  // libc file streams can call user-supplied functions, see fopencookie.
-  {
-    SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f);
-    MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false);
-  }
-  return REAL(fwrite)(p, size, nmemb, f);
-}
-
 static void FlushStreams() {
   // Flushing all the streams here may freeze the process if a child thread is
   // performing file stream operations at the same time.

Added: compiler-rt/trunk/test/asan/TestCases/Posix/fread_fwrite.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/fread_fwrite.cc?rev=299061&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/fread_fwrite.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/fread_fwrite.cc Thu Mar 30 02:25:33 2017
@@ -0,0 +1,34 @@
+// RUN: %clangxx_asan -g %s -o %t
+// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK-FWRITE
+// RUN: not %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FREAD
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int test_fread() {
+  FILE *f = fopen("/dev/zero", "r");
+  char buf[2];
+  fread(buf, sizeof(buf), 2, f); // BOOM
+  fclose(f);
+  return 0;
+}
+
+int test_fwrite() {
+  FILE *f = fopen("/dev/null", "w");
+  char buf[2];
+  fwrite(buf, sizeof(buf), 2, f); // BOOM
+  return fclose(f);
+}
+
+int main(int argc, char *argv[]) {
+  if (argc > 1)
+    test_fread();
+  else
+    test_fwrite();
+  return 0;
+}
+
+// CHECK-FREAD: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}fread
+// CHECK-FWRITE: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
+// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}fwrite

Added: compiler-rt/trunk/test/msan/fread_fwrite.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/fread_fwrite.cc?rev=299061&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/fread_fwrite.cc (added)
+++ compiler-rt/trunk/test/msan/fread_fwrite.cc Thu Mar 30 02:25:33 2017
@@ -0,0 +1,34 @@
+// RUN: %clangxx_msan -g %s -o %t
+// RUN: not %t 2>&1 | FileCheck %s
+// RUN: %t 1
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int test_fread() {
+  FILE *f = fopen("/dev/zero", "r");
+  char c;
+  unsigned read = fread(&c, sizeof(c), 1, f);
+  fclose(f);
+  if (c == '1') // No error
+    return 1;
+  return 0;
+}
+
+int test_fwrite() {
+  FILE *f = fopen("/dev/null", "w");
+  char c;
+  if (fwrite(&c, sizeof(c), 1, f) != sizeof(c)) // BOOM
+    return 1;
+  return fclose(f);
+}
+
+int main(int argc, char *argv[]) {
+  if (argc > 1)
+    test_fread();
+  else
+    test_fwrite();
+  return 0;
+}
+
+// CHECK: Uninitialized bytes in __interceptor_fwrite at offset 0 inside




More information about the llvm-commits mailing list