[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
This commit is contained in:
Ilya Leoshkevich
2020-03-23 12:46:20 -07:00
committed by Vitaly Buka
parent cfaa84e1a6
commit 5f5fb56c68
5 changed files with 60 additions and 29 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}