summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2018-03-16 22:15:05 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2018-03-16 22:15:05 +0000
commita4561123de9c4a31575abe573ac4324b36d84234 (patch)
tree2a610481075ae67cde74dd2ef15e6ee91aaef3e4
parentcce4af160cade64cfd0fdda9fdb320a26d145ca8 (diff)
downloadbcm5719-llvm-a4561123de9c4a31575abe573ac4324b36d84234.tar.gz
bcm5719-llvm-a4561123de9c4a31575abe573ac4324b36d84234.zip
[asan] Replace vfork with fork.
Summary: 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 Reviewers: kcc, vitalybuka Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D44587 llvm-svn: 327752
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.cc11
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.h2
-rw-r--r--compiler-rt/test/asan/TestCases/Posix/vfork.cc30
3 files changed, 43 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc
index 0b59561b862..97f75136b06 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cc
+++ b/compiler-rt/lib/asan/asan_interceptors.cc
@@ -572,6 +572,13 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
}
#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 @@ void InitializeAsanInterceptors() {
ASAN_INTERCEPT_FUNC(__cxa_atexit);
#endif
+#if ASAN_INTERCEPT_VFORK
+ ASAN_INTERCEPT_FUNC(vfork);
+#endif
+
InitializePlatformInterceptors();
VReport(1, "AddressSanitizer: libc interceptors initialized\n");
diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h
index cf7bbaa276b..19a946cca03 100644
--- a/compiler-rt/lib/asan/asan_interceptors.h
+++ b/compiler-rt/lib/asan/asan_interceptors.h
@@ -46,11 +46,13 @@ void InitializePlatformInterceptors();
# 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 || \
diff --git a/compiler-rt/test/asan/TestCases/Posix/vfork.cc b/compiler-rt/test/asan/TestCases/Posix/vfork.cc
new file mode 100644
index 00000000000..5fcb11f53f2
--- /dev/null
+++ b/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;
+}
OpenPOWER on IntegriCloud