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 51 extern "C" void *__mmap(void *, size_t, int, int, int, int, 52 off_t) SANITIZER_WEAK_ATTRIBUTE; 53 extern "C" int __sysctl(const int *, unsigned int, void *, size_t *, 54 const void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 55 extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE; 56 extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE; 57 extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE; 58 extern "C" ssize_t _sys_write(int, const void *, 59 size_t) SANITIZER_WEAK_ATTRIBUTE; 60 extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE; 61 extern "C" ssize_t _sys_readlink(const char *, char *, 62 size_t) SANITIZER_WEAK_ATTRIBUTE; 63 extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE; 64 extern "C" int _sys___nanosleep50(const void *, 65 void *) SANITIZER_WEAK_ATTRIBUTE; 66 extern "C" int _sys_execve(const char *, char *const[], 67 char *const[]) SANITIZER_WEAK_ATTRIBUTE; 68 extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE; 69 extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE; 70 extern "C" int _sys___sigprocmask14(int, const void *, 71 void *) SANITIZER_WEAK_ATTRIBUTE; 72 extern "C" int _sys___wait450(int wpid, int *, int, 73 void *) SANITIZER_WEAK_ATTRIBUTE; 74 75 namespace __sanitizer { 76 77 static 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 97 uptr 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 103 uptr internal_munmap(void *addr, uptr length) { 104 DEFINE__REAL(int, munmap, void *a, uptr b); 105 return _REAL(munmap, addr, length); 106 } 107 108 int 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 113 uptr internal_close(fd_t fd) { 114 CHECK(&_sys_close); 115 return _sys_close(fd); 116 } 117 118 uptr internal_open(const char *filename, int flags) { 119 CHECK(&_sys_open); 120 return _sys_open(filename, flags); 121 } 122 123 uptr internal_open(const char *filename, int flags, u32 mode) { 124 CHECK(&_sys_open); 125 return _sys_open(filename, flags, mode); 126 } 127 128 uptr 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 135 uptr 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 142 uptr 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 149 uptr 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 154 uptr 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 159 uptr internal_fstat(fd_t fd, void *buf) { 160 DEFINE__REAL(int, __fstat50, int a, void *b); 161 return _REAL(__fstat50, fd, buf); 162 } 163 164 uptr 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 171 uptr internal_dup(int oldfd) { 172 DEFINE__REAL(int, dup, int a); 173 return _REAL(dup, oldfd); 174 } 175 176 uptr internal_dup2(int oldfd, int newfd) { 177 DEFINE__REAL(int, dup2, int a, int b); 178 return _REAL(dup2, oldfd, newfd); 179 } 180 181 uptr internal_readlink(const char *path, char *buf, uptr bufsize) { 182 CHECK(&_sys_readlink); 183 return (uptr)_sys_readlink(path, buf, bufsize); 184 } 185 186 uptr internal_unlink(const char *path) { 187 DEFINE__REAL(int, unlink, const char *a); 188 return _REAL(unlink, path); 189 } 190 191 uptr 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 196 uptr internal_sched_yield() { 197 CHECK(&_sys_sched_yield); 198 return _sys_sched_yield(); 199 } 200 201 void internal__exit(int exitcode) { 202 DEFINE__REAL(void, _exit, int a); 203 _REAL(_exit, exitcode); 204 Die(); // Unreachable. 205 } 206 207 unsigned 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 218 uptr 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 224 tid_t GetTid() { 225 DEFINE__REAL(int, _lwp_self); 226 return _REAL(_lwp_self); 227 } 228 229 int 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 235 u64 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 243 uptr 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 248 uptr 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 253 uptr internal_waitpid(int pid, int *status, int options) { 254 CHECK(&_sys___wait450); 255 return _sys___wait450(pid, status, options, 0 /* rusage */); 256 } 257 258 uptr internal_getpid() { 259 DEFINE__REAL(int, getpid); 260 return _REAL(getpid); 261 } 262 263 uptr internal_getppid() { 264 DEFINE__REAL(int, getppid); 265 return _REAL(getppid); 266 } 267 268 int internal_dlinfo(void *handle, int request, void *p) { 269 DEFINE__REAL(int, dlinfo, void *a, int b, void *c); 270 return _REAL(dlinfo, handle, request, p); 271 } 272 273 uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) { 274 DEFINE__REAL(int, __getdents30, int a, void *b, size_t c); 275 return _REAL(__getdents30, fd, dirp, count); 276 } 277 278 uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { 279 CHECK(&__lseek); 280 return __lseek(fd, 0, offset, whence); 281 } 282 283 uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { 284 Printf("internal_prctl not implemented for NetBSD"); 285 Die(); 286 return 0; 287 } 288 289 uptr internal_sigaltstack(const void *ss, void *oss) { 290 DEFINE__REAL(int, __sigaltstack14, const void *a, void *b); 291 return _REAL(__sigaltstack14, ss, oss); 292 } 293 294 int internal_fork() { 295 CHECK(&__fork); 296 return __fork(); 297 } 298 299 int internal_sysctl(const int *name, unsigned int namelen, void *oldp, 300 uptr *oldlenp, const void *newp, uptr newlen) { 301 CHECK(&__sysctl); 302 return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen); 303 } 304 305 int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, 306 const void *newp, uptr newlen) { 307 DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c, 308 const void *d, size_t e); 309 return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp, 310 (size_t)newlen); 311 } 312 313 uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 314 __sanitizer_sigset_t *oldset) { 315 CHECK(&_sys___sigprocmask14); 316 return _sys___sigprocmask14(how, set, oldset); 317 } 318 319 void internal_sigfillset(__sanitizer_sigset_t *set) { 320 DEFINE__REAL(int, __sigfillset14, const void *a); 321 (void)_REAL(__sigfillset14, set); 322 } 323 324 void internal_sigemptyset(__sanitizer_sigset_t *set) { 325 DEFINE__REAL(int, __sigemptyset14, const void *a); 326 (void)_REAL(__sigemptyset14, set); 327 } 328 329 void internal_sigdelset(__sanitizer_sigset_t *set, int signo) { 330 DEFINE__REAL(int, __sigdelset14, const void *a, int b); 331 (void)_REAL(__sigdelset14, set, signo); 332 } 333 334 uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, 335 void *arg) { 336 DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e); 337 338 return _REAL(clone, fn, child_stack, flags, arg); 339 } 340 341 } // namespace __sanitizer 342 343 #endif 344