[PATCH] D44587: [asan] Replace vfork with fork.

Evgenii Stepanov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 16 14:40:25 PDT 2018


eugenis created this revision.
eugenis added reviewers: kcc, vitalybuka.
Herald added a subscriber: kubamracek.

vfork is not ASan-friendly because it modifies stack shadow in the
parent process address space. While it is possible to compensate for that with, for example,
__asan_handle_no_return before each call to _exit or execve and friends, simply replacing
vfork with fork looks like by far the easiest solution.

Posix compliant programs can not detect the difference between vfork and fork.

Fixes https://github.com/google/sanitizers/issues/925


https://reviews.llvm.org/D44587

Files:
  compiler-rt/lib/asan/asan_interceptors.cc
  compiler-rt/lib/asan/asan_interceptors.h
  compiler-rt/test/asan/TestCases/Posix/vfork.cc


Index: compiler-rt/test/asan/TestCases/Posix/vfork.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/asan/TestCases/Posix/vfork.cc
@@ -0,0 +1,30 @@
+// Test that vfork() is fork().
+// https://github.com/google/sanitizers/issues/925
+
+// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int volatile global;
+
+int main(int argc, char **argv) {
+  pid_t pid = vfork();
+  if (pid) {
+    // parent
+    int status;
+    int res;
+    do {
+      res = waitpid(pid, &status, 0);
+    } while (res >= 0 && !WIFEXITED(status) && !WIFSIGNALED(status));
+    assert(global == 0);
+  } else {
+    // child
+    global = 42;
+    _exit(0);
+  }
+
+  return 0;
+}
Index: compiler-rt/lib/asan/asan_interceptors.h
===================================================================
--- compiler-rt/lib/asan/asan_interceptors.h
+++ compiler-rt/lib/asan/asan_interceptors.h
@@ -46,11 +46,13 @@
 # define ASAN_INTERCEPT__LONGJMP 1
 # define ASAN_INTERCEPT_INDEX 1
 # define ASAN_INTERCEPT_PTHREAD_CREATE 1
+# define ASAN_INTERCEPT_VFORK 1
 #else
 # define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
 # define ASAN_INTERCEPT__LONGJMP 0
 # define ASAN_INTERCEPT_INDEX 0
 # define ASAN_INTERCEPT_PTHREAD_CREATE 0
+# define ASAN_INTERCEPT_VFORK 0
 #endif
 
 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
Index: compiler-rt/lib/asan/asan_interceptors.cc
===================================================================
--- compiler-rt/lib/asan/asan_interceptors.cc
+++ compiler-rt/lib/asan/asan_interceptors.cc
@@ -572,6 +572,13 @@
 }
 #endif  // ASAN_INTERCEPT___CXA_ATEXIT
 
+#if ASAN_INTERCEPT_VFORK
+extern "C" int fork(void);
+INTERCEPTOR(int, vfork, void) {
+  return fork();
+}
+#endif  // ASAN_INTERCEPT_VFORK
+
 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
 namespace __asan {
 void InitializeAsanInterceptors() {
@@ -649,6 +656,10 @@
   ASAN_INTERCEPT_FUNC(__cxa_atexit);
 #endif
 
+#if ASAN_INTERCEPT_VFORK
+  ASAN_INTERCEPT_FUNC(vfork);
+#endif
+
   InitializePlatformInterceptors();
 
   VReport(1, "AddressSanitizer: libc interceptors initialized\n");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44587.138773.patch
Type: text/x-patch
Size: 2244 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180316/36ce232b/attachment.bin>


More information about the llvm-commits mailing list