[compiler-rt] 5f5fb56 - [compiler-rt] Intercept the uname() function

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 23 13:06:58 PDT 2020


Author: Ilya Leoshkevich
Date: 2020-03-23T12:59:38-07:00
New Revision: 5f5fb56c68e4830597a5b52d7a8edafea21566ac

URL: https://github.com/llvm/llvm-project/commit/5f5fb56c68e4830597a5b52d7a8edafea21566ac
DIFF: https://github.com/llvm/llvm-project/commit/5f5fb56c68e4830597a5b52d7a8edafea21566ac.diff

LOG: [compiler-rt] Intercept the uname() function

Summary:
Move interceptor from msan to sanitizer_common_interceptors.inc, so that
other sanitizers could benefit.

Adjust FixedCVE_2016_2143() to deal with the intercepted uname().

Patch by Ilya Leoshkevich.

Reviewers: eugenis, vitalybuka, uweigand, jonpa

Reviewed By: eugenis, vitalybuka

Subscribers: dberris, krytarowski, #sanitizers, stefansf, Andreas-Krebbel

Tags: #sanitizers

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

Added: 
    compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c

Modified: 
    compiler-rt/lib/msan/msan_interceptors.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
    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 4cdce7e29af1..9b1340b0104e 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cpp
+++ b/compiler-rt/lib/msan/msan_interceptors.cpp
@@ -824,30 +824,6 @@ INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
 #define MSAN_MAYBE_INTERCEPT_PRLIMIT64
 #endif
 
-#if SANITIZER_FREEBSD
-// FreeBSD's <sys/utsname.h> define uname() as
-// static __inline int uname(struct utsname *name) {
-//   return __xuname(SYS_NMLN, (void*)name);
-// }
-INTERCEPTOR(int, __xuname, int size, void *utsname) {
-  ENSURE_MSAN_INITED();
-  int res = REAL(__xuname)(size, utsname);
-  if (!res)
-    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
-  return res;
-}
-#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)
-#else
-INTERCEPTOR(int, uname, struct utsname *utsname) {
-  ENSURE_MSAN_INITED();
-  int res = REAL(uname)(utsname);
-  if (!res)
-    __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
-  return res;
-}
-#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)
-#endif
-
 INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
   ENSURE_MSAN_INITED();
   int res = REAL(gethostname)(name, len);
@@ -1705,7 +1681,6 @@ void InitializeInterceptors() {
   MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
   MSAN_MAYBE_INTERCEPT_PRLIMIT;
   MSAN_MAYBE_INTERCEPT_PRLIMIT64;
-  MSAN_INTERCEPT_UNAME;
   INTERCEPT_FUNCTION(gethostname);
   MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
   MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 6daed4a6736c..8267b3bb4dd0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -9749,6 +9749,40 @@ INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
 #define INIT_SIGALTSTACK
 #endif
 
+#if SANITIZER_INTERCEPT_UNAME
+INTERCEPTOR(int, uname, struct utsname *utsname) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);
+  int res = REAL(uname)(utsname);
+  if (!res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
+                                   __sanitizer::struct_utsname_sz);
+  return res;
+}
+#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)
+#else
+#define INIT_UNAME
+#endif
+
+#if SANITIZER_INTERCEPT___XUNAME
+// FreeBSD's <sys/utsname.h> define uname() as
+// static __inline int uname(struct utsname *name) {
+//   return __xuname(SYS_NMLN, (void*)name);
+// }
+INTERCEPTOR(int, __xuname, int size, void *utsname) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);
+  int res = REAL(__xuname)(size, utsname);
+  if (!res)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
+                                   __sanitizer::struct_utsname_sz);
+  return res;
+}
+#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)
+#else
+#define INIT___XUNAME
+#endif
+
 #include "sanitizer_common_interceptors_netbsd_compat.inc"
 
 static void InitializeCommonInterceptors() {
@@ -10055,6 +10089,8 @@ static void InitializeCommonInterceptors() {
   INIT_QSORT;
   INIT_QSORT_R;
   INIT_SIGALTSTACK;
+  INIT_UNAME;
+  INIT___XUNAME;
 
   INIT___PRINTF_CHK;
 }

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
index 9e3b4f13a436..16b4c9b633d8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
@@ -15,14 +15,15 @@
 
 #if SANITIZER_LINUX && SANITIZER_S390
 
-#include "sanitizer_libc.h"
-#include "sanitizer_linux.h"
-
+#include <dlfcn.h>
 #include <errno.h>
 #include <sys/syscall.h>
 #include <sys/utsname.h>
 #include <unistd.h>
 
+#include "sanitizer_libc.h"
+#include "sanitizer_linux.h"
+
 namespace __sanitizer {
 
 // --------------- sanitizer_libc.h
@@ -122,8 +123,12 @@ static bool FixedCVE_2016_2143() {
   // adjust this for their own kernels.
   struct utsname buf;
   unsigned int major, minor, patch = 0;
+  // Depending on the concrete sanitizer being used, uname may or may not
+  // be intercepted. Make sure we use the libc version in either case.
+  using Uname = int (*)(struct utsname *);
+  Uname uname = reinterpret_cast<Uname>(dlsym(RTLD_NEXT, "uname"));
   // This should never fail, but just in case...
-  if (uname(&buf))
+  if (uname == nullptr || uname(&buf))
     return false;
   const char *ptr = buf.release;
   major = internal_simple_strtoll(ptr, &ptr, 10);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 8d08c0de1770..9dd6d285f594 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -597,5 +597,7 @@
   (SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID)
 #define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID)
 #define SANITIZER_INTERCEPT_SIGALTSTACK SI_POSIX
+#define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD)
+#define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c
new file mode 100644
index 000000000000..0bf7e0fd98e3
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c
@@ -0,0 +1,13 @@
+// RUN: %clang %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdio.h>
+#include <sys/utsname.h>
+
+int main() {
+  struct utsname buf;
+  int err = uname(&buf);
+  assert(err == 0);
+  printf("%s %s %s %s %s\n", buf.sysname, buf.nodename, buf.release,
+         buf.version, buf.machine);
+}


        


More information about the llvm-commits mailing list