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