Skip to content

Commit 5f5fb56

Browse files
iii-ivitalybuka
authored andcommitted
[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
1 parent cfaa84e commit 5f5fb56

File tree

5 files changed

+60
-29
lines changed

5 files changed

+60
-29
lines changed

compiler-rt/lib/msan/msan_interceptors.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -824,30 +824,6 @@ INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
824824
#define MSAN_MAYBE_INTERCEPT_PRLIMIT64
825825
#endif
826826

827-
#if SANITIZER_FREEBSD
828-
// FreeBSD's <sys/utsname.h> define uname() as
829-
// static __inline int uname(struct utsname *name) {
830-
// return __xuname(SYS_NMLN, (void*)name);
831-
// }
832-
INTERCEPTOR(int, __xuname, int size, void *utsname) {
833-
ENSURE_MSAN_INITED();
834-
int res = REAL(__xuname)(size, utsname);
835-
if (!res)
836-
__msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
837-
return res;
838-
}
839-
#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)
840-
#else
841-
INTERCEPTOR(int, uname, struct utsname *utsname) {
842-
ENSURE_MSAN_INITED();
843-
int res = REAL(uname)(utsname);
844-
if (!res)
845-
__msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
846-
return res;
847-
}
848-
#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)
849-
#endif
850-
851827
INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
852828
ENSURE_MSAN_INITED();
853829
int res = REAL(gethostname)(name, len);
@@ -1705,7 +1681,6 @@ void InitializeInterceptors() {
17051681
MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
17061682
MSAN_MAYBE_INTERCEPT_PRLIMIT;
17071683
MSAN_MAYBE_INTERCEPT_PRLIMIT64;
1708-
MSAN_INTERCEPT_UNAME;
17091684
INTERCEPT_FUNCTION(gethostname);
17101685
MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
17111686
MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9749,6 +9749,40 @@ INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
97499749
#define INIT_SIGALTSTACK
97509750
#endif
97519751

9752+
#if SANITIZER_INTERCEPT_UNAME
9753+
INTERCEPTOR(int, uname, struct utsname *utsname) {
9754+
void *ctx;
9755+
COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);
9756+
int res = REAL(uname)(utsname);
9757+
if (!res)
9758+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
9759+
__sanitizer::struct_utsname_sz);
9760+
return res;
9761+
}
9762+
#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)
9763+
#else
9764+
#define INIT_UNAME
9765+
#endif
9766+
9767+
#if SANITIZER_INTERCEPT___XUNAME
9768+
// FreeBSD's <sys/utsname.h> define uname() as
9769+
// static __inline int uname(struct utsname *name) {
9770+
// return __xuname(SYS_NMLN, (void*)name);
9771+
// }
9772+
INTERCEPTOR(int, __xuname, int size, void *utsname) {
9773+
void *ctx;
9774+
COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);
9775+
int res = REAL(__xuname)(size, utsname);
9776+
if (!res)
9777+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
9778+
__sanitizer::struct_utsname_sz);
9779+
return res;
9780+
}
9781+
#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)
9782+
#else
9783+
#define INIT___XUNAME
9784+
#endif
9785+
97529786
#include "sanitizer_common_interceptors_netbsd_compat.inc"
97539787

97549788
static void InitializeCommonInterceptors() {
@@ -10055,6 +10089,8 @@ static void InitializeCommonInterceptors() {
1005510089
INIT_QSORT;
1005610090
INIT_QSORT_R;
1005710091
INIT_SIGALTSTACK;
10092+
INIT_UNAME;
10093+
INIT___XUNAME;
1005810094

1005910095
INIT___PRINTF_CHK;
1006010096
}

compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515

1616
#if SANITIZER_LINUX && SANITIZER_S390
1717

18-
#include "sanitizer_libc.h"
19-
#include "sanitizer_linux.h"
20-
18+
#include <dlfcn.h>
2119
#include <errno.h>
2220
#include <sys/syscall.h>
2321
#include <sys/utsname.h>
2422
#include <unistd.h>
2523

24+
#include "sanitizer_libc.h"
25+
#include "sanitizer_linux.h"
26+
2627
namespace __sanitizer {
2728

2829
// --------------- sanitizer_libc.h
@@ -122,8 +123,12 @@ static bool FixedCVE_2016_2143() {
122123
// adjust this for their own kernels.
123124
struct utsname buf;
124125
unsigned int major, minor, patch = 0;
126+
// Depending on the concrete sanitizer being used, uname may or may not
127+
// be intercepted. Make sure we use the libc version in either case.
128+
using Uname = int (*)(struct utsname *);
129+
Uname uname = reinterpret_cast<Uname>(dlsym(RTLD_NEXT, "uname"));
125130
// This should never fail, but just in case...
126-
if (uname(&buf))
131+
if (uname == nullptr || uname(&buf))
127132
return false;
128133
const char *ptr = buf.release;
129134
major = internal_simple_strtoll(ptr, &ptr, 10);

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,5 +597,7 @@
597597
(SI_POSIX && !SI_IOSSIM && !SI_WATCHOS && !SI_TVOS && !SI_ANDROID)
598598
#define SANITIZER_INTERCEPT_QSORT_R (SI_LINUX && !SI_ANDROID)
599599
#define SANITIZER_INTERCEPT_SIGALTSTACK SI_POSIX
600+
#define SANITIZER_INTERCEPT_UNAME (SI_POSIX && !SI_FREEBSD)
601+
#define SANITIZER_INTERCEPT___XUNAME SI_FREEBSD
600602

601603
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang %s -o %t && %run %t
2+
3+
#include <assert.h>
4+
#include <stdio.h>
5+
#include <sys/utsname.h>
6+
7+
int main() {
8+
struct utsname buf;
9+
int err = uname(&buf);
10+
assert(err == 0);
11+
printf("%s %s %s %s %s\n", buf.sysname, buf.nodename, buf.release,
12+
buf.version, buf.machine);
13+
}

0 commit comments

Comments
 (0)