From 63bd043a1249224c09eb1d1eb95547b5f9af8c71 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Fri, 25 Jan 2019 02:18:01 +0000 Subject: [PATCH] Enhance support for NetBSD in SafeStack Summary: Always try to detect and call internal or real libc symbols instead of locally installed interceptors. This covers: - GetTid() - TgKill() - Mmap() - Munmap() - Mprotect() This cherry-picks code from sanitizer_common/sanitizer_netbsd.cc. Reviewers: vitalybuka Reviewed By: vitalybuka Subscribers: llvm-commits, mgorny, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D57179 llvm-svn: 352154 --- .../lib/safestack/safestack_platform.h | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index b906d52d56e9..81e4c2645ce2 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -13,9 +13,13 @@ #ifndef SAFESTACK_PLATFORM_H #define SAFESTACK_PLATFORM_H +#include "safestack_util.h" #include "sanitizer_common/sanitizer_platform.h" +#include #include +#include +#include #include #include #include @@ -27,6 +31,8 @@ #if SANITIZER_NETBSD #include + +extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #endif #if SANITIZER_FREEBSD @@ -35,11 +41,34 @@ namespace safestack { +#if SANITIZER_NETBSD +static void *GetRealLibcAddress(const char *symbol) { + void *real = dlsym(RTLD_NEXT, symbol); + if (!real) + real = dlsym(RTLD_DEFAULT, symbol); + if (!real) { + fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s", + symbol); + abort(); + } + return real; +} + +#define _REAL(func, ...) real##_##func(__VA_ARGS__) +#define DEFINE__REAL(ret_type, func, ...) \ + static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ + if (!real_##func) { \ + real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ + } \ + SFS_CHECK(real_##func); +#endif + using ThreadId = uint64_t; inline ThreadId GetTid() { #if SANITIZER_NETBSD - return _lwp_self(); + DEFINE__REAL(int, _lwp_self); + return _REAL(_lwp_self); #elif SANITIZER_FREEBSD long Tid; thr_self(&Tid); @@ -51,8 +80,9 @@ inline ThreadId GetTid() { inline int TgKill(pid_t pid, ThreadId tid, int sig) { #if SANITIZER_NETBSD + DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; - return _lwp_kill(tid, sig); + return _REAL(_lwp_kill, tid, sig); #elif SANITIZER_FREEBSD return syscall(SYS_thr_kill2, pid, tid, sig); #else @@ -63,7 +93,7 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) { inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { #if SANITIZER_NETBSD - return mmap(addr, length, prot, flags, fd, offset); + return __mmap(addr, length, prot, flags, fd, 0, offset); #elif defined(__x86_64__) && (SANITIZER_FREEBSD) return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset); #else @@ -73,7 +103,8 @@ inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd, inline int Munmap(void *addr, size_t length) { #if SANITIZER_NETBSD - return munmap(addr, length); + DEFINE__REAL(int, munmap, void *a, size_t b); + return _REAL(munmap, addr, length); #else return syscall(SYS_munmap, addr, length); #endif @@ -81,7 +112,8 @@ inline int Munmap(void *addr, size_t length) { inline int Mprotect(void *addr, size_t length, int prot) { #if SANITIZER_NETBSD - return mprotect(addr, length, prot); + DEFINE__REAL(int, mprotect, void *a, size_t b, int c); + return _REAL(mprotect, addr, length, prot); #else return syscall(SYS_mprotect, addr, length, prot); #endif