summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/asan_interceptors.cc11
-rw-r--r--lib/asan/asan_interceptors.h2
-rw-r--r--test/asan/TestCases/Posix/vfork.cc30
3 files changed, 43 insertions, 0 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
index 0b59561b8..97f75136b 100644
--- a/lib/asan/asan_interceptors.cc
+++ b/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/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h
index cf7bbaa27..19a946cca 100644
--- a/lib/asan/asan_interceptors.h
+++ b/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/test/asan/TestCases/Posix/vfork.cc b/test/asan/TestCases/Posix/vfork.cc
new file mode 100644
index 000000000..5fcb11f53
--- /dev/null
+++ b/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;
+}