diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h --- 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 different from @@ -71,6 +72,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum); uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg); #endif // SANITIZER_LINUX +int internal_uname(struct utsname *buf); // This class reads thread IDs from /proc//task using only syscalls. class ThreadLister { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -1015,7 +1015,7 @@ struct utsname uname_info; int pers = personality(0xffffffffUL); if (!(pers & PER_MASK) - && uname(&uname_info) == 0 + && internal_uname(&uname_info) == 0 && internal_strstr(uname_info.machine, "64")) return 0; #endif // SANITIZER_ANDROID @@ -1627,6 +1627,18 @@ } #endif // defined(__x86_64__) && SANITIZER_LINUX +int internal_uname(struct utsname *buf) { + // 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 real = reinterpret_cast(dlsym(RTLD_NEXT, "uname")); + if (real == nullptr) { + errno = -ENOSYS; + return -1; + } + return real(buf); +} + #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_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp @@ -123,12 +123,8 @@ // 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(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);