OpenBSD UBsan support missing bits

Summary:
Lost bits since the WIP ticket

Patch by David CARLIER

Reviewers: vitalybuka, vsk

Reviewed By: vitalybuka

Subscribers: srhines, kubamracek, krytarowski, fedor.sergeev, llvm-commits, #sanitizers

Differential Revision: https://reviews.llvm.org/D44599

llvm-svn: 327923
This commit is contained in:
Vitaly Buka 2018-03-19 23:12:14 +00:00
parent f92817ab23
commit 544a5555c5
2 changed files with 99 additions and 67 deletions

View File

@ -14,8 +14,8 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_OPENBSD || SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
@ -64,7 +64,12 @@
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#if !SANITIZER_OPENBSD
#include <ucontext.h>
#endif
#if SANITIZER_OPENBSD
#include <sys/futex.h>
#endif
#include <unistd.h>
#if SANITIZER_LINUX
@ -123,8 +128,8 @@ const int FUTEX_WAKE = 1;
// Are we using 32-bit or 64-bit Linux syscalls?
// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
// but it still needs to use 64-bit syscalls.
#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \
SANITIZER_WORDSIZE == 64)
#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \
SANITIZER_WORDSIZE == 64)
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
#else
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
@ -159,7 +164,7 @@ namespace __sanitizer {
// --------------- sanitizer_libc.h
#if !SANITIZER_SOLARIS
#if !SANITIZER_S390
#if !SANITIZER_S390 && !SANITIZER_OPENBSD
uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
OFF_T offset) {
#if SANITIZER_NETBSD
@ -175,8 +180,9 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
offset / 4096);
#endif
}
#endif // !SANITIZER_S390
#endif // !SANITIZER_S390 && !SANITIZER_OPENBSD
#if !SANITIZER_OPENBSD
uptr internal_munmap(void *addr, uptr length) {
return internal_syscall_ptr(SYSCALL(munmap), (uptr)addr, length);
}
@ -184,6 +190,7 @@ uptr internal_munmap(void *addr, uptr length) {
int internal_mprotect(void *addr, uptr length, int prot) {
return internal_syscall_ptr(SYSCALL(mprotect), (uptr)addr, length, prot);
}
#endif
uptr internal_close(fd_t fd) {
return internal_syscall(SYSCALL(close), fd);
@ -299,12 +306,12 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
#endif
uptr internal_stat(const char *path, void *buf) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
(uptr)buf, 0);
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
0);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
(uptr)buf, 0);
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
0);
#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
# if defined(__mips64)
// For mips64, stat syscall fills buffer in the format of kernel_stat
@ -326,12 +333,12 @@ uptr internal_stat(const char *path, void *buf) {
uptr internal_lstat(const char *path, void *buf) {
#if SANITIZER_NETBSD
return internal_syscall_ptr(SYSCALL(lstat), path, buf);
#elif SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
(uptr)buf, AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_FREEBSD || SANITIZER_OPENBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
(uptr)buf, AT_SYMLINK_NOFOLLOW);
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
# if SANITIZER_MIPS64
// For mips64, lstat syscall fills buffer in the format of kernel_stat
@ -351,8 +358,9 @@ uptr internal_lstat(const char *path, void *buf) {
}
uptr internal_fstat(fd_t fd, void *buf) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
# if SANITIZER_MIPS64 && !SANITIZER_NETBSD
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
SANITIZER_LINUX_USES_64BIT_SYSCALLS
#if SANITIZER_MIPS64 && !SANITIZER_NETBSD && !SANITIZER_OPENBSD
// For mips64, fstat syscall fills buffer in the format of kernel_stat
struct kernel_stat kbuf;
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
@ -385,16 +393,16 @@ uptr internal_dup2(int oldfd, int newfd) {
}
uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD,
(uptr)path, (uptr)buf, bufsize);
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
bufsize);
#else
return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize);
#endif
}
uptr internal_unlink(const char *path) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
#else
return internal_syscall_ptr(SYSCALL(unlink), (uptr)path);
@ -402,7 +410,7 @@ uptr internal_unlink(const char *path) {
}
uptr internal_rename(const char *oldpath, const char *newpath) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath);
#else
@ -415,7 +423,7 @@ uptr internal_sched_yield() {
}
void internal__exit(int exitcode) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
internal_syscall(SYSCALL(exit), exitcode);
#else
internal_syscall(SYSCALL(exit_group), exitcode);
@ -435,7 +443,7 @@ unsigned int internal_sleep(unsigned int seconds) {
uptr internal_execve(const char *filename, char *const argv[],
char *const envp[]) {
return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv,
(uptr)envp);
(uptr)envp);
}
#endif // !SANITIZER_SOLARIS
@ -457,6 +465,8 @@ tid_t GetTid() {
long Tid;
thr_self(&Tid);
return Tid;
#elif SANITIZER_OPENBSD
return internal_syscall(SYSCALL(getthrid));
#elif SANITIZER_NETBSD
return _lwp_self();
#elif SANITIZER_SOLARIS
@ -468,7 +478,7 @@ tid_t GetTid() {
#if !SANITIZER_SOLARIS
u64 NanoTime() {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
timeval tv;
#else
kernel_timeval tv;
@ -487,7 +497,8 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
// 'environ' array (on some others) and does not use libc. This function
// should be called first inside __asan_init.
const char *GetEnv(const char *name) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
SANITIZER_SOLARIS
if (::environ != 0) {
uptr NameLen = internal_strlen(name);
for (char **Env = ::environ; *Env != 0; Env++) {
@ -525,13 +536,14 @@ const char *GetEnv(const char *name) {
#endif
}
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_OPENBSD
extern "C" {
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
}
#endif
#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD
#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
!SANITIZER_OPENBSD
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@ -556,6 +568,7 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
}
#endif
#if !SANITIZER_OPENBSD
static void GetArgsAndEnv(char ***argv, char ***envp) {
#if SANITIZER_FREEBSD
// On FreeBSD, retrieving the argument and environment arrays is done via the
@ -572,10 +585,10 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
#elif SANITIZER_NETBSD
*argv = __ps_strings->ps_argvstr;
*envp = __ps_strings->ps_envstr;
#else
#else // SANITIZER_FREEBSD
#if !SANITIZER_GO
if (&__libc_stack_end) {
#endif
#endif // !SANITIZER_GO
uptr* stack_end = (uptr*)__libc_stack_end;
int argc = *stack_end;
*argv = (char**)(stack_end + 1);
@ -586,8 +599,8 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
}
#endif
#endif
#endif // !SANITIZER_GO
#endif // SANITIZER_FREEBSD
}
char **GetArgv() {
@ -622,6 +635,7 @@ void ReExec() {
Printf("execve failed, errno %d\n", rverrno);
Die();
}
#endif
#if !SANITIZER_SOLARIS
enum MutexState {
@ -675,7 +689,7 @@ void BlockingMutex::CheckLocked() {
// The actual size of this structure is specified by d_reclen.
// Note that getdents64 uses a different structure format. We only provide the
// 32-bit syscall here.
#if SANITIZER_NETBSD
#if SANITIZER_NETBSD || SANITIZER_OPENBSD
// struct dirent is different for Linux and us. At this moment, we use only
// d_fileno (Linux call this d_ino), d_reclen, and d_name.
struct linux_dirent {
@ -828,19 +842,18 @@ int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
__sanitizer_sigaction u_adjust;
internal_memcpy(&u_adjust, act, sizeof(u_adjust));
#if !SANITIZER_ANDROID || !SANITIZER_MIPS32
if (u_adjust.sa_restorer == nullptr) {
u_adjust.sa_restorer = internal_sigreturn;
}
if (u_adjust.sa_restorer == nullptr) {
u_adjust.sa_restorer = internal_sigreturn;
}
#endif
return internal_sigaction_norestorer(signum, (const void *)&u_adjust,
oldact);
return internal_sigaction_norestorer(signum, (const void *)&u_adjust, oldact);
}
#endif // defined(__x86_64__) && !SANITIZER_GO
#endif // defined(__x86_64__) && !SANITIZER_GO
#endif // SANITIZER_LINUX
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
__sanitizer_sigset_t *oldset) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
__sanitizer_sigset_t *oldset) {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
return internal_syscall_ptr(SYSCALL(sigprocmask), how, set, oldset);
#else
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
@ -986,7 +999,7 @@ static uptr GetKernelAreaSize() {
#endif // SANITIZER_WORDSIZE == 32
uptr GetMaxVirtualAddress() {
#if SANITIZER_NETBSD && defined(__x86_64__)
#if (SANITIZER_NETBSD || SANITIZER_OPENBSD) && defined(__x86_64__)
return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
#elif SANITIZER_WORDSIZE == 64
# if defined(__powerpc64__) || defined(__aarch64__)
@ -1037,6 +1050,7 @@ uptr GetPageSize() {
#endif
}
#if !SANITIZER_OPENBSD
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
#if SANITIZER_SOLARIS
const char *default_module_name = getexecname();
@ -1072,6 +1086,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
return module_name_len;
#endif
}
#endif // !SANITIZER_OPENBSD
uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
#if SANITIZER_LINUX
@ -1104,10 +1119,10 @@ bool LibraryNameIs(const char *full_name, const char *base_name) {
// Call cb for each region mapped by map.
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
CHECK_NE(map, nullptr);
#if !SANITIZER_FREEBSD
#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
typedef ElfW(Phdr) Elf_Phdr;
typedef ElfW(Ehdr) Elf_Ehdr;
#endif // !SANITIZER_FREEBSD
#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
char *base = (char *)map->l_addr;
Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
char *phdrs = base + ehdr->e_phoff;
@ -1690,6 +1705,7 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
#endif
SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
#if !SANITIZER_OPENBSD
ucontext_t *ucontext = (ucontext_t *)context;
#if defined(__x86_64__) || defined(__i386__)
static const uptr PF_WRITE = 1U << 1;
@ -1723,6 +1739,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
(void)ucontext;
return UNKNOWN; // FIXME: Implement.
#endif
#else // !SANITIZER_OPENBSD
return UNKNOWN;
#endif // !SANITIZER_OPENBSD
}
void SignalContext::DumpAllRegisters(void *context) {
@ -1898,5 +1917,4 @@ bool GetRandom(void *buffer, uptr length, bool blocking) {
} // namespace __sanitizer
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
// SANITIZER_SOLARIS
#endif

View File

@ -14,8 +14,8 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_OPENBSD || SANITIZER_SOLARIS
#include "sanitizer_allocator_internal.h"
#include "sanitizer_atomic.h"
@ -42,6 +42,11 @@
#define pthread_getattr_np pthread_attr_get_np
#endif
#if SANITIZER_OPENBSD
#include <pthread_np.h>
#include <sys/sysctl.h>
#endif
#if SANITIZER_NETBSD
#include <sys/sysctl.h>
#include <sys/tls.h>
@ -127,7 +132,12 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
CHECK_EQ(thr_stksegment(&ss), 0);
stacksize = ss.ss_size;
stackaddr = (char *)ss.ss_sp - stacksize;
#else // !SANITIZER_SOLARIS
#elif SANITIZER_OPENBSD
stack_t sattr;
CHECK_EQ(pthread_stackseg_np(pthread_self(), &sattr), 0);
stackaddr = sattr.ss_sp;
stacksize = sattr.ss_size;
#else // !SANITIZER_SOLARIS
pthread_attr_t attr;
pthread_attr_init(&attr);
CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
@ -173,8 +183,8 @@ bool SanitizerGetThreadName(char *name, int max_len) {
#endif
}
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
!SANITIZER_NETBSD && !SANITIZER_SOLARIS
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
!SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_SOLARIS
static uptr g_tls_size;
#ifdef __i386__
@ -184,7 +194,7 @@ static uptr g_tls_size;
#endif
void InitTlsSize() {
// all current supported platforms have 16 bytes stack alignment
// all current supported platforms have 16 bytes stack alignment
const size_t kStackAlign = 16;
typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
get_tls_func get_tls;
@ -205,9 +215,10 @@ void InitTlsSize() { }
#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO &&
// !SANITIZER_NETBSD && !SANITIZER_SOLARIS
#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \
|| defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) \
|| defined(__arm__)) && SANITIZER_LINUX && !SANITIZER_ANDROID
#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \
defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \
defined(__arm__)) && \
SANITIZER_LINUX && !SANITIZER_ANDROID
// sizeof(struct pthread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
@ -432,6 +443,9 @@ static void GetTls(uptr *addr, uptr *size) {
*addr = (uptr)tcb->tcb_dtv[1];
}
}
#elif SANITIZER_OPENBSD
*addr = 0;
*size = 0;
#elif SANITIZER_ANDROID
*addr = 0;
*size = 0;
@ -447,8 +461,8 @@ static void GetTls(uptr *addr, uptr *size) {
#if !SANITIZER_GO
uptr GetTlsSize() {
#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \
SANITIZER_OPENBSD || SANITIZER_SOLARIS
uptr addr, size;
GetTls(&addr, &size);
return size;
@ -485,13 +499,13 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
#endif
}
# if !SANITIZER_FREEBSD
#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
typedef ElfW(Phdr) Elf_Phdr;
# elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2
# define Elf_Phdr XElf32_Phdr
# define dl_phdr_info xdl_phdr_info
# define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b))
# endif
#elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2
#define Elf_Phdr XElf32_Phdr
#define dl_phdr_info xdl_phdr_info
#define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b))
#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
struct DlIteratePhdrData {
InternalMmapVectorNoCtor<LoadedModule> *modules;
@ -611,7 +625,7 @@ uptr GetRSS() {
// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as
// they allocate memory.
u32 GetNumberOfCPUs() {
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
u32 ncpu;
int req[2];
size_t len = sizeof(ncpu);
@ -770,4 +784,4 @@ u64 MonotonicNanoTime() {
} // namespace __sanitizer
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
#endif