Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/safestack/safestack_platform.h
35260 views
1
//===-- safestack_platform.h ----------------------------------------------===//
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 implements platform specific parts of SafeStack runtime.
10
// Don't use equivalent functionality from sanitizer_common to avoid dragging
11
// a large codebase into security sensitive code.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef SAFESTACK_PLATFORM_H
16
#define SAFESTACK_PLATFORM_H
17
18
#include "safestack_util.h"
19
#include "sanitizer_common/sanitizer_platform.h"
20
21
#include <dlfcn.h>
22
#include <errno.h>
23
#include <stdint.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <sys/mman.h>
27
#include <sys/syscall.h>
28
#include <sys/types.h>
29
#include <unistd.h>
30
31
#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || \
32
SANITIZER_SOLARIS)
33
# error "Support for your platform has not been implemented"
34
#endif
35
36
#if SANITIZER_NETBSD
37
#include <lwp.h>
38
39
extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t);
40
#endif
41
42
#if SANITIZER_FREEBSD
43
#include <sys/thr.h>
44
#endif
45
46
#if SANITIZER_SOLARIS
47
# include <thread.h>
48
#endif
49
50
// Keep in sync with sanitizer_linux.cpp.
51
//
52
// Are we using 32-bit or 64-bit Linux syscalls?
53
// x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32
54
// but it still needs to use 64-bit syscalls.
55
#if SANITIZER_LINUX && \
56
(defined(__x86_64__) || defined(__powerpc64__) || \
57
SANITIZER_WORDSIZE == 64 || (defined(__mips__) && _MIPS_SIM == _ABIN32))
58
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
59
#else
60
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
61
#endif
62
63
namespace safestack {
64
65
#if SANITIZER_NETBSD
66
static void *GetRealLibcAddress(const char *symbol) {
67
void *real = dlsym(RTLD_NEXT, symbol);
68
if (!real)
69
real = dlsym(RTLD_DEFAULT, symbol);
70
if (!real) {
71
fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s",
72
symbol);
73
abort();
74
}
75
return real;
76
}
77
78
#define _REAL(func, ...) real##_##func(__VA_ARGS__)
79
#define DEFINE__REAL(ret_type, func, ...) \
80
static ret_type (*real_##func)(__VA_ARGS__) = NULL; \
81
if (!real_##func) { \
82
real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \
83
} \
84
SFS_CHECK(real_##func);
85
#endif
86
87
#if SANITIZER_SOLARIS
88
# define _REAL(func) _##func
89
# define DEFINE__REAL(ret_type, func, ...) \
90
extern "C" ret_type _REAL(func)(__VA_ARGS__)
91
92
# if !defined(_LP64) && _FILE_OFFSET_BITS == 64
93
# define _REAL64(func) _##func##64
94
# else
95
# define _REAL64(func) _REAL(func)
96
# endif
97
# define DEFINE__REAL64(ret_type, func, ...) \
98
extern "C" ret_type _REAL64(func)(__VA_ARGS__)
99
100
DEFINE__REAL64(void *, mmap, void *a, size_t b, int c, int d, int e, off_t f);
101
DEFINE__REAL(int, munmap, void *a, size_t b);
102
DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
103
#endif
104
105
using ThreadId = uint64_t;
106
107
inline ThreadId GetTid() {
108
#if SANITIZER_NETBSD
109
DEFINE__REAL(int, _lwp_self);
110
return _REAL(_lwp_self);
111
#elif SANITIZER_FREEBSD
112
long Tid;
113
thr_self(&Tid);
114
return Tid;
115
#elif SANITIZER_SOLARIS
116
return thr_self();
117
#else
118
return syscall(SYS_gettid);
119
#endif
120
}
121
122
inline int TgKill(pid_t pid, ThreadId tid, int sig) {
123
#if SANITIZER_NETBSD
124
DEFINE__REAL(int, _lwp_kill, int a, int b);
125
(void)pid;
126
return _REAL(_lwp_kill, tid, sig);
127
#elif SANITIZER_SOLARIS
128
(void)pid;
129
errno = thr_kill(tid, sig);
130
// TgKill is expected to return -1 on error, not an errno.
131
return errno != 0 ? -1 : 0;
132
#elif SANITIZER_FREEBSD
133
return syscall(SYS_thr_kill2, pid, tid, sig);
134
#else
135
// tid is pid_t (int), not ThreadId (uint64_t).
136
return syscall(SYS_tgkill, pid, (pid_t)tid, sig);
137
#endif
138
}
139
140
inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd,
141
off_t offset) {
142
#if SANITIZER_NETBSD
143
return __mmap(addr, length, prot, flags, fd, 0, offset);
144
#elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__))
145
return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
146
#elif SANITIZER_FREEBSD && (defined(__i386__))
147
return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
148
#elif SANITIZER_SOLARIS
149
return _REAL64(mmap)(addr, length, prot, flags, fd, offset);
150
#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
151
return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
152
#else
153
// mmap2 specifies file offset in 4096-byte units.
154
SFS_CHECK(IsAligned(offset, 4096));
155
return (void *)syscall(SYS_mmap2, addr, length, prot, flags, fd,
156
offset / 4096);
157
#endif
158
}
159
160
inline int Munmap(void *addr, size_t length) {
161
#if SANITIZER_NETBSD
162
DEFINE__REAL(int, munmap, void *a, size_t b);
163
return _REAL(munmap, addr, length);
164
#elif SANITIZER_SOLARIS
165
return _REAL(munmap)(addr, length);
166
#else
167
return syscall(SYS_munmap, addr, length);
168
#endif
169
}
170
171
inline int Mprotect(void *addr, size_t length, int prot) {
172
#if SANITIZER_NETBSD
173
DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
174
return _REAL(mprotect, addr, length, prot);
175
#elif SANITIZER_SOLARIS
176
return _REAL(mprotect)(addr, length, prot);
177
#else
178
return syscall(SYS_mprotect, addr, length, prot);
179
#endif
180
}
181
182
} // namespace safestack
183
184
#endif // SAFESTACK_PLATFORM_H
185
186