[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:
committed by
Vitaly Buka
parent
cfaa84e1a6
commit
5f5fb56c68
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
13
compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c
Normal file
13
compiler-rt/test/sanitizer_common/TestCases/Posix/uname.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user