[compiler-rt] 1f82d0f - [msan] Add interceptors for Linux 64-bit stat variants

Manoj Gupta via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 15 20:23:15 PDT 2022


Author: Manoj Gupta
Date: 2022-03-15T20:22:28-07:00
New Revision: 1f82d0f795d11376adf3e62fc35fd98bb46e82b0

URL: https://github.com/llvm/llvm-project/commit/1f82d0f795d11376adf3e62fc35fd98bb46e82b0
DIFF: https://github.com/llvm/llvm-project/commit/1f82d0f795d11376adf3e62fc35fd98bb46e82b0.diff

LOG: [msan] Add interceptors for Linux 64-bit stat variants

glibc >= 2.33 uses shared functions for stat family functions.
D111984 added support for non-64 bit variants but they
do not appear to be enough as we have been noticing msan
errors on 64-bit stat variants on Chrome OS.

Reviewed By: vitalybuka

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

Added: 
    compiler-rt/test/msan/fstat64.cpp
    compiler-rt/test/msan/fstatat64.cpp
    compiler-rt/test/msan/stat64.cpp
    compiler-rt/test/sanitizer_common/TestCases/Posix/lstat64.cpp

Modified: 
    compiler-rt/lib/msan/msan_interceptors.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp
index dbe18ce37509e..d745fa7563d90 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cpp
+++ b/compiler-rt/lib/msan/msan_interceptors.cpp
@@ -666,6 +666,19 @@ INTERCEPTOR(int, fstat, int fd, void *buf) {
 #define MSAN_MAYBE_INTERCEPT_FSTAT
 #endif
 
+#if SANITIZER_STAT_LINUX
+INTERCEPTOR(int, fstat64, int fd, void *buf) {
+  ENSURE_MSAN_INITED();
+  int res = REAL(fstat64)(fd, buf);
+  if (!res)
+    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
+  return res;
+}
+#  define MSAN_MAYBE_INTERCEPT_FSTAT64 MSAN_INTERCEPT_FUNC(fstat64)
+#else
+#  define MSAN_MAYBE_INTERCEPT_FSTAT64
+#endif
+
 #if SANITIZER_GLIBC
 INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
   ENSURE_MSAN_INITED();
@@ -704,6 +717,19 @@ INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
 #  define MSAN_MAYBE_INTERCEPT_FSTATAT
 #endif
 
+#if SANITIZER_STAT_LINUX
+INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) {
+  ENSURE_MSAN_INITED();
+  int res = REAL(fstatat64)(fd, pathname, buf, flags);
+  if (!res)
+    __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
+  return res;
+}
+#  define MSAN_MAYBE_INTERCEPT_FSTATAT64 MSAN_INTERCEPT_FUNC(fstatat64)
+#else
+#  define MSAN_MAYBE_INTERCEPT_FSTATAT64
+#endif
+
 #if SANITIZER_GLIBC
 INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
             int flags) {
@@ -1691,8 +1717,10 @@ void InitializeInterceptors() {
   INTERCEPT_FUNCTION(gettimeofday);
   MSAN_MAYBE_INTERCEPT_FCVT;
   MSAN_MAYBE_INTERCEPT_FSTAT;
+  MSAN_MAYBE_INTERCEPT_FSTAT64;
   MSAN_MAYBE_INTERCEPT___FXSTAT;
   MSAN_MAYBE_INTERCEPT_FSTATAT;
+  MSAN_MAYBE_INTERCEPT_FSTATAT64;
   MSAN_MAYBE_INTERCEPT___FXSTATAT;
   MSAN_MAYBE_INTERCEPT___FXSTAT64;
   MSAN_MAYBE_INTERCEPT___FXSTATAT64;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index eeeeb1622ff5b..18b023078441b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -6941,6 +6941,23 @@ INTERCEPTOR(int, stat, const char *path, void *buf) {
 #define INIT_STAT
 #endif
 
+#if SANITIZER_INTERCEPT_STAT64
+INTERCEPTOR(int, stat64, const char *path, void *buf) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf);
+  if (common_flags()->intercept_stat)
+    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
+  int res = REAL(stat64)(path, buf);
+  if (!res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
+  return res;
+}
+#define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64)
+#else
+#define INIT_STAT64
+#endif
+
+
 #if SANITIZER_INTERCEPT_LSTAT
 INTERCEPTOR(int, lstat, const char *path, void *buf) {
   void *ctx;
@@ -6957,6 +6974,22 @@ INTERCEPTOR(int, lstat, const char *path, void *buf) {
 #define INIT_LSTAT
 #endif
 
+#if SANITIZER_INTERCEPT_STAT64
+INTERCEPTOR(int, lstat64, const char *path, void *buf) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf);
+  if (common_flags()->intercept_stat)
+    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
+  int res = REAL(lstat64)(path, buf);
+  if (!res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
+  return res;
+}
+#define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64)
+#else
+#define INIT_LSTAT64
+#endif
+
 #if SANITIZER_INTERCEPT___XSTAT
 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
   void *ctx;
@@ -10516,8 +10549,10 @@ static void InitializeCommonInterceptors() {
   INIT_RECV_RECVFROM;
   INIT_SEND_SENDTO;
   INIT_STAT;
+  INIT_STAT64;
   INIT_EVENTFD_READ_WRITE;
   INIT_LSTAT;
+  INIT_LSTAT64;
   INIT___XSTAT;
   INIT___XSTAT64;
   INIT___LXSTAT;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 14610f2df78df..4c9677d20c088 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -465,6 +465,7 @@
 #define SANITIZER_INTERCEPT_STAT                                        \
   (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS ||     \
    SI_STAT_LINUX)
+#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX
 #define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX)
 #define SANITIZER_INTERCEPT___XSTAT \
   ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX)

diff  --git a/compiler-rt/test/msan/fstat64.cpp b/compiler-rt/test/msan/fstat64.cpp
new file mode 100644
index 0000000000000..8e3a6d553bfcf
--- /dev/null
+++ b/compiler-rt/test/msan/fstat64.cpp
@@ -0,0 +1,16 @@
+// REQUIRES: linux
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int main(void) {
+  struct stat64 st;
+  if (fstat64(0, &st))
+    exit(1);
+
+  if (S_ISBLK(st.st_mode))
+    exit(0);
+
+  return 0;
+}

diff  --git a/compiler-rt/test/msan/fstatat64.cpp b/compiler-rt/test/msan/fstatat64.cpp
new file mode 100644
index 0000000000000..253299c456694
--- /dev/null
+++ b/compiler-rt/test/msan/fstatat64.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: linux
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+
+#include <cassert>
+#include <cstdlib>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int main(void) {
+  struct stat64 st;
+  int dirfd = open("/dev", O_RDONLY);
+  if (fstatat64(dirfd, "null", &st, 0))
+    exit(1);
+
+  assert(S_ISCHR(st.st_mode));
+
+  return 0;
+}

diff  --git a/compiler-rt/test/msan/stat64.cpp b/compiler-rt/test/msan/stat64.cpp
new file mode 100644
index 0000000000000..a1280a0de37d2
--- /dev/null
+++ b/compiler-rt/test/msan/stat64.cpp
@@ -0,0 +1,16 @@
+// REQUIRES: linux
+// RUN: %clangxx_msan -O0 %s -o %t && %run %t
+
+#include <cassert>
+#include <cstdlib>
+#include <sys/stat.h>
+
+int main(void) {
+  struct stat64 st;
+  if (stat64("/dev/null", &st))
+    exit(1);
+
+  assert(S_ISCHR(st.st_mode));
+
+  return 0;
+}

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/lstat64.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/lstat64.cpp
new file mode 100644
index 0000000000000..22ab3068274ee
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/lstat64.cpp
@@ -0,0 +1,19 @@
+// REQUIRES: linux
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+int main(void) {
+  struct stat64 st;
+
+  assert(!lstat64("/dev/null", &st));
+#if defined(__sun__) && defined(__svr4__)
+  assert(S_ISLNK(st.st_mode));
+#else
+  assert(S_ISCHR(st.st_mode));
+#endif
+
+  return 0;
+}


        


More information about the llvm-commits mailing list