1 //===-- sanitizer_openbsd.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 various sanitizers' runtime libraries and
10 // implements Solaris-specific functions.
11 //===----------------------------------------------------------------------===//
12 
13 #include "sanitizer_platform.h"
14 #if SANITIZER_OPENBSD
15 
16 #include <stdio.h>
17 
18 #include "sanitizer_common.h"
19 #include "sanitizer_flags.h"
20 #include "sanitizer_internal_defs.h"
21 #include "sanitizer_libc.h"
22 #include "sanitizer_placement_new.h"
23 #include "sanitizer_platform_limits_posix.h"
24 #include "sanitizer_procmaps.h"
25 
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <pthread.h>
30 #include <sched.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/mman.h>
35 #include <sys/shm.h>
36 #include <sys/sysctl.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 
40 extern char **environ;
41 
42 namespace __sanitizer {
43 
internal_mmap(void * addr,size_t length,int prot,int flags,int fd,u64 offset)44 uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd,
45                    u64 offset) {
46   return (uptr)mmap(addr, length, prot, flags, fd, offset);
47 }
48 
internal_munmap(void * addr,uptr length)49 uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); }
50 
internal_mprotect(void * addr,uptr length,int prot)51 int internal_mprotect(void *addr, uptr length, int prot) {
52   return mprotect(addr, length, prot);
53 }
54 
internal_sysctlbyname(const char * sname,void * oldp,uptr * oldlenp,const void * newp,uptr newlen)55 int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
56                           const void *newp, uptr newlen) {
57   Printf("internal_sysctlbyname not implemented for OpenBSD");
58   Die();
59   return 0;
60 }
61 
ReadBinaryName(char * buf,uptr buf_len)62 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
63   // On OpenBSD we cannot get the full path
64   struct kinfo_proc kp;
65   uptr kl;
66   const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()};
67   if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1)
68     return internal_snprintf(buf,
69                              (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len),
70                              "%s", kp.p_comm);
71   return (uptr)0;
72 }
73 
GetArgsAndEnv(char *** argv,char *** envp)74 static void GetArgsAndEnv(char ***argv, char ***envp) {
75   uptr nargv;
76   uptr nenv;
77   int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV};
78   int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV};
79   if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) {
80     Printf("sysctl KERN_PROC_NARGV failed\n");
81     Die();
82   }
83   if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) {
84     Printf("sysctl KERN_PROC_NENV failed\n");
85     Die();
86   }
87   if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) {
88     Printf("sysctl KERN_PROC_ARGV failed\n");
89     Die();
90   }
91   if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) {
92     Printf("sysctl KERN_PROC_ENV failed\n");
93     Die();
94   }
95 }
96 
GetArgv()97 char **GetArgv() {
98   char **argv, **envp;
99   GetArgsAndEnv(&argv, &envp);
100   return argv;
101 }
102 
GetEnviron()103 char **GetEnviron() {
104   char **argv, **envp;
105   GetArgsAndEnv(&argv, &envp);
106   return envp;
107 }
108 
ReExec()109 void ReExec() {
110   UNIMPLEMENTED();
111 }
112 
113 }  // namespace __sanitizer
114 
115 #endif  // SANITIZER_OPENBSD
116