Index: lib/sanitizer_common/CMakeLists.txt =================================================================== --- lib/sanitizer_common/CMakeLists.txt +++ lib/sanitizer_common/CMakeLists.txt @@ -16,9 +16,11 @@ sanitizer_linux.cc sanitizer_linux_s390.cc sanitizer_mac.cc + sanitizer_openbsd.cc sanitizer_persistent_allocator.cc sanitizer_platform_limits_linux.cc sanitizer_platform_limits_netbsd.cc + sanitizer_platform_limits_openbsd.cc sanitizer_platform_limits_posix.cc sanitizer_platform_limits_solaris.cc sanitizer_posix.cc Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -3590,7 +3590,7 @@ // * GNU version returns message pointer, which points to either buf or some // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ - SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD + SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { @@ -4405,25 +4405,36 @@ #endif #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET -INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) -INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) -INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) -INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) -INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) -INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) -INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); - // FIXME: under ASan the call below may write to freed memory and corrupt - // its metadata. See - // https://github.com/google/sanitizers/issues/321. - int res = REAL(pthread_attr_getstack)(attr, addr, size); - if (!res) { - if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); - if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); - } - return res; -} +#define COMMON_INTERCEPTOR_PTHREAD_ATTR_GET \ +INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) \ +INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) \ +INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) \ +INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) \ +INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); \ + // FIXME: under ASan the call below may write to freed memory and corrupt \ + // its metadata. See \ + // https://github.com/google/sanitizers/issues/321. \ + int res = REAL(pthread_attr_getstack)(attr, addr, size); \ + if (!res) { \ + if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); \ + if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); \ + } \ + return res; \ +} + +#if !SANITIZER_OPENBSD +#define SANITIZER_INTERCEPTOR_PTHREAD_ATTR_GET \ +COMMON_INTERCEPTOR_PTHREAD_ATTR_GET \ +INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) \ +INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) +#else +#define SANITIZER_INTERCEPTOR_PTHREAD_ATTR_GET \ +COMMON_INTERCEPTOR_PTHREAD_ATTR_GET +#endif + +SANITIZER_INTERCEPTOR_PTHREAD_ATTR_GET // We may need to call the real pthread_attr_getstack from the run-time // in sanitizer_common, but we don't want to include the interception headers @@ -4436,14 +4447,21 @@ } // extern "C" } // namespace __sanitizer -#define INIT_PTHREAD_ATTR_GET \ +#define COMMON_INIT_PTHREAD_ATTR_GET \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ - COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ - COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); + +#if !SANITIZER_OPENBSD +#define INIT_PTHREAD_ATTR_GET \ + COMMON_INIT_PTHREAD_ATTR_GET \ + COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ + COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ +#else +#define INIT_PTHREAD_ATTR_GET COMMON_INIT_PTHREAD_ATTR_GET +#endif #else #define INIT_PTHREAD_ATTR_GET #endif Index: lib/sanitizer_common/sanitizer_errno.h =================================================================== --- lib/sanitizer_common/sanitizer_errno.h +++ lib/sanitizer_common/sanitizer_errno.h @@ -24,7 +24,7 @@ #if SANITIZER_FREEBSD || SANITIZER_MAC # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD +#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD # define __errno_location __errno #elif SANITIZER_SOLARIS # define __errno_location ___errno Index: lib/sanitizer_common/sanitizer_internal_defs.h =================================================================== --- lib/sanitizer_common/sanitizer_internal_defs.h +++ lib/sanitizer_common/sanitizer_internal_defs.h @@ -39,7 +39,8 @@ #endif // TLS is handled differently on different platforms -#if SANITIZER_LINUX || SANITIZER_NETBSD || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_FREEBSD || SANITIZER_OPENBSD # define SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE \ __attribute__((tls_model("initial-exec"))) thread_local #else @@ -100,7 +101,7 @@ // FIXME: do we have anything like this on Mac? #ifndef SANITIZER_CAN_USE_PREINIT_ARRAY #if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || \ - SANITIZER_FREEBSD) && !defined(PIC) + SANITIZER_FREEBSD || SANITIZER_OPENBSD) && !defined(PIC) # define SANITIZER_CAN_USE_PREINIT_ARRAY 1 // Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. // FIXME: Check for those conditions. @@ -159,7 +160,8 @@ typedef int pid_t; #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_MAC || \ (SANITIZER_LINUX && defined(__x86_64__)) typedef u64 OFF_T; #else @@ -170,7 +172,7 @@ #if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC typedef uptr operator_new_size_type; #else -# if defined(__s390__) && !defined(__s390x__) +# if defined(SANITIZER_OPENBSD) || defined(__s390__) && !defined(__s390x__) // Special case: 31-bit s390 has unsigned long as size_t. typedef unsigned long operator_new_size_type; # else @@ -179,7 +181,7 @@ #endif #if SANITIZER_MAC -// On Darwin, thread IDs are 64-bit even on 32-bit systems. +// On Darwin, thread IDs are 64-bit even on 32 bits systems. typedef u64 tid_t; #else typedef uptr tid_t; Index: lib/sanitizer_common/sanitizer_libignore.cc =================================================================== --- lib/sanitizer_common/sanitizer_libignore.cc +++ lib/sanitizer_common/sanitizer_libignore.cc @@ -9,10 +9,12 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ + SANITIZER_NETBSD || SANITIZER_OPENBSD #include "sanitizer_libignore.h" #include "sanitizer_flags.h" + #include "sanitizer_posix.h" #include "sanitizer_procmaps.h" Index: lib/sanitizer_common/sanitizer_linux.h =================================================================== --- lib/sanitizer_common/sanitizer_linux.h +++ lib/sanitizer_common/sanitizer_linux.h @@ -15,10 +15,11 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" #include "sanitizer_platform_limits_solaris.h" #include "sanitizer_posix.h" Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -15,7 +15,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_flags.h" @@ -64,7 +64,11 @@ #include #include #include +#if !SANITIZER_OPENBSD #include +#else +#include +#endif #include #if SANITIZER_LINUX @@ -84,6 +88,7 @@ // FreeBSD 9.2 and 10.0. #include } +#include extern char **environ; // provided by crt1 #endif // SANITIZER_FREEBSD @@ -95,6 +100,12 @@ extern struct ps_strings *__ps_strings; #endif // SANITIZER_NETBSD +#if SANITIZER_OPENBSD +#include +#include +extern char **environ; +#endif + #if SANITIZER_SOLARIS #include #include @@ -123,7 +134,7 @@ // 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) + SANITIZER_WORDSIZE == 64) # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1 #else # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 @@ -158,13 +169,14 @@ // --------------- 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 return internal_syscall_ptr(SYSCALL(mmap), addr, length, prot, flags, fd, (long)0, offset); -#elif SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS +#elif SANITIZER_FREEBSD || \ + SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd, offset); #else @@ -174,8 +186,9 @@ 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); } @@ -183,6 +196,7 @@ 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); @@ -298,25 +312,25 @@ #endif uptr internal_stat(const char *path, void *buf) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path, - (uptr)buf, 0); + (uptr)buf, 0); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, + return internal_syscall_ptr(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 struct kernel_stat kbuf; - int res = internal_syscall(SYSCALL(stat), path, &kbuf); + int res = internal_syscall_ptr(SYSCALL(stat), path, &kbuf); kernel_stat_to_stat(&kbuf, (struct stat *)buf); return res; # else - return internal_syscall(SYSCALL(stat), (uptr)path, (uptr)buf); + return internal_syscall_ptr(SYSCALL(stat), (uptr)path, (uptr)buf); # endif #else struct stat64 buf64; - int res = internal_syscall(SYSCALL(stat64), path, &buf64); + int res = internal_syscall_ptr(SYSCALL(stat64), path, &buf64); stat64_to_stat(&buf64, (struct stat *)buf); return res; #endif @@ -325,12 +339,12 @@ uptr internal_lstat(const char *path, void *buf) { #if SANITIZER_NETBSD return internal_syscall_ptr(SYSCALL(lstat), path, buf); -#elif SANITIZER_FREEBSD +#elif SANITIZER_FREEBSD || SANITIZER_OPENBSD return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, - (uptr)buf, AT_SYMLINK_NOFOLLOW); + (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); + (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 @@ -350,8 +364,9 @@ } 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); @@ -384,26 +399,26 @@ } 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_ptr(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 - return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD + return internal_syscall_ptr(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); #else return internal_syscall_ptr(SYSCALL(unlink), (uptr)path); #endif } uptr internal_rename(const char *oldpath, const char *newpath) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD, - (uptr)newpath); +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD + return internal_syscall_ptr(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, + AT_FDCWD, (uptr)newpath); #else return internal_syscall_ptr(SYSCALL(rename), (uptr)oldpath, (uptr)newpath); #endif @@ -414,7 +429,7 @@ } 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); @@ -434,7 +449,7 @@ 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 @@ -454,6 +469,8 @@ tid_t GetTid() { #if SANITIZER_FREEBSD return (uptr)pthread_self(); +#elif SANITIZER_OPENBSD + return internal_syscall(SYSCALL(getthrid)); #elif SANITIZER_NETBSD return _lwp_self(); #elif SANITIZER_SOLARIS @@ -465,7 +482,7 @@ #if !SANITIZER_SOLARIS u64 NanoTime() { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD timeval tv; #else kernel_timeval tv; @@ -484,7 +501,8 @@ // '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++) { @@ -522,13 +540,14 @@ #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; @@ -569,6 +588,27 @@ #elif SANITIZER_NETBSD *argv = __ps_strings->ps_argvstr; *envp = __ps_strings->ps_envstr; +#elif SANITIZER_OPENBSD + size_t nargv; + size_t nenv; + int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV}; + int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV}; + if (sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_NARGV failed\n"); + Die(); + } + if (sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_NENV failed\n"); + Die(); + } + if (sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_ARGV failed\n"); + Die(); + } + if (sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_ENV failed\n"); + Die(); + } #else #if !SANITIZER_GO if (&__libc_stack_end) { @@ -672,7 +712,7 @@ // 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 { @@ -825,19 +865,19 @@ __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; @@ -983,7 +1023,7 @@ #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__) @@ -1039,6 +1079,16 @@ const char *default_module_name = getexecname(); CHECK_NE(default_module_name, NULL); return internal_snprintf(buf, buf_len, "%s", default_module_name); +#elif SANITIZER_OPENBSD + // On OpenBSD we cannot get the full path + struct kinfo_proc kp; + size_t kl; + const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + if (sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1) + return internal_snprintf(buf, + (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len), + "%s", kp.p_comm); + return (uptr)0; #else #if SANITIZER_FREEBSD || SANITIZER_NETBSD #if SANITIZER_FREEBSD @@ -1101,10 +1151,10 @@ // 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; @@ -1687,6 +1737,7 @@ #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; @@ -1720,6 +1771,9 @@ (void)ucontext; return UNKNOWN; // FIXME: Implement. #endif +#else + return UNKNOWN; +#endif } void SignalContext::DumpAllRegisters(void *context) { @@ -1727,7 +1781,11 @@ } static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { -#if SANITIZER_NETBSD +#if SANITIZER_OPENBSD + *pc = 0; + *bp = 0; + *sp = 0; +#elif SANITIZER_NETBSD // This covers all NetBSD architectures ucontext_t *ucontext = (ucontext_t *)context; *pc = _UC_MACHINE_PC(ucontext); Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -15,7 +15,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" @@ -38,10 +38,16 @@ #if SANITIZER_FREEBSD #include #include + #include #define pthread_getattr_np pthread_attr_get_np #endif +#if SANITIZER_OPENBSD +#include +#include +#endif + #if SANITIZER_NETBSD #include #include @@ -127,7 +133,12 @@ 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); @@ -174,7 +185,7 @@ } #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \ - !SANITIZER_NETBSD && !SANITIZER_SOLARIS + !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_SOLARIS static uptr g_tls_size; #ifdef __i386__ @@ -184,7 +195,7 @@ #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 +216,10 @@ #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 +444,9 @@ *addr = (uptr)tcb->tcb_dtv[1]; } } +#elif SANITIZER_OPENBSD + *addr = 0; + *size = 0; #elif SANITIZER_ANDROID *addr = 0; *size = 0; @@ -448,7 +463,7 @@ #if !SANITIZER_GO uptr GetTlsSize() { #if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_SOLARIS uptr addr, size; GetTls(&addr, &size); return size; @@ -485,7 +500,7 @@ #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 @@ -611,7 +626,7 @@ // 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); Index: lib/sanitizer_common/sanitizer_openbsd.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_openbsd.cc @@ -0,0 +1,54 @@ +//===-- sanitizer_openbsd.cc ----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements Solaris-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_OPENBSD + +#include + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_platform_limits_posix.h" +#include "sanitizer_procmaps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace __sanitizer { + +uptr internal_mmap(void *addr, size_t length, int prot, int flags, + int fd, u64 offset) { + return (uptr)mmap(addr, length, prot, flags, fd, offset); +} + +uptr internal_munmap(void *addr, uptr length) { + return munmap(addr, length); +} + +int internal_mprotect(void *addr, uptr length, int prot) { + return mprotect(addr, length, prot); +} + +} // namespace __sanitizer + +#endif // SANITIZER_OPENBSD Index: lib/sanitizer_common/sanitizer_platform.h =================================================================== --- lib/sanitizer_common/sanitizer_platform.h +++ lib/sanitizer_common/sanitizer_platform.h @@ -14,8 +14,8 @@ #define SANITIZER_PLATFORM_H #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) + !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \ + !defined(__Fuchsia__) && !(defined(__sun__) && defined(__srv4__)) # error "This operating system is not supported" #endif @@ -37,6 +37,12 @@ # define SANITIZER_NETBSD 0 #endif +#if defined(__OpenBSD__) +# define SANITIZER_OPENBSD 1 +#else +# define SANITIZER_OPENBSD 0 +#endif + #if defined(__sun__) && defined(__svr4__) # define SANITIZER_SOLARIS 1 #else @@ -100,7 +106,7 @@ #define SANITIZER_POSIX \ (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS) + SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -296,7 +302,8 @@ # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0 #endif -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS # define SANITIZER_MADVISE_DONTNEED MADV_FREE #else # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -34,6 +34,7 @@ #if SI_POSIX # include "sanitizer_platform_limits_netbsd.h" +# include "sanitizer_platform_limits_openbsd.h" # include "sanitizer_platform_limits_posix.h" # include "sanitizer_platform_limits_solaris.h" #endif @@ -62,6 +63,12 @@ # define SI_NETBSD 0 #endif +#if SANITIZER_OPENBSD +# define SI_OPENBSD 1 +#else +# define SI_OPENBSD 0 +#endif + #if SANITIZER_LINUX # define SI_LINUX 1 #else @@ -141,7 +148,8 @@ // FIXME: enable memmem on Windows. #define SANITIZER_INTERCEPT_MEMMEM (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_7) #define SANITIZER_INTERCEPT_MEMCHR SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || SI_NETBSD) +#define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || \ + SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_READ SI_POSIX #define SANITIZER_INTERCEPT_PREAD SI_POSIX @@ -158,7 +166,7 @@ #define SANITIZER_INTERCEPT_WRITEV SI_POSIX #define SANITIZER_INTERCEPT_PREADV \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_PWRITEV SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PREADV64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PWRITEV64 SI_LINUX_NOT_ANDROID @@ -185,23 +193,25 @@ #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETPWENT \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_GETPWENT_R \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SETPWENT \ (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETTIME \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WAIT SI_POSIX #define SANITIZER_INTERCEPT_INET SI_POSIX -#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_GETADDRINFO SI_POSIX #define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX #define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX @@ -217,7 +227,8 @@ (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX -#define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID || SI_NETBSD +#define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID || \ + SI_NETBSD || SI_OPENBSD #define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD #define SANITIZER_INTERCEPT_MODF SI_POSIX #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX @@ -247,22 +258,25 @@ (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_WCSTOMBS SI_POSIX #define SANITIZER_INTERCEPT_WCSNRTOMBS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || \ + SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_WCRTOMB \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || \ + SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_REALPATH SI_POSIX #define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \ (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CONFSTR \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRERROR SI_POSIX #define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX #define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_SCANDIR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX #define SANITIZER_INTERCEPT_POLL SI_POSIX @@ -278,7 +292,7 @@ #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX #define SANITIZER_INTERCEPT_BACKTRACE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS \ @@ -286,15 +300,16 @@ #define SANITIZER_INTERCEPT_STATFS64 \ ((SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_INITGROUPS SI_POSIX -#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON SI_POSIX +#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_ETHER_HOST \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_SHMCTL \ - (SI_NETBSD || SI_SOLARIS || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ + (SI_NETBSD || SI_OPENBSD || SI_SOLARIS || \ + ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ SANITIZER_WORDSIZE == 64)) // NOLINT #define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX @@ -302,8 +317,8 @@ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \ - (SI_POSIX && !SI_NETBSD) -#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \ (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ @@ -312,14 +327,14 @@ (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED \ - (SI_POSIX && !SI_NETBSD) + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED \ - (SI_POSIX && !SI_NETBSD) + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \ (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \ - (SI_LINUX_NOT_ANDROID && !SI_NETBSD) + (SI_LINUX_NOT_ANDROID && !SI_NETBSD && !SI_OPENBSD) #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX #define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX @@ -331,34 +346,37 @@ #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_RAND_R \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || \ + SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_ICONV \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TIMES SI_POSIX // FIXME: getline seems to be available on OSX 10.7 #define SANITIZER_INTERCEPT_GETLINE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT__EXIT \ - (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS) + (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \ (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETRESID SI_LINUX #define SANITIZER_INTERCEPT_GETIFADDRS \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_IF_INDEXTONAME \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID #if SI_LINUX && defined(__arm__) #define SANITIZER_INTERCEPT_AEABI_MEM 1 @@ -366,26 +384,28 @@ #define SANITIZER_INTERCEPT_AEABI_MEM 0 #endif #define SANITIZER_INTERCEPT___BZERO SI_MAC -#define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX) +#define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && \ + !SI_OPENBSD && SI_POSIX) #define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_TSEARCH \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_SOLARIS) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FOPEN SI_POSIX #define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \ - (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_SOLARIS) + (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FFLUSH SI_POSIX #define SANITIZER_INTERCEPT_FCLOSE SI_POSIX #ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE #define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || \ + SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #endif #define SANITIZER_INTERCEPT_GETPASS \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_TIMERFD SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_MLOCKX SI_POSIX @@ -393,10 +413,11 @@ #define SANITIZER_INTERCEPT_SEM \ (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX -#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS) +#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || \ + SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX #define SANITIZER_INTERCEPT_CTERMID \ - (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) + (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS) #define SANITIZER_INTERCEPTOR_HOOKS (SI_LINUX || SI_MAC || SI_WINDOWS) @@ -405,7 +426,7 @@ #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX #define SANITIZER_INTERCEPT_STAT \ - (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS) + (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_LSTAT SI_NETBSD #define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX) #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID @@ -418,31 +439,33 @@ (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD) #define SANITIZER_INTERCEPT_GETLOADAVG \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD) + (!SI_FREEBSD && !SI_MAC && \ + !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA) +#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && \ + !SI_NETBSD && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PVALLOC \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_CFREE \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC) -#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC) +#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_OPENBSD) #define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID -#define SANITIZER_INTERCEPT_ACCT SI_NETBSD +#define SANITIZER_INTERCEPT_ACCT SI_NETBSD || SI_OPENBSD #define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD #define SANITIZER_INTERCEPT_UID_FROM_USER SI_NETBSD #define SANITIZER_INTERCEPT_GROUP_FROM_GID SI_NETBSD #define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD -#define SANITIZER_INTERCEPT_ACCESS SI_NETBSD -#define SANITIZER_INTERCEPT_FACCESSAT SI_NETBSD -#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD -#define SANITIZER_INTERCEPT_STRLCPY SI_NETBSD +#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_GETGROUPLIST (SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_STRLCPY (SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID @@ -457,7 +480,7 @@ #define SANITIZER_INTERCEPT_READLINKAT \ (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_10) -#define SANITIZER_INTERCEPT_DEVNAME SI_NETBSD +#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_DEVNAME_R SI_NETBSD #define SANITIZER_INTERCEPT_FGETLN SI_NETBSD #define SANITIZER_INTERCEPT_STRMODE SI_NETBSD Index: lib/sanitizer_common/sanitizer_platform_limits_openbsd.h =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_platform_limits_openbsd.h @@ -0,0 +1,380 @@ +//===-- sanitizer_platform_limits_openbsd.h -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific OpenBSD data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_OPENBSD_H +#define SANITIZER_PLATFORM_LIMITS_OPENBSD_H + +#if SANITIZER_OPENBSD + +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" + +#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \ + ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift)))) + +#if defined(__x86_64__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312) +#elif defined(__i386__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164) +#endif + +namespace __sanitizer { +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +extern unsigned struct_sigevent_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; + +extern unsigned struct_rlimit_sz; +extern unsigned struct_utimbuf_sz; +extern unsigned struct_timespec_sz; + +struct __sanitizer_iocb { + u64 aio_offset; + uptr aio_buf; + long aio_nbytes; + u32 aio_fildes; + u32 aio_lio_opcode; + long aio_reqprio; +#if SANITIZER_WORDSIZE == 64 + u8 aio_sigevent[32]; +#else + u8 aio_sigevent[20]; +#endif + u32 _state; + u32 _errno; + long _retval; +}; + +struct __sanitizer___sysctl_args { + int *name; + int nlen; + void *oldval; + uptr *oldlenp; + void *newval; + uptr newlen; +}; + +struct __sanitizer_sem_t { + uptr data[5]; +}; + +struct __sanitizer_ipc_perm { + u32 cuid; + u32 cgid; + u32 uid; + u32 gid; + u32 mode; + unsigned short seq; + long key; +}; + +struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; + int shm_segsz; + u32 shm_lpid; + u32 shm_cpid; + short shm_nattch; + u64 shm_atime; + long __shm_atimensec; + u64 shm_dtime; + long __shm_dtimensec; + u64 shm_ctime; + long __shm_ctimensec; + void *_shm_internal; +}; + +extern unsigned struct_msqid_ds_sz; +extern unsigned struct_mq_attr_sz; +extern unsigned struct_timex_sz; +extern unsigned struct_statvfs_sz; + +struct __sanitizer_iovec { + void *iov_base; + uptr iov_len; +}; + +struct __sanitizer_ifaddrs { + struct __sanitizer_ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + struct __sanitizer_sockaddr *ifa_addr; // (struct sockaddr *) + struct __sanitizer_sockaddr *ifa_netmask; // (struct sockaddr *) + struct __sanitizer_sockaddr *ifa_dstaddr; // (struct sockaddr *) + void *ifa_data; +}; + +typedef unsigned __sanitizer_pthread_key_t; + +typedef long long __sanitizer_time_t; +typedef int __sanitizer_suseconds_t; + +struct __sanitizer_timeval { + __sanitizer_time_t tv_sec; + __sanitizer_suseconds_t tv_usec; +}; + +struct __sanitizer_itimerval { + struct __sanitizer_timeval it_interval; + struct __sanitizer_timeval it_value; +}; + +struct __sanitizer_passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; + __sanitizer_time_t pw_change; + char *pw_class; + char *pw_gecos; + char *pw_dir; + char *pw_shell; + __sanitizer_time_t pw_expire; +}; + +struct __sanitizer_group { + char *gr_name; + char *gr_passwd; + int gr_gid; + char **gr_mem; +}; + +struct __sanitizer_ether_addr { + u8 octet[6]; +}; + +struct __sanitizer_tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; + +struct __sanitizer_msghdr { + void *msg_name; + unsigned msg_namelen; + struct __sanitizer_iovec *msg_iov; + unsigned msg_iovlen; + void *msg_control; + unsigned msg_controllen; + int msg_flags; +}; +struct __sanitizer_cmsghdr { + unsigned cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +struct __sanitizer_dirent { + u64 d_fileno; + u64 d_off; + u16 d_reclen; +}; + +typedef u64 __sanitizer_clock_t; +typedef u32 __sanitizer_clockid_t; + +typedef u32 __sanitizer___kernel_uid_t; +typedef u32 __sanitizer___kernel_gid_t; +typedef u64 __sanitizer___kernel_off_t; +typedef struct { + u32 fds_bits[8]; +} __sanitizer___kernel_fd_set; + +typedef struct { + unsigned int pta_magic; + int pta_flags; + void *pta_private; +} __sanitizer_pthread_attr_t; + +typedef unsigned int __sanitizer_sigset_t; + +struct __sanitizer_siginfo { + // The size is determined by looking at sizeof of real siginfo_t on linux. + u64 opaque[128 / sizeof(u64)]; +}; + +using __sanitizer_sighandler_ptr = void (*)(int sig); +using __sanitizer_sigactionhandler_ptr = void (*)(int sig, + __sanitizer_siginfo *siginfo, + void *uctx); + +struct __sanitizer_sigaction { + union { + __sanitizer_sighandler_ptr handler; + __sanitizer_sigactionhandler_ptr sigaction; + }; + __sanitizer_sigset_t sa_mask; + int sa_flags; +}; + +typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; + +struct __sanitizer_kernel_sigaction_t { + union { + void (*handler)(int signo); + void (*sigaction)(int signo, void *info, void *ctx); + }; + unsigned long sa_flags; + void (*sa_restorer)(void); + __sanitizer_kernel_sigset_t sa_mask; +}; + +extern const uptr sig_ign; +extern const uptr sig_dfl; +extern const uptr sig_err; +extern const uptr sa_siginfo; + +extern int af_inet; +extern int af_inet6; +uptr __sanitizer_in_addr_sz(int af); + +struct __sanitizer_dl_phdr_info { +#if SANITIZER_WORDSIZE == 64 + u64 dlpi_addr; +#else + u32 dlpi_addr; +#endif + const char *dlpi_name; + const void *dlpi_phdr; +#if SANITIZER_WORDSIZE == 64 + u32 dlpi_phnum; +#else + u16 dlpi_phnum; +#endif +}; + +extern unsigned struct_ElfW_Phdr_sz; + +struct __sanitizer_addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + unsigned ai_addrlen; + struct __sanitizer_sockaddr *ai_addr; + char *ai_canonname; + struct __sanitizer_addrinfo *ai_next; +}; + +struct __sanitizer_hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +struct __sanitizer_pollfd { + int fd; + short events; + short revents; +}; + +typedef unsigned __sanitizer_nfds_t; + +struct __sanitizer_glob_t { + int gl_pathc; + int gl_matchc; + int gl_offs; + int gl_flags; + char **gl_pathv; + void **gl_statv; + int (*gl_errfunc)(const char *, int); + void (*gl_closedir)(void *dirp); + struct dirent *(*gl_readdir)(void *dirp); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, void * /* struct stat* */); + int (*gl_stat)(const char *, void * /* struct stat* */); +}; + +extern int glob_nomatch; +extern int glob_altdirfunc; + +extern unsigned path_max; + +typedef char __sanitizer_FILE; +#define SANITIZER_HAS_STRUCT_FILE 0 + +extern int shmctl_ipc_stat; + +// This simplifies generic code +#define struct_shminfo_sz -1 +#define struct_shm_info_sz -1 +#define shmctl_shm_stat -1 +#define shmctl_ipc_info -1 +#define shmctl_shm_info -1 + +extern unsigned struct_utmp_sz; +extern unsigned struct_utmpx_sz; + +extern int map_fixed; + +// ioctl arguments +struct __sanitizer_ifconf { + int ifc_len; + union { + void *ifcu_req; + } ifc_ifcu; +}; + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; +} // namespace __sanitizer + +#define CHECK_TYPE_SIZE(TYPE) \ + COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) + +#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ + offsetof(CLASS, MEMBER)) + +// For sigaction, which is a function and struct at the same time, +// and thus requires explicit "struct" in sizeof() expression. +#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((struct CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ + offsetof(struct CLASS, MEMBER)) + +#define SIGACTION_SYMNAME __sigaction14 + +#endif // SANITIZER_OPENBSD + +#endif Index: lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc @@ -0,0 +1,279 @@ +//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific NetBSD data structures. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_OPENBSD +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Include these after system headers to avoid name clashes and ambiguities. +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_openbsd.h" + +namespace __sanitizer { +unsigned struct_utsname_sz = sizeof(struct utsname); +unsigned struct_stat_sz = sizeof(struct stat); +unsigned struct_rusage_sz = sizeof(struct rusage); +unsigned struct_tm_sz = sizeof(struct tm); +unsigned struct_passwd_sz = sizeof(struct passwd); +unsigned struct_group_sz = sizeof(struct group); +unsigned siginfo_t_sz = sizeof(siginfo_t); +unsigned struct_sigaction_sz = sizeof(struct sigaction); +unsigned struct_itimerval_sz = sizeof(struct itimerval); +unsigned pthread_t_sz = sizeof(pthread_t); +unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t); +unsigned pthread_cond_t_sz = sizeof(pthread_cond_t); +unsigned pid_t_sz = sizeof(pid_t); +unsigned timeval_sz = sizeof(timeval); +unsigned uid_t_sz = sizeof(uid_t); +unsigned gid_t_sz = sizeof(gid_t); +unsigned mbstate_t_sz = sizeof(mbstate_t); +unsigned sigset_t_sz = sizeof(sigset_t); +unsigned struct_timezone_sz = sizeof(struct timezone); +unsigned struct_tms_sz = sizeof(struct tms); +unsigned struct_sched_param_sz = sizeof(struct sched_param); +unsigned struct_sockaddr_sz = sizeof(struct sockaddr); +unsigned struct_rlimit_sz = sizeof(struct rlimit); +unsigned struct_timespec_sz = sizeof(struct timespec); +unsigned struct_utimbuf_sz = sizeof(struct utimbuf); +unsigned struct_itimerspec_sz = sizeof(struct itimerspec); +unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); +unsigned struct_statvfs_sz = sizeof(struct statvfs); + +const uptr sig_ign = (uptr)SIG_IGN; +const uptr sig_dfl = (uptr)SIG_DFL; +const uptr sig_err = (uptr)SIG_ERR; +const uptr sa_siginfo = (uptr)SA_SIGINFO; + +int shmctl_ipc_stat = (int)IPC_STAT; + +unsigned struct_utmp_sz = sizeof(struct utmp); + +int map_fixed = MAP_FIXED; + +int af_inet = (int)AF_INET; +int af_inet6 = (int)AF_INET6; + +uptr __sanitizer_in_addr_sz(int af) { + if (af == AF_INET) + return sizeof(struct in_addr); + else if (af == AF_INET6) + return sizeof(struct in6_addr); + else + return 0; +} + +unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + +int glob_nomatch = GLOB_NOMATCH; +int glob_altdirfunc = GLOB_ALTDIRFUNC; + +unsigned path_max = PATH_MAX; + +const int si_SEGV_MAPERR = SEGV_MAPERR; +const int si_SEGV_ACCERR = SEGV_ACCERR; +} // namespace __sanitizer + +using namespace __sanitizer; + +COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t)); + +COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned)); +CHECK_TYPE_SIZE(pthread_key_t); + +CHECK_TYPE_SIZE(dl_phdr_info); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum); + +CHECK_TYPE_SIZE(glob_t); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); +CHECK_SIZE_AND_OFFSET(glob_t, gl_offs); +CHECK_SIZE_AND_OFFSET(glob_t, gl_flags); +CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat); +CHECK_SIZE_AND_OFFSET(glob_t, gl_stat); + +CHECK_TYPE_SIZE(addrinfo); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_family); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_next); + +CHECK_TYPE_SIZE(hostent); +CHECK_SIZE_AND_OFFSET(hostent, h_name); +CHECK_SIZE_AND_OFFSET(hostent, h_aliases); +CHECK_SIZE_AND_OFFSET(hostent, h_addrtype); +CHECK_SIZE_AND_OFFSET(hostent, h_length); +CHECK_SIZE_AND_OFFSET(hostent, h_addr_list); + +CHECK_TYPE_SIZE(iovec); +CHECK_SIZE_AND_OFFSET(iovec, iov_base); +CHECK_SIZE_AND_OFFSET(iovec, iov_len); + +CHECK_TYPE_SIZE(msghdr); +CHECK_SIZE_AND_OFFSET(msghdr, msg_name); +CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iov); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_control); +CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_flags); + +CHECK_TYPE_SIZE(cmsghdr); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type); + +COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); +CHECK_SIZE_AND_OFFSET(dirent, d_fileno); +CHECK_SIZE_AND_OFFSET(dirent, d_off); +CHECK_SIZE_AND_OFFSET(dirent, d_reclen); + +CHECK_TYPE_SIZE(ifconf); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_len); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu); + +CHECK_TYPE_SIZE(pollfd); +CHECK_SIZE_AND_OFFSET(pollfd, fd); +CHECK_SIZE_AND_OFFSET(pollfd, events); +CHECK_SIZE_AND_OFFSET(pollfd, revents); + +CHECK_TYPE_SIZE(nfds_t); + +CHECK_TYPE_SIZE(sigset_t); + +COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction)); +// Can't write checks for sa_handler and sa_sigaction due to them being +// preprocessor macros. +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); + +CHECK_TYPE_SIZE(tm); +CHECK_SIZE_AND_OFFSET(tm, tm_sec); +CHECK_SIZE_AND_OFFSET(tm, tm_min); +CHECK_SIZE_AND_OFFSET(tm, tm_hour); +CHECK_SIZE_AND_OFFSET(tm, tm_mday); +CHECK_SIZE_AND_OFFSET(tm, tm_mon); +CHECK_SIZE_AND_OFFSET(tm, tm_year); +CHECK_SIZE_AND_OFFSET(tm, tm_wday); +CHECK_SIZE_AND_OFFSET(tm, tm_yday); +CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); +CHECK_SIZE_AND_OFFSET(tm, tm_zone); + +CHECK_TYPE_SIZE(ipc_perm); +CHECK_SIZE_AND_OFFSET(ipc_perm, cuid); +CHECK_SIZE_AND_OFFSET(ipc_perm, cgid); +CHECK_SIZE_AND_OFFSET(ipc_perm, uid); +CHECK_SIZE_AND_OFFSET(ipc_perm, gid); +CHECK_SIZE_AND_OFFSET(ipc_perm, mode); +CHECK_SIZE_AND_OFFSET(ipc_perm, seq); +CHECK_SIZE_AND_OFFSET(ipc_perm, key); + +CHECK_TYPE_SIZE(shmid_ds); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_atimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_dtimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_ctimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch); + +CHECK_TYPE_SIZE(clock_t); + +CHECK_TYPE_SIZE(ifaddrs); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask); +// Compare against the union, because we can't reach into the union in a +// compliant way. +#ifdef ifa_dstaddr +#undef ifa_dstaddr +#endif +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data); + +CHECK_TYPE_SIZE(passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_name); +CHECK_SIZE_AND_OFFSET(passwd, pw_passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_uid); +CHECK_SIZE_AND_OFFSET(passwd, pw_gid); +CHECK_SIZE_AND_OFFSET(passwd, pw_dir); +CHECK_SIZE_AND_OFFSET(passwd, pw_shell); + +CHECK_SIZE_AND_OFFSET(passwd, pw_gecos); + +CHECK_TYPE_SIZE(group); +CHECK_SIZE_AND_OFFSET(group, gr_name); +CHECK_SIZE_AND_OFFSET(group, gr_passwd); +CHECK_SIZE_AND_OFFSET(group, gr_gid); +CHECK_SIZE_AND_OFFSET(group, gr_mem); + +#endif // SANITIZER_OPENBSD Index: lib/sanitizer_common/sanitizer_posix.h =================================================================== --- lib/sanitizer_common/sanitizer_posix.h +++ lib/sanitizer_common/sanitizer_posix.h @@ -17,6 +17,7 @@ // This header should NOT include any other headers from sanitizer runtime. #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" #include "sanitizer_platform_limits_solaris.h" Index: lib/sanitizer_common/sanitizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -19,6 +19,7 @@ #include "sanitizer_common.h" #include "sanitizer_flags.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" #include "sanitizer_platform_limits_solaris.h" #include "sanitizer_posix.h" @@ -42,7 +43,7 @@ #if SANITIZER_FREEBSD // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before // that, it was never implemented. So just define it to zero. -#undef MAP_NORESERVE +#undef MAP_NORESERVE #define MAP_NORESERVE 0 #endif @@ -120,6 +121,9 @@ } bool AddressSpaceIsUnlimited() { +#if SANITIZER_OPENBSD +#define RLIMIT_AS RLIMIT_DATA +#endif rlim_t as_size = getlim(RLIMIT_AS); return (as_size == RLIM_INFINITY); } Index: lib/sanitizer_common/sanitizer_procmaps.h =================================================================== --- lib/sanitizer_common/sanitizer_procmaps.h +++ lib/sanitizer_common/sanitizer_procmaps.h @@ -17,7 +17,7 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_MAC || SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" Index: lib/sanitizer_common/sanitizer_procmaps_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_common.cc +++ lib/sanitizer_common/sanitizer_procmaps_common.cc @@ -13,7 +13,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_placement_new.h" Index: lib/sanitizer_common/sanitizer_procmaps_freebsd.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_freebsd.cc +++ lib/sanitizer_common/sanitizer_procmaps_freebsd.cc @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD #include "sanitizer_common.h" #if SANITIZER_FREEBSD #include "sanitizer_freebsd.h" @@ -19,11 +19,19 @@ #include "sanitizer_procmaps.h" #include +#include #include #if SANITIZER_FREEBSD #include #endif +#if SANITIZER_OPENBSD +#include +#define KVME_PROT_READ KVE_PROT_READ +#define KVME_PROT_WRITE KVE_PROT_WRITE +#define KVME_PROT_EXEC KVE_PROT_EXEC +#endif + // Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode. #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) # include @@ -41,6 +49,10 @@ KERN_PROC, KERN_PROC_VMMAP, getpid() +#elif SANITIZER_OPENBSD + CTL_KERN, + KERN_PROC_VMMAP, + getpid() #else CTL_VM, VM_PROC, @@ -55,13 +67,28 @@ CHECK_EQ(Err, 0); CHECK_GT(Size, 0); +#if !SANITIZER_OPENBSD size_t MmapedSize = Size * 4 / 3; void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()"); Size = MmapedSize; Err = sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0); CHECK_EQ(Err, 0); + proc_maps->data = (char *)VmMap; +#else + size_t PageSize = GetPageSize(); + size_t MmapedSize = Size; + MmapedSize = ((MmapedSize - 1) / PageSize + 1) * PageSize; + char *Mem = (char *)MmapOrDie(MmapedSize, "ReadProcMaps()"); + Size = 2 * Size + 10 * sizeof(struct kinfo_vmentry); + if (Size > 0x10000) + Size = 0x10000; + Size = (Size / sizeof(struct kinfo_vmentry)) * sizeof(struct kinfo_vmentry); + Err = sysctl(Mib, ARRAY_SIZE(Mib), Mem, &Size, NULL, 0); + CHECK_EQ(Err, 0); + MmapedSize = Size; + proc_maps->data = Mem; +#endif - proc_maps->data = (char*)VmMap; proc_maps->mmaped_size = MmapedSize; proc_maps->len = Size; } @@ -69,7 +96,7 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; if (data_.current >= last) return false; - struct kinfo_vmentry *VmEntry = (struct kinfo_vmentry *)data_.current; + const struct kinfo_vmentry *VmEntry = (const struct kinfo_vmentry *)data_.current; segment->start = (uptr)VmEntry->kve_start; segment->end = (uptr)VmEntry->kve_end; @@ -83,11 +110,13 @@ if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0) segment->protection |= kProtectionExecute; +#if !SANITIZER_OPENBSD if (segment->filename != NULL && segment->filename_size > 0) { internal_snprintf(segment->filename, Min(segment->filename_size, (uptr)PATH_MAX), "%s", VmEntry->kve_path); } +#endif #if SANITIZER_FREEBSD data_.current += VmEntry->kve_structsize; @@ -100,4 +129,4 @@ } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD Index: lib/sanitizer_common/sanitizer_stacktrace.h =================================================================== --- lib/sanitizer_common/sanitizer_stacktrace.h +++ lib/sanitizer_common/sanitizer_stacktrace.h @@ -23,6 +23,8 @@ # define SANITIZER_CAN_FAST_UNWIND 0 #elif SANITIZER_WINDOWS # define SANITIZER_CAN_FAST_UNWIND 0 +#elif SANITIZER_OPENBSD +# define SANITIZER_CAN_FAST_UNWIND 0 #else # define SANITIZER_CAN_FAST_UNWIND 1 #endif @@ -30,7 +32,7 @@ // Fast unwind is the only option on Mac for now; we will need to // revisit this macro when slow unwind works on Mac, see // https://github.com/google/sanitizers/issues/137 -#if SANITIZER_MAC +#if SANITIZER_MAC || SANITIZER_OPENBSD # define SANITIZER_CAN_SLOW_UNWIND 0 #else # define SANITIZER_CAN_SLOW_UNWIND 1 Index: lib/sanitizer_common/sanitizer_syscall_generic.inc =================================================================== --- lib/sanitizer_common/sanitizer_syscall_generic.inc +++ lib/sanitizer_common/sanitizer_syscall_generic.inc @@ -11,7 +11,8 @@ // //===----------------------------------------------------------------------===// -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS # define SYSCALL(name) SYS_ ## name #else # define SYSCALL(name) __NR_ ## name