168d75effSDimitry Andric //===-- sanitizer_netbsd.cpp ----------------------------------------------===// 268d75effSDimitry Andric // 368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 668d75effSDimitry Andric // 768d75effSDimitry Andric //===----------------------------------------------------------------------===// 868d75effSDimitry Andric // 968d75effSDimitry Andric // This file is shared between Sanitizer run-time libraries and implements 1068d75effSDimitry Andric // NetBSD-specific functions from sanitizer_libc.h. 1168d75effSDimitry Andric //===----------------------------------------------------------------------===// 1268d75effSDimitry Andric 1368d75effSDimitry Andric #include "sanitizer_platform.h" 1468d75effSDimitry Andric 1568d75effSDimitry Andric #if SANITIZER_NETBSD 1668d75effSDimitry Andric 1768d75effSDimitry Andric #include "sanitizer_common.h" 1868d75effSDimitry Andric #include "sanitizer_flags.h" 1968d75effSDimitry Andric #include "sanitizer_getauxval.h" 2068d75effSDimitry Andric #include "sanitizer_internal_defs.h" 2168d75effSDimitry Andric #include "sanitizer_libc.h" 2268d75effSDimitry Andric #include "sanitizer_linux.h" 2368d75effSDimitry Andric #include "sanitizer_mutex.h" 2468d75effSDimitry Andric #include "sanitizer_placement_new.h" 2568d75effSDimitry Andric #include "sanitizer_procmaps.h" 2668d75effSDimitry Andric 2768d75effSDimitry Andric #include <sys/param.h> 2868d75effSDimitry Andric #include <sys/types.h> 2968d75effSDimitry Andric 3068d75effSDimitry Andric #include <sys/exec.h> 3168d75effSDimitry Andric #include <sys/mman.h> 3268d75effSDimitry Andric #include <sys/ptrace.h> 3368d75effSDimitry Andric #include <sys/resource.h> 3468d75effSDimitry Andric #include <sys/stat.h> 3568d75effSDimitry Andric #include <sys/syscall.h> 3668d75effSDimitry Andric #include <sys/sysctl.h> 3768d75effSDimitry Andric #include <sys/time.h> 3868d75effSDimitry Andric 3968d75effSDimitry Andric #include <dlfcn.h> 4068d75effSDimitry Andric #include <errno.h> 4168d75effSDimitry Andric #include <fcntl.h> 4268d75effSDimitry Andric #include <limits.h> 4368d75effSDimitry Andric #include <link.h> 4468d75effSDimitry Andric #include <lwp.h> 4568d75effSDimitry Andric #include <pthread.h> 4668d75effSDimitry Andric #include <sched.h> 4768d75effSDimitry Andric #include <signal.h> 4868d75effSDimitry Andric #include <ucontext.h> 4968d75effSDimitry Andric #include <unistd.h> 5068d75effSDimitry Andric 5168d75effSDimitry Andric extern "C" void *__mmap(void *, size_t, int, int, int, int, 5268d75effSDimitry Andric off_t) SANITIZER_WEAK_ATTRIBUTE; 5368d75effSDimitry Andric extern "C" int __sysctl(const int *, unsigned int, void *, size_t *, 5468d75effSDimitry Andric const void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 5568d75effSDimitry Andric extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE; 5668d75effSDimitry Andric extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE; 5768d75effSDimitry Andric extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 5868d75effSDimitry Andric extern "C" ssize_t _sys_write(int, const void *, 5968d75effSDimitry Andric size_t) SANITIZER_WEAK_ATTRIBUTE; 6068d75effSDimitry Andric extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE; 6168d75effSDimitry Andric extern "C" ssize_t _sys_readlink(const char *, char *, 6268d75effSDimitry Andric size_t) SANITIZER_WEAK_ATTRIBUTE; 6368d75effSDimitry Andric extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE; 6468d75effSDimitry Andric extern "C" int _sys___nanosleep50(const void *, 6568d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 6668d75effSDimitry Andric extern "C" int _sys_execve(const char *, char *const[], 6768d75effSDimitry Andric char *const[]) SANITIZER_WEAK_ATTRIBUTE; 6868d75effSDimitry Andric extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE; 6968d75effSDimitry Andric extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE; 7068d75effSDimitry Andric extern "C" int _sys___sigprocmask14(int, const void *, 7168d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 7268d75effSDimitry Andric extern "C" int _sys___wait450(int wpid, int *, int, 7368d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 7468d75effSDimitry Andric 7568d75effSDimitry Andric namespace __sanitizer { 7668d75effSDimitry Andric 7768d75effSDimitry Andric static void *GetRealLibcAddress(const char *symbol) { 7868d75effSDimitry Andric void *real = dlsym(RTLD_NEXT, symbol); 7968d75effSDimitry Andric if (!real) 8068d75effSDimitry Andric real = dlsym(RTLD_DEFAULT, symbol); 8168d75effSDimitry Andric if (!real) { 8268d75effSDimitry Andric Printf("GetRealLibcAddress failed for symbol=%s", symbol); 8368d75effSDimitry Andric Die(); 8468d75effSDimitry Andric } 8568d75effSDimitry Andric return real; 8668d75effSDimitry Andric } 8768d75effSDimitry Andric 8868d75effSDimitry Andric #define _REAL(func, ...) real##_##func(__VA_ARGS__) 8968d75effSDimitry Andric #define DEFINE__REAL(ret_type, func, ...) \ 9068d75effSDimitry Andric static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ 9168d75effSDimitry Andric if (!real_##func) { \ 9268d75effSDimitry Andric real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ 9368d75effSDimitry Andric } \ 9468d75effSDimitry Andric CHECK(real_##func); 9568d75effSDimitry Andric 9668d75effSDimitry Andric // --------------- sanitizer_libc.h 9768d75effSDimitry Andric uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, 98480093f4SDimitry Andric u64 offset) { 9968d75effSDimitry Andric CHECK(&__mmap); 10068d75effSDimitry Andric return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset); 10168d75effSDimitry Andric } 10268d75effSDimitry Andric 10368d75effSDimitry Andric uptr internal_munmap(void *addr, uptr length) { 10468d75effSDimitry Andric DEFINE__REAL(int, munmap, void *a, uptr b); 10568d75effSDimitry Andric return _REAL(munmap, addr, length); 10668d75effSDimitry Andric } 10768d75effSDimitry Andric 10868d75effSDimitry Andric int internal_mprotect(void *addr, uptr length, int prot) { 10968d75effSDimitry Andric DEFINE__REAL(int, mprotect, void *a, uptr b, int c); 11068d75effSDimitry Andric return _REAL(mprotect, addr, length, prot); 11168d75effSDimitry Andric } 11268d75effSDimitry Andric 11368d75effSDimitry Andric uptr internal_close(fd_t fd) { 11468d75effSDimitry Andric CHECK(&_sys_close); 11568d75effSDimitry Andric return _sys_close(fd); 11668d75effSDimitry Andric } 11768d75effSDimitry Andric 11868d75effSDimitry Andric uptr internal_open(const char *filename, int flags) { 11968d75effSDimitry Andric CHECK(&_sys_open); 12068d75effSDimitry Andric return _sys_open(filename, flags); 12168d75effSDimitry Andric } 12268d75effSDimitry Andric 12368d75effSDimitry Andric uptr internal_open(const char *filename, int flags, u32 mode) { 12468d75effSDimitry Andric CHECK(&_sys_open); 12568d75effSDimitry Andric return _sys_open(filename, flags, mode); 12668d75effSDimitry Andric } 12768d75effSDimitry Andric 12868d75effSDimitry Andric uptr internal_read(fd_t fd, void *buf, uptr count) { 12968d75effSDimitry Andric sptr res; 13068d75effSDimitry Andric CHECK(&_sys_read); 13168d75effSDimitry Andric HANDLE_EINTR(res, (sptr)_sys_read(fd, buf, (size_t)count)); 13268d75effSDimitry Andric return res; 13368d75effSDimitry Andric } 13468d75effSDimitry Andric 13568d75effSDimitry Andric uptr internal_write(fd_t fd, const void *buf, uptr count) { 13668d75effSDimitry Andric sptr res; 13768d75effSDimitry Andric CHECK(&_sys_write); 13868d75effSDimitry Andric HANDLE_EINTR(res, (sptr)_sys_write(fd, buf, count)); 13968d75effSDimitry Andric return res; 14068d75effSDimitry Andric } 14168d75effSDimitry Andric 14268d75effSDimitry Andric uptr internal_ftruncate(fd_t fd, uptr size) { 14368d75effSDimitry Andric sptr res; 14468d75effSDimitry Andric CHECK(&__ftruncate); 14568d75effSDimitry Andric HANDLE_EINTR(res, __ftruncate(fd, 0, (s64)size)); 14668d75effSDimitry Andric return res; 14768d75effSDimitry Andric } 14868d75effSDimitry Andric 14968d75effSDimitry Andric uptr internal_stat(const char *path, void *buf) { 15068d75effSDimitry Andric DEFINE__REAL(int, __stat50, const char *a, void *b); 15168d75effSDimitry Andric return _REAL(__stat50, path, buf); 15268d75effSDimitry Andric } 15368d75effSDimitry Andric 15468d75effSDimitry Andric uptr internal_lstat(const char *path, void *buf) { 15568d75effSDimitry Andric DEFINE__REAL(int, __lstat50, const char *a, void *b); 15668d75effSDimitry Andric return _REAL(__lstat50, path, buf); 15768d75effSDimitry Andric } 15868d75effSDimitry Andric 15968d75effSDimitry Andric uptr internal_fstat(fd_t fd, void *buf) { 16068d75effSDimitry Andric DEFINE__REAL(int, __fstat50, int a, void *b); 16168d75effSDimitry Andric return _REAL(__fstat50, fd, buf); 16268d75effSDimitry Andric } 16368d75effSDimitry Andric 16468d75effSDimitry Andric uptr internal_filesize(fd_t fd) { 16568d75effSDimitry Andric struct stat st; 16668d75effSDimitry Andric if (internal_fstat(fd, &st)) 16768d75effSDimitry Andric return -1; 16868d75effSDimitry Andric return (uptr)st.st_size; 16968d75effSDimitry Andric } 17068d75effSDimitry Andric 17168d75effSDimitry Andric uptr internal_dup(int oldfd) { 17268d75effSDimitry Andric DEFINE__REAL(int, dup, int a); 17368d75effSDimitry Andric return _REAL(dup, oldfd); 17468d75effSDimitry Andric } 17568d75effSDimitry Andric 17668d75effSDimitry Andric uptr internal_dup2(int oldfd, int newfd) { 17768d75effSDimitry Andric DEFINE__REAL(int, dup2, int a, int b); 17868d75effSDimitry Andric return _REAL(dup2, oldfd, newfd); 17968d75effSDimitry Andric } 18068d75effSDimitry Andric 18168d75effSDimitry Andric uptr internal_readlink(const char *path, char *buf, uptr bufsize) { 18268d75effSDimitry Andric CHECK(&_sys_readlink); 18368d75effSDimitry Andric return (uptr)_sys_readlink(path, buf, bufsize); 18468d75effSDimitry Andric } 18568d75effSDimitry Andric 18668d75effSDimitry Andric uptr internal_unlink(const char *path) { 18768d75effSDimitry Andric DEFINE__REAL(int, unlink, const char *a); 18868d75effSDimitry Andric return _REAL(unlink, path); 18968d75effSDimitry Andric } 19068d75effSDimitry Andric 19168d75effSDimitry Andric uptr internal_rename(const char *oldpath, const char *newpath) { 19268d75effSDimitry Andric DEFINE__REAL(int, rename, const char *a, const char *b); 19368d75effSDimitry Andric return _REAL(rename, oldpath, newpath); 19468d75effSDimitry Andric } 19568d75effSDimitry Andric 19668d75effSDimitry Andric uptr internal_sched_yield() { 19768d75effSDimitry Andric CHECK(&_sys_sched_yield); 19868d75effSDimitry Andric return _sys_sched_yield(); 19968d75effSDimitry Andric } 20068d75effSDimitry Andric 20168d75effSDimitry Andric void internal__exit(int exitcode) { 20268d75effSDimitry Andric DEFINE__REAL(void, _exit, int a); 20368d75effSDimitry Andric _REAL(_exit, exitcode); 20468d75effSDimitry Andric Die(); // Unreachable. 20568d75effSDimitry Andric } 20668d75effSDimitry Andric 20768d75effSDimitry Andric unsigned int internal_sleep(unsigned int seconds) { 20868d75effSDimitry Andric struct timespec ts; 20968d75effSDimitry Andric ts.tv_sec = seconds; 21068d75effSDimitry Andric ts.tv_nsec = 0; 21168d75effSDimitry Andric CHECK(&_sys___nanosleep50); 21268d75effSDimitry Andric int res = _sys___nanosleep50(&ts, &ts); 21368d75effSDimitry Andric if (res) 21468d75effSDimitry Andric return ts.tv_sec; 21568d75effSDimitry Andric return 0; 21668d75effSDimitry Andric } 21768d75effSDimitry Andric 21868d75effSDimitry Andric uptr internal_execve(const char *filename, char *const argv[], 21968d75effSDimitry Andric char *const envp[]) { 22068d75effSDimitry Andric CHECK(&_sys_execve); 22168d75effSDimitry Andric return _sys_execve(filename, argv, envp); 22268d75effSDimitry Andric } 22368d75effSDimitry Andric 22468d75effSDimitry Andric tid_t GetTid() { 22568d75effSDimitry Andric DEFINE__REAL(int, _lwp_self); 22668d75effSDimitry Andric return _REAL(_lwp_self); 22768d75effSDimitry Andric } 22868d75effSDimitry Andric 22968d75effSDimitry Andric int TgKill(pid_t pid, tid_t tid, int sig) { 23068d75effSDimitry Andric DEFINE__REAL(int, _lwp_kill, int a, int b); 23168d75effSDimitry Andric (void)pid; 23268d75effSDimitry Andric return _REAL(_lwp_kill, tid, sig); 23368d75effSDimitry Andric } 23468d75effSDimitry Andric 23568d75effSDimitry Andric u64 NanoTime() { 23668d75effSDimitry Andric timeval tv; 23768d75effSDimitry Andric DEFINE__REAL(int, __gettimeofday50, void *a, void *b); 23868d75effSDimitry Andric internal_memset(&tv, 0, sizeof(tv)); 23968d75effSDimitry Andric _REAL(__gettimeofday50, &tv, 0); 24068d75effSDimitry Andric return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000; 24168d75effSDimitry Andric } 24268d75effSDimitry Andric 24368d75effSDimitry Andric uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { 24468d75effSDimitry Andric DEFINE__REAL(int, __clock_gettime50, __sanitizer_clockid_t a, void *b); 24568d75effSDimitry Andric return _REAL(__clock_gettime50, clk_id, tp); 24668d75effSDimitry Andric } 24768d75effSDimitry Andric 24868d75effSDimitry Andric uptr internal_ptrace(int request, int pid, void *addr, int data) { 24968d75effSDimitry Andric DEFINE__REAL(int, ptrace, int a, int b, void *c, int d); 25068d75effSDimitry Andric return _REAL(ptrace, request, pid, addr, data); 25168d75effSDimitry Andric } 25268d75effSDimitry Andric 25368d75effSDimitry Andric uptr internal_waitpid(int pid, int *status, int options) { 25468d75effSDimitry Andric CHECK(&_sys___wait450); 25568d75effSDimitry Andric return _sys___wait450(pid, status, options, 0 /* rusage */); 25668d75effSDimitry Andric } 25768d75effSDimitry Andric 25868d75effSDimitry Andric uptr internal_getpid() { 25968d75effSDimitry Andric DEFINE__REAL(int, getpid); 26068d75effSDimitry Andric return _REAL(getpid); 26168d75effSDimitry Andric } 26268d75effSDimitry Andric 26368d75effSDimitry Andric uptr internal_getppid() { 26468d75effSDimitry Andric DEFINE__REAL(int, getppid); 26568d75effSDimitry Andric return _REAL(getppid); 26668d75effSDimitry Andric } 26768d75effSDimitry Andric 268*5ffd83dbSDimitry Andric int internal_dlinfo(void *handle, int request, void *p) { 269*5ffd83dbSDimitry Andric DEFINE__REAL(int, dlinfo, void *a, int b, void *c); 270*5ffd83dbSDimitry Andric return _REAL(dlinfo, handle, request, p); 271*5ffd83dbSDimitry Andric } 272*5ffd83dbSDimitry Andric 27368d75effSDimitry Andric uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) { 27468d75effSDimitry Andric DEFINE__REAL(int, __getdents30, int a, void *b, size_t c); 27568d75effSDimitry Andric return _REAL(__getdents30, fd, dirp, count); 27668d75effSDimitry Andric } 27768d75effSDimitry Andric 27868d75effSDimitry Andric uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { 27968d75effSDimitry Andric CHECK(&__lseek); 28068d75effSDimitry Andric return __lseek(fd, 0, offset, whence); 28168d75effSDimitry Andric } 28268d75effSDimitry Andric 28368d75effSDimitry Andric uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { 28468d75effSDimitry Andric Printf("internal_prctl not implemented for NetBSD"); 28568d75effSDimitry Andric Die(); 28668d75effSDimitry Andric return 0; 28768d75effSDimitry Andric } 28868d75effSDimitry Andric 28968d75effSDimitry Andric uptr internal_sigaltstack(const void *ss, void *oss) { 29068d75effSDimitry Andric DEFINE__REAL(int, __sigaltstack14, const void *a, void *b); 29168d75effSDimitry Andric return _REAL(__sigaltstack14, ss, oss); 29268d75effSDimitry Andric } 29368d75effSDimitry Andric 29468d75effSDimitry Andric int internal_fork() { 29568d75effSDimitry Andric CHECK(&__fork); 29668d75effSDimitry Andric return __fork(); 29768d75effSDimitry Andric } 29868d75effSDimitry Andric 29968d75effSDimitry Andric int internal_sysctl(const int *name, unsigned int namelen, void *oldp, 30068d75effSDimitry Andric uptr *oldlenp, const void *newp, uptr newlen) { 30168d75effSDimitry Andric CHECK(&__sysctl); 30268d75effSDimitry Andric return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen); 30368d75effSDimitry Andric } 30468d75effSDimitry Andric 30568d75effSDimitry Andric int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, 30668d75effSDimitry Andric const void *newp, uptr newlen) { 30768d75effSDimitry Andric DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c, 30868d75effSDimitry Andric const void *d, size_t e); 30968d75effSDimitry Andric return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp, 31068d75effSDimitry Andric (size_t)newlen); 31168d75effSDimitry Andric } 31268d75effSDimitry Andric 31368d75effSDimitry Andric uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 31468d75effSDimitry Andric __sanitizer_sigset_t *oldset) { 31568d75effSDimitry Andric CHECK(&_sys___sigprocmask14); 31668d75effSDimitry Andric return _sys___sigprocmask14(how, set, oldset); 31768d75effSDimitry Andric } 31868d75effSDimitry Andric 31968d75effSDimitry Andric void internal_sigfillset(__sanitizer_sigset_t *set) { 32068d75effSDimitry Andric DEFINE__REAL(int, __sigfillset14, const void *a); 32168d75effSDimitry Andric (void)_REAL(__sigfillset14, set); 32268d75effSDimitry Andric } 32368d75effSDimitry Andric 32468d75effSDimitry Andric void internal_sigemptyset(__sanitizer_sigset_t *set) { 32568d75effSDimitry Andric DEFINE__REAL(int, __sigemptyset14, const void *a); 32668d75effSDimitry Andric (void)_REAL(__sigemptyset14, set); 32768d75effSDimitry Andric } 32868d75effSDimitry Andric 32968d75effSDimitry Andric void internal_sigdelset(__sanitizer_sigset_t *set, int signo) { 33068d75effSDimitry Andric DEFINE__REAL(int, __sigdelset14, const void *a, int b); 33168d75effSDimitry Andric (void)_REAL(__sigdelset14, set, signo); 33268d75effSDimitry Andric } 33368d75effSDimitry Andric 33468d75effSDimitry Andric uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, 33568d75effSDimitry Andric void *arg) { 33668d75effSDimitry Andric DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e); 33768d75effSDimitry Andric 33868d75effSDimitry Andric return _REAL(clone, fn, child_stack, flags, arg); 33968d75effSDimitry Andric } 34068d75effSDimitry Andric 34168d75effSDimitry Andric } // namespace __sanitizer 34268d75effSDimitry Andric 34368d75effSDimitry Andric #endif 344