[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