[compiler-rt] 2ca7fe3 - [compiler-rt] Use uname syscall in GetKernelAreaSize()

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 26 05:37:43 PDT 2020


Author: Ilya Leoshkevich
Date: 2020-03-26T13:35:09+01:00
New Revision: 2ca7fe3796475ec5afc1c804a3f92abbfa4cb2f9

URL: https://github.com/llvm/llvm-project/commit/2ca7fe3796475ec5afc1c804a3f92abbfa4cb2f9
DIFF: https://github.com/llvm/llvm-project/commit/2ca7fe3796475ec5afc1c804a3f92abbfa4cb2f9.diff

LOG: [compiler-rt] Use uname syscall in GetKernelAreaSize()

Commit 5f5fb56c68e4 ("[compiler-rt] Intercept the uname() function")
broke clang-cmake-thumbv7-full-sh build:

http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-full-sh/builds/4296

This also affects i386.

The reason is that intercepted uname() is called by GetKernelAreaSize()
during ASAN initialization on 32-bit platforms, but the respective
interceptor is not initialized yet at this point, leading to null
pointer dereference.

Introduce internal_uname() wrapper around uname syscall, and use it in
GetKernelAreaSize() and in FixedCVE_2016_2143().

Author: Ilya Leoshkevich
Reviewed By: Evgenii Stepanov

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

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_linux.h
    compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 3c09e74928e9..b5261409de9c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -1015,9 +1015,8 @@ static uptr GetKernelAreaSize() {
   // is modified (e.g. under schroot) so check this as well.
   struct utsname uname_info;
   int pers = personality(0xffffffffUL);
-  if (!(pers & PER_MASK)
-      && uname(&uname_info) == 0
-      && internal_strstr(uname_info.machine, "64"))
+  if (!(pers & PER_MASK) && internal_uname(&uname_info) == 0 &&
+      internal_strstr(uname_info.machine, "64"))
     return 0;
 #endif  // SANITIZER_ANDROID
 
@@ -1629,6 +1628,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
 }
 #endif  // defined(__x86_64__) && SANITIZER_LINUX
 
+#if SANITIZER_LINUX
+int internal_uname(struct utsname *buf) {
+  return internal_syscall(SYSCALL(uname), buf);
+}
+#endif
+
 #if SANITIZER_ANDROID
 #if __ANDROID_API__ < 21
 extern "C" __attribute__((weak)) int dl_iterate_phdr(

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index c28347ad963a..25a7e0b79bab 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -25,6 +25,7 @@
 #include "sanitizer_posix.h"
 
 struct link_map;  // Opaque type returned by dlopen().
+struct utsname;
 
 namespace __sanitizer {
 // Dirent structure for getdents(). Note that this structure is 
diff erent from
@@ -64,6 +65,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
   || defined(__arm__)
 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr);
+int internal_uname(struct utsname *buf);
 #endif
 #elif SANITIZER_FREEBSD
 void internal_sigdelset(__sanitizer_sigset_t *set, int signum);

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
index 16b4c9b633d8..bb2f5b5f9f7d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp
@@ -123,12 +123,8 @@ 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 == nullptr || uname(&buf))
+  if (internal_uname(&buf))
     return false;
   const char *ptr = buf.release;
   major = internal_simple_strtoll(ptr, &ptr, 10);


        


More information about the llvm-commits mailing list