1*68d75effSDimitry Andric //===-- sanitizer_netbsd.cpp ----------------------------------------------===// 2*68d75effSDimitry Andric // 3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*68d75effSDimitry Andric // 7*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 8*68d75effSDimitry Andric // 9*68d75effSDimitry Andric // This file is shared between Sanitizer run-time libraries and implements 10*68d75effSDimitry Andric // NetBSD-specific functions from sanitizer_libc.h. 11*68d75effSDimitry Andric //===----------------------------------------------------------------------===// 12*68d75effSDimitry Andric 13*68d75effSDimitry Andric #include "sanitizer_platform.h" 14*68d75effSDimitry Andric 15*68d75effSDimitry Andric #if SANITIZER_NETBSD 16*68d75effSDimitry Andric 17*68d75effSDimitry Andric #include "sanitizer_common.h" 18*68d75effSDimitry Andric #include "sanitizer_flags.h" 19*68d75effSDimitry Andric #include "sanitizer_getauxval.h" 20*68d75effSDimitry Andric #include "sanitizer_internal_defs.h" 21*68d75effSDimitry Andric #include "sanitizer_libc.h" 22*68d75effSDimitry Andric #include "sanitizer_linux.h" 23*68d75effSDimitry Andric #include "sanitizer_mutex.h" 24*68d75effSDimitry Andric #include "sanitizer_placement_new.h" 25*68d75effSDimitry Andric #include "sanitizer_procmaps.h" 26*68d75effSDimitry Andric 27*68d75effSDimitry Andric #include <sys/param.h> 28*68d75effSDimitry Andric #include <sys/types.h> 29*68d75effSDimitry Andric 30*68d75effSDimitry Andric #include <sys/exec.h> 31*68d75effSDimitry Andric #include <sys/mman.h> 32*68d75effSDimitry Andric #include <sys/ptrace.h> 33*68d75effSDimitry Andric #include <sys/resource.h> 34*68d75effSDimitry Andric #include <sys/stat.h> 35*68d75effSDimitry Andric #include <sys/syscall.h> 36*68d75effSDimitry Andric #include <sys/sysctl.h> 37*68d75effSDimitry Andric #include <sys/time.h> 38*68d75effSDimitry Andric 39*68d75effSDimitry Andric #include <dlfcn.h> 40*68d75effSDimitry Andric #include <errno.h> 41*68d75effSDimitry Andric #include <fcntl.h> 42*68d75effSDimitry Andric #include <limits.h> 43*68d75effSDimitry Andric #include <link.h> 44*68d75effSDimitry Andric #include <lwp.h> 45*68d75effSDimitry Andric #include <pthread.h> 46*68d75effSDimitry Andric #include <sched.h> 47*68d75effSDimitry Andric #include <signal.h> 48*68d75effSDimitry Andric #include <ucontext.h> 49*68d75effSDimitry Andric #include <unistd.h> 50*68d75effSDimitry Andric 51*68d75effSDimitry Andric extern "C" void *__mmap(void *, size_t, int, int, int, int, 52*68d75effSDimitry Andric off_t) SANITIZER_WEAK_ATTRIBUTE; 53*68d75effSDimitry Andric extern "C" int __sysctl(const int *, unsigned int, void *, size_t *, 54*68d75effSDimitry Andric const void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 55*68d75effSDimitry Andric extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE; 56*68d75effSDimitry Andric extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE; 57*68d75effSDimitry Andric extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 58*68d75effSDimitry Andric extern "C" ssize_t _sys_write(int, const void *, 59*68d75effSDimitry Andric size_t) SANITIZER_WEAK_ATTRIBUTE; 60*68d75effSDimitry Andric extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE; 61*68d75effSDimitry Andric extern "C" ssize_t _sys_readlink(const char *, char *, 62*68d75effSDimitry Andric size_t) SANITIZER_WEAK_ATTRIBUTE; 63*68d75effSDimitry Andric extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE; 64*68d75effSDimitry Andric extern "C" int _sys___nanosleep50(const void *, 65*68d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 66*68d75effSDimitry Andric extern "C" int _sys_execve(const char *, char *const[], 67*68d75effSDimitry Andric char *const[]) SANITIZER_WEAK_ATTRIBUTE; 68*68d75effSDimitry Andric extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE; 69*68d75effSDimitry Andric extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE; 70*68d75effSDimitry Andric extern "C" int _sys___sigprocmask14(int, const void *, 71*68d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 72*68d75effSDimitry Andric extern "C" int _sys___wait450(int wpid, int *, int, 73*68d75effSDimitry Andric void *) SANITIZER_WEAK_ATTRIBUTE; 74*68d75effSDimitry Andric 75*68d75effSDimitry Andric namespace __sanitizer { 76*68d75effSDimitry Andric 77*68d75effSDimitry Andric static void *GetRealLibcAddress(const char *symbol) { 78*68d75effSDimitry Andric void *real = dlsym(RTLD_NEXT, symbol); 79*68d75effSDimitry Andric if (!real) 80*68d75effSDimitry Andric real = dlsym(RTLD_DEFAULT, symbol); 81*68d75effSDimitry Andric if (!real) { 82*68d75effSDimitry Andric Printf("GetRealLibcAddress failed for symbol=%s", symbol); 83*68d75effSDimitry Andric Die(); 84*68d75effSDimitry Andric } 85*68d75effSDimitry Andric return real; 86*68d75effSDimitry Andric } 87*68d75effSDimitry Andric 88*68d75effSDimitry Andric #define _REAL(func, ...) real##_##func(__VA_ARGS__) 89*68d75effSDimitry Andric #define DEFINE__REAL(ret_type, func, ...) \ 90*68d75effSDimitry Andric static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ 91*68d75effSDimitry Andric if (!real_##func) { \ 92*68d75effSDimitry Andric real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ 93*68d75effSDimitry Andric } \ 94*68d75effSDimitry Andric CHECK(real_##func); 95*68d75effSDimitry Andric 96*68d75effSDimitry Andric // --------------- sanitizer_libc.h 97*68d75effSDimitry Andric uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, 98*68d75effSDimitry Andric OFF_T offset) { 99*68d75effSDimitry Andric CHECK(&__mmap); 100*68d75effSDimitry Andric return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset); 101*68d75effSDimitry Andric } 102*68d75effSDimitry Andric 103*68d75effSDimitry Andric uptr internal_munmap(void *addr, uptr length) { 104*68d75effSDimitry Andric DEFINE__REAL(int, munmap, void *a, uptr b); 105*68d75effSDimitry Andric return _REAL(munmap, addr, length); 106*68d75effSDimitry Andric } 107*68d75effSDimitry Andric 108*68d75effSDimitry Andric int internal_mprotect(void *addr, uptr length, int prot) { 109*68d75effSDimitry Andric DEFINE__REAL(int, mprotect, void *a, uptr b, int c); 110*68d75effSDimitry Andric return _REAL(mprotect, addr, length, prot); 111*68d75effSDimitry Andric } 112*68d75effSDimitry Andric 113*68d75effSDimitry Andric uptr internal_close(fd_t fd) { 114*68d75effSDimitry Andric CHECK(&_sys_close); 115*68d75effSDimitry Andric return _sys_close(fd); 116*68d75effSDimitry Andric } 117*68d75effSDimitry Andric 118*68d75effSDimitry Andric uptr internal_open(const char *filename, int flags) { 119*68d75effSDimitry Andric CHECK(&_sys_open); 120*68d75effSDimitry Andric return _sys_open(filename, flags); 121*68d75effSDimitry Andric } 122*68d75effSDimitry Andric 123*68d75effSDimitry Andric uptr internal_open(const char *filename, int flags, u32 mode) { 124*68d75effSDimitry Andric CHECK(&_sys_open); 125*68d75effSDimitry Andric return _sys_open(filename, flags, mode); 126*68d75effSDimitry Andric } 127*68d75effSDimitry Andric 128*68d75effSDimitry Andric uptr internal_read(fd_t fd, void *buf, uptr count) { 129*68d75effSDimitry Andric sptr res; 130*68d75effSDimitry Andric CHECK(&_sys_read); 131*68d75effSDimitry Andric HANDLE_EINTR(res, (sptr)_sys_read(fd, buf, (size_t)count)); 132*68d75effSDimitry Andric return res; 133*68d75effSDimitry Andric } 134*68d75effSDimitry Andric 135*68d75effSDimitry Andric uptr internal_write(fd_t fd, const void *buf, uptr count) { 136*68d75effSDimitry Andric sptr res; 137*68d75effSDimitry Andric CHECK(&_sys_write); 138*68d75effSDimitry Andric HANDLE_EINTR(res, (sptr)_sys_write(fd, buf, count)); 139*68d75effSDimitry Andric return res; 140*68d75effSDimitry Andric } 141*68d75effSDimitry Andric 142*68d75effSDimitry Andric uptr internal_ftruncate(fd_t fd, uptr size) { 143*68d75effSDimitry Andric sptr res; 144*68d75effSDimitry Andric CHECK(&__ftruncate); 145*68d75effSDimitry Andric HANDLE_EINTR(res, __ftruncate(fd, 0, (s64)size)); 146*68d75effSDimitry Andric return res; 147*68d75effSDimitry Andric } 148*68d75effSDimitry Andric 149*68d75effSDimitry Andric uptr internal_stat(const char *path, void *buf) { 150*68d75effSDimitry Andric DEFINE__REAL(int, __stat50, const char *a, void *b); 151*68d75effSDimitry Andric return _REAL(__stat50, path, buf); 152*68d75effSDimitry Andric } 153*68d75effSDimitry Andric 154*68d75effSDimitry Andric uptr internal_lstat(const char *path, void *buf) { 155*68d75effSDimitry Andric DEFINE__REAL(int, __lstat50, const char *a, void *b); 156*68d75effSDimitry Andric return _REAL(__lstat50, path, buf); 157*68d75effSDimitry Andric } 158*68d75effSDimitry Andric 159*68d75effSDimitry Andric uptr internal_fstat(fd_t fd, void *buf) { 160*68d75effSDimitry Andric DEFINE__REAL(int, __fstat50, int a, void *b); 161*68d75effSDimitry Andric return _REAL(__fstat50, fd, buf); 162*68d75effSDimitry Andric } 163*68d75effSDimitry Andric 164*68d75effSDimitry Andric uptr internal_filesize(fd_t fd) { 165*68d75effSDimitry Andric struct stat st; 166*68d75effSDimitry Andric if (internal_fstat(fd, &st)) 167*68d75effSDimitry Andric return -1; 168*68d75effSDimitry Andric return (uptr)st.st_size; 169*68d75effSDimitry Andric } 170*68d75effSDimitry Andric 171*68d75effSDimitry Andric uptr internal_dup(int oldfd) { 172*68d75effSDimitry Andric DEFINE__REAL(int, dup, int a); 173*68d75effSDimitry Andric return _REAL(dup, oldfd); 174*68d75effSDimitry Andric } 175*68d75effSDimitry Andric 176*68d75effSDimitry Andric uptr internal_dup2(int oldfd, int newfd) { 177*68d75effSDimitry Andric DEFINE__REAL(int, dup2, int a, int b); 178*68d75effSDimitry Andric return _REAL(dup2, oldfd, newfd); 179*68d75effSDimitry Andric } 180*68d75effSDimitry Andric 181*68d75effSDimitry Andric uptr internal_readlink(const char *path, char *buf, uptr bufsize) { 182*68d75effSDimitry Andric CHECK(&_sys_readlink); 183*68d75effSDimitry Andric return (uptr)_sys_readlink(path, buf, bufsize); 184*68d75effSDimitry Andric } 185*68d75effSDimitry Andric 186*68d75effSDimitry Andric uptr internal_unlink(const char *path) { 187*68d75effSDimitry Andric DEFINE__REAL(int, unlink, const char *a); 188*68d75effSDimitry Andric return _REAL(unlink, path); 189*68d75effSDimitry Andric } 190*68d75effSDimitry Andric 191*68d75effSDimitry Andric uptr internal_rename(const char *oldpath, const char *newpath) { 192*68d75effSDimitry Andric DEFINE__REAL(int, rename, const char *a, const char *b); 193*68d75effSDimitry Andric return _REAL(rename, oldpath, newpath); 194*68d75effSDimitry Andric } 195*68d75effSDimitry Andric 196*68d75effSDimitry Andric uptr internal_sched_yield() { 197*68d75effSDimitry Andric CHECK(&_sys_sched_yield); 198*68d75effSDimitry Andric return _sys_sched_yield(); 199*68d75effSDimitry Andric } 200*68d75effSDimitry Andric 201*68d75effSDimitry Andric void internal__exit(int exitcode) { 202*68d75effSDimitry Andric DEFINE__REAL(void, _exit, int a); 203*68d75effSDimitry Andric _REAL(_exit, exitcode); 204*68d75effSDimitry Andric Die(); // Unreachable. 205*68d75effSDimitry Andric } 206*68d75effSDimitry Andric 207*68d75effSDimitry Andric unsigned int internal_sleep(unsigned int seconds) { 208*68d75effSDimitry Andric struct timespec ts; 209*68d75effSDimitry Andric ts.tv_sec = seconds; 210*68d75effSDimitry Andric ts.tv_nsec = 0; 211*68d75effSDimitry Andric CHECK(&_sys___nanosleep50); 212*68d75effSDimitry Andric int res = _sys___nanosleep50(&ts, &ts); 213*68d75effSDimitry Andric if (res) 214*68d75effSDimitry Andric return ts.tv_sec; 215*68d75effSDimitry Andric return 0; 216*68d75effSDimitry Andric } 217*68d75effSDimitry Andric 218*68d75effSDimitry Andric uptr internal_execve(const char *filename, char *const argv[], 219*68d75effSDimitry Andric char *const envp[]) { 220*68d75effSDimitry Andric CHECK(&_sys_execve); 221*68d75effSDimitry Andric return _sys_execve(filename, argv, envp); 222*68d75effSDimitry Andric } 223*68d75effSDimitry Andric 224*68d75effSDimitry Andric tid_t GetTid() { 225*68d75effSDimitry Andric DEFINE__REAL(int, _lwp_self); 226*68d75effSDimitry Andric return _REAL(_lwp_self); 227*68d75effSDimitry Andric } 228*68d75effSDimitry Andric 229*68d75effSDimitry Andric int TgKill(pid_t pid, tid_t tid, int sig) { 230*68d75effSDimitry Andric DEFINE__REAL(int, _lwp_kill, int a, int b); 231*68d75effSDimitry Andric (void)pid; 232*68d75effSDimitry Andric return _REAL(_lwp_kill, tid, sig); 233*68d75effSDimitry Andric } 234*68d75effSDimitry Andric 235*68d75effSDimitry Andric u64 NanoTime() { 236*68d75effSDimitry Andric timeval tv; 237*68d75effSDimitry Andric DEFINE__REAL(int, __gettimeofday50, void *a, void *b); 238*68d75effSDimitry Andric internal_memset(&tv, 0, sizeof(tv)); 239*68d75effSDimitry Andric _REAL(__gettimeofday50, &tv, 0); 240*68d75effSDimitry Andric return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000; 241*68d75effSDimitry Andric } 242*68d75effSDimitry Andric 243*68d75effSDimitry Andric uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { 244*68d75effSDimitry Andric DEFINE__REAL(int, __clock_gettime50, __sanitizer_clockid_t a, void *b); 245*68d75effSDimitry Andric return _REAL(__clock_gettime50, clk_id, tp); 246*68d75effSDimitry Andric } 247*68d75effSDimitry Andric 248*68d75effSDimitry Andric uptr internal_ptrace(int request, int pid, void *addr, int data) { 249*68d75effSDimitry Andric DEFINE__REAL(int, ptrace, int a, int b, void *c, int d); 250*68d75effSDimitry Andric return _REAL(ptrace, request, pid, addr, data); 251*68d75effSDimitry Andric } 252*68d75effSDimitry Andric 253*68d75effSDimitry Andric uptr internal_waitpid(int pid, int *status, int options) { 254*68d75effSDimitry Andric CHECK(&_sys___wait450); 255*68d75effSDimitry Andric return _sys___wait450(pid, status, options, 0 /* rusage */); 256*68d75effSDimitry Andric } 257*68d75effSDimitry Andric 258*68d75effSDimitry Andric uptr internal_getpid() { 259*68d75effSDimitry Andric DEFINE__REAL(int, getpid); 260*68d75effSDimitry Andric return _REAL(getpid); 261*68d75effSDimitry Andric } 262*68d75effSDimitry Andric 263*68d75effSDimitry Andric uptr internal_getppid() { 264*68d75effSDimitry Andric DEFINE__REAL(int, getppid); 265*68d75effSDimitry Andric return _REAL(getppid); 266*68d75effSDimitry Andric } 267*68d75effSDimitry Andric 268*68d75effSDimitry Andric uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) { 269*68d75effSDimitry Andric DEFINE__REAL(int, __getdents30, int a, void *b, size_t c); 270*68d75effSDimitry Andric return _REAL(__getdents30, fd, dirp, count); 271*68d75effSDimitry Andric } 272*68d75effSDimitry Andric 273*68d75effSDimitry Andric uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { 274*68d75effSDimitry Andric CHECK(&__lseek); 275*68d75effSDimitry Andric return __lseek(fd, 0, offset, whence); 276*68d75effSDimitry Andric } 277*68d75effSDimitry Andric 278*68d75effSDimitry Andric uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { 279*68d75effSDimitry Andric Printf("internal_prctl not implemented for NetBSD"); 280*68d75effSDimitry Andric Die(); 281*68d75effSDimitry Andric return 0; 282*68d75effSDimitry Andric } 283*68d75effSDimitry Andric 284*68d75effSDimitry Andric uptr internal_sigaltstack(const void *ss, void *oss) { 285*68d75effSDimitry Andric DEFINE__REAL(int, __sigaltstack14, const void *a, void *b); 286*68d75effSDimitry Andric return _REAL(__sigaltstack14, ss, oss); 287*68d75effSDimitry Andric } 288*68d75effSDimitry Andric 289*68d75effSDimitry Andric int internal_fork() { 290*68d75effSDimitry Andric CHECK(&__fork); 291*68d75effSDimitry Andric return __fork(); 292*68d75effSDimitry Andric } 293*68d75effSDimitry Andric 294*68d75effSDimitry Andric int internal_sysctl(const int *name, unsigned int namelen, void *oldp, 295*68d75effSDimitry Andric uptr *oldlenp, const void *newp, uptr newlen) { 296*68d75effSDimitry Andric CHECK(&__sysctl); 297*68d75effSDimitry Andric return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen); 298*68d75effSDimitry Andric } 299*68d75effSDimitry Andric 300*68d75effSDimitry Andric int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, 301*68d75effSDimitry Andric const void *newp, uptr newlen) { 302*68d75effSDimitry Andric DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c, 303*68d75effSDimitry Andric const void *d, size_t e); 304*68d75effSDimitry Andric return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp, 305*68d75effSDimitry Andric (size_t)newlen); 306*68d75effSDimitry Andric } 307*68d75effSDimitry Andric 308*68d75effSDimitry Andric uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 309*68d75effSDimitry Andric __sanitizer_sigset_t *oldset) { 310*68d75effSDimitry Andric CHECK(&_sys___sigprocmask14); 311*68d75effSDimitry Andric return _sys___sigprocmask14(how, set, oldset); 312*68d75effSDimitry Andric } 313*68d75effSDimitry Andric 314*68d75effSDimitry Andric void internal_sigfillset(__sanitizer_sigset_t *set) { 315*68d75effSDimitry Andric DEFINE__REAL(int, __sigfillset14, const void *a); 316*68d75effSDimitry Andric (void)_REAL(__sigfillset14, set); 317*68d75effSDimitry Andric } 318*68d75effSDimitry Andric 319*68d75effSDimitry Andric void internal_sigemptyset(__sanitizer_sigset_t *set) { 320*68d75effSDimitry Andric DEFINE__REAL(int, __sigemptyset14, const void *a); 321*68d75effSDimitry Andric (void)_REAL(__sigemptyset14, set); 322*68d75effSDimitry Andric } 323*68d75effSDimitry Andric 324*68d75effSDimitry Andric void internal_sigdelset(__sanitizer_sigset_t *set, int signo) { 325*68d75effSDimitry Andric DEFINE__REAL(int, __sigdelset14, const void *a, int b); 326*68d75effSDimitry Andric (void)_REAL(__sigdelset14, set, signo); 327*68d75effSDimitry Andric } 328*68d75effSDimitry Andric 329*68d75effSDimitry Andric uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, 330*68d75effSDimitry Andric void *arg) { 331*68d75effSDimitry Andric DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e); 332*68d75effSDimitry Andric 333*68d75effSDimitry Andric return _REAL(clone, fn, child_stack, flags, arg); 334*68d75effSDimitry Andric } 335*68d75effSDimitry Andric 336*68d75effSDimitry Andric } // namespace __sanitizer 337*68d75effSDimitry Andric 338*68d75effSDimitry Andric #endif 339