[compiler-rt] [rtsan] Fix va_args handling in open functions (PR #108291)

Chris Apple via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 21 09:36:51 PDT 2024


https://github.com/cjappl updated https://github.com/llvm/llvm-project/pull/108291

>From 5a4555a2b4b18ca61f87fb00ed858835553baab7 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Wed, 11 Sep 2024 14:41:14 -0600
Subject: [PATCH 1/3] [rtsan] Fix va_args handling in open functions

---
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 28 +++++++++++---------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index d186d1aaa8d93e..7eceef51963601 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -64,13 +64,15 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("open");
 
-  va_list args;
-  va_start(args, oflag);
-  const mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (oflag & O_CREAT) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(open)(path, oflag, mode);
+  }
 
-  const int result = REAL(open)(path, oflag, mode);
-  return result;
+  return REAL(open)(path, oflag);
 }
 
 #if SANITIZER_INTERCEPT_OPEN64
@@ -97,13 +99,15 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("openat");
 
-  va_list args;
-  va_start(args, oflag);
-  mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (oflag & O_CREAT) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(openat)(fd, path, oflag, mode);
+  }
 
-  const int result = REAL(openat)(fd, path, oflag, mode);
-  return result;
+  return REAL(openat)(fd, path, oflag);
 }
 
 #if SANITIZER_INTERCEPT_OPENAT64

>From d61ad671a711006890c55a67ef973c0e90585623 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sat, 14 Sep 2024 06:48:31 -0600
Subject: [PATCH 2/3] [PR] vitalybuka - Ensure we read O_TMPFILE as well

---
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index 7eceef51963601..b9bf771f42d3b5 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -58,13 +58,20 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
 } // namespace
 
 // Filesystem
+static bool open_reads_va_args(int oflag) {
+#ifdef O_TMPFILE
+  return (oflag & (O_CREAT | O_TMPFILE)) != 0;
+#else
+  return (oflag & O_CREAT) != 0;
+#endif
+}
 
 INTERCEPTOR(int, open, const char *path, int oflag, ...) {
   // TODO Establish whether we should intercept here if the flag contains
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("open");
 
-  if (oflag & O_CREAT) {
+  if (open_reads_va_args(oflag)) {
     va_list args;
     va_start(args, oflag);
     const mode_t mode = va_arg(args, int);
@@ -99,7 +106,7 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("openat");
 
-  if (oflag & O_CREAT) {
+  if (open_reads_va_args(oflag)) {
     va_list args;
     va_start(args, oflag);
     const mode_t mode = va_arg(args, int);

>From 1a17ad9aa09bfde421fe39d51e8a46431e2cfea5 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sat, 21 Sep 2024 10:36:18 -0600
Subject: [PATCH 3/3] [PR] vitalybuka - Fix va_args in open in tsan

---
 compiler-rt/lib/rtsan/rtsan_interceptors.cpp  | 39 +++++++++----------
 .../lib/sanitizer_common/sanitizer_posix.cpp  | 10 ++++-
 .../lib/sanitizer_common/sanitizer_posix.h    |  1 +
 .../lib/tsan/rtl/tsan_interceptors_posix.cpp  | 20 +++++++---
 4 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index b9bf771f42d3b5..9cc7214aef85c7 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -58,20 +58,13 @@ struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
 } // namespace
 
 // Filesystem
-static bool open_reads_va_args(int oflag) {
-#ifdef O_TMPFILE
-  return (oflag & (O_CREAT | O_TMPFILE)) != 0;
-#else
-  return (oflag & O_CREAT) != 0;
-#endif
-}
 
 INTERCEPTOR(int, open, const char *path, int oflag, ...) {
   // TODO Establish whether we should intercept here if the flag contains
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("open");
 
-  if (open_reads_va_args(oflag)) {
+  if (OpenReadsVaArgs(oflag)) {
     va_list args;
     va_start(args, oflag);
     const mode_t mode = va_arg(args, int);
@@ -88,13 +81,15 @@ INTERCEPTOR(int, open64, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("open64");
 
-  va_list args;
-  va_start(args, oflag);
-  const mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (OpenReadsVaArgs(oflag)) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(open64)(path, oflag, mode);
+  }
 
-  const int result = REAL(open64)(path, oflag, mode);
-  return result;
+  return REAL(open64)(path, oflag);
 }
 #define RTSAN_MAYBE_INTERCEPT_OPEN64 INTERCEPT_FUNCTION(open64)
 #else
@@ -106,7 +101,7 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("openat");
 
-  if (open_reads_va_args(oflag)) {
+  if (OpenReadsVaArgs(oflag)) {
     va_list args;
     va_start(args, oflag);
     const mode_t mode = va_arg(args, int);
@@ -123,13 +118,15 @@ INTERCEPTOR(int, openat64, int fd, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_notify_intercepted_call("openat64");
 
-  va_list args;
-  va_start(args, oflag);
-  mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (OpenReadsVaArgs(oflag)) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(openat64)(fd, path, oflag, mode);
+  }
 
-  const int result = REAL(openat64)(fd, path, oflag, mode);
-  return result;
+  return REAL(openat64)(fd, path, oflag);
 }
 #define RTSAN_MAYBE_INTERCEPT_OPENAT64 INTERCEPT_FUNCTION(openat64)
 #else
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
index 7d7d5754319947..69af6465a62c2d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
@@ -353,7 +353,15 @@ bool ShouldMockFailureToOpen(const char *path) {
          internal_strncmp(path, "/proc/", 6) == 0;
 }
 
-#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO
+bool OpenReadsVaArgs(int oflag) {
+#  ifdef O_TMPFILE
+  return (oflag & (O_CREAT | O_TMPFILE)) != 0;
+#  else
+  return (oflag & O_CREAT) != 0;
+#  endif
+}
+
+#  if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO
 int GetNamedMappingFd(const char *name, uptr size, int *flags) {
   if (!common_flags()->decorate_proc_maps || !name)
     return -1;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
index d0954f77e97136..1f0795caa420c7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
@@ -108,6 +108,7 @@ bool IsStateDetached(int state);
 fd_t ReserveStandardFds(fd_t fd);
 
 bool ShouldMockFailureToOpen(const char *path);
+bool OpenReadsVaArgs(int oflag);
 
 // Create a non-file mapping with a given /proc/self/maps name.
 uptr MmapNamed(void *addr, uptr length, int prot, int flags, const char *name);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 53c876f4f9175f..423d97e94d81ae 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -1680,13 +1680,23 @@ TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
 #endif
 
 TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
-  va_list ap;
-  va_start(ap, oflag);
-  mode_t mode = va_arg(ap, int);
-  va_end(ap);
+  mode_t mode = 0;
+  if (OpenReadsVaArgs(oflag)) {
+    va_list ap;
+    va_start(ap, oflag);
+    mode = va_arg(ap, int);
+    va_end(ap);
+  }
+
   SCOPED_TSAN_INTERCEPTOR(open, name, oflag, mode);
   READ_STRING(thr, pc, name, 0);
-  int fd = REAL(open)(name, oflag, mode);
+
+  int fd;
+  if (OpenReadsVaArgs(oflag))
+    fd = REAL(open)(name, oflag, mode);
+  else
+    fd = REAL(open)(name, oflag);
+
   if (fd >= 0)
     FdFileCreate(thr, pc, fd);
   return fd;



More information about the llvm-commits mailing list