1 //===-- dfsan_custom.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 a part of DataFlowSanitizer.
10 //
11 // This file defines the custom functions listed in done_abilist.txt.
12 //===----------------------------------------------------------------------===//
13
14 #include <arpa/inet.h>
15 #include <assert.h>
16 #include <ctype.h>
17 #include <dlfcn.h>
18 #include <link.h>
19 #include <poll.h>
20 #include <pthread.h>
21 #include <pwd.h>
22 #include <sched.h>
23 #include <signal.h>
24 #include <stdarg.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/epoll.h>
30 #include <sys/resource.h>
31 #include <sys/select.h>
32 #include <sys/socket.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #include <time.h>
37 #include <unistd.h>
38
39 #include "dfsan/dfsan.h"
40 #include "dfsan/dfsan_chained_origin_depot.h"
41 #include "dfsan/dfsan_flags.h"
42 #include "dfsan/dfsan_thread.h"
43 #include "sanitizer_common/sanitizer_common.h"
44 #include "sanitizer_common/sanitizer_internal_defs.h"
45 #include "sanitizer_common/sanitizer_linux.h"
46 #include "sanitizer_common/sanitizer_stackdepot.h"
47
48 using namespace __dfsan;
49
50 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \
51 do { \
52 if (f) \
53 f(__VA_ARGS__); \
54 } while (false)
55 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
56 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);
57
58 // Async-safe, non-reentrant spin lock.
59 class SignalSpinLocker {
60 public:
SignalSpinLocker()61 SignalSpinLocker() {
62 sigset_t all_set;
63 sigfillset(&all_set);
64 pthread_sigmask(SIG_SETMASK, &all_set, &saved_thread_mask_);
65 sigactions_mu.Lock();
66 }
~SignalSpinLocker()67 ~SignalSpinLocker() {
68 sigactions_mu.Unlock();
69 pthread_sigmask(SIG_SETMASK, &saved_thread_mask_, nullptr);
70 }
71
72 private:
73 static StaticSpinMutex sigactions_mu;
74 sigset_t saved_thread_mask_;
75
76 SignalSpinLocker(const SignalSpinLocker &) = delete;
77 SignalSpinLocker &operator=(const SignalSpinLocker &) = delete;
78 };
79
80 StaticSpinMutex SignalSpinLocker::sigactions_mu;
81
82 extern "C" {
83 SANITIZER_INTERFACE_ATTRIBUTE int
__dfsw_stat(const char * path,struct stat * buf,dfsan_label path_label,dfsan_label buf_label,dfsan_label * ret_label)84 __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label,
85 dfsan_label buf_label, dfsan_label *ret_label) {
86 int ret = stat(path, buf);
87 if (ret == 0)
88 dfsan_set_label(0, buf, sizeof(struct stat));
89 *ret_label = 0;
90 return ret;
91 }
92
__dfso_stat(const char * path,struct stat * buf,dfsan_label path_label,dfsan_label buf_label,dfsan_label * ret_label,dfsan_origin path_origin,dfsan_origin buf_origin,dfsan_origin * ret_origin)93 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat(
94 const char *path, struct stat *buf, dfsan_label path_label,
95 dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin,
96 dfsan_origin buf_origin, dfsan_origin *ret_origin) {
97 int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label);
98 return ret;
99 }
100
__dfsw_fstat(int fd,struct stat * buf,dfsan_label fd_label,dfsan_label buf_label,dfsan_label * ret_label)101 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf,
102 dfsan_label fd_label,
103 dfsan_label buf_label,
104 dfsan_label *ret_label) {
105 int ret = fstat(fd, buf);
106 if (ret == 0)
107 dfsan_set_label(0, buf, sizeof(struct stat));
108 *ret_label = 0;
109 return ret;
110 }
111
__dfso_fstat(int fd,struct stat * buf,dfsan_label fd_label,dfsan_label buf_label,dfsan_label * ret_label,dfsan_origin fd_origin,dfsan_origin buf_origin,dfsan_origin * ret_origin)112 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat(
113 int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label,
114 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
115 dfsan_origin *ret_origin) {
116 int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label);
117 return ret;
118 }
119
dfsan_strchr_with_label(const char * s,int c,size_t * bytes_read,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label)120 static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read,
121 dfsan_label s_label, dfsan_label c_label,
122 dfsan_label *ret_label) {
123 char *match_pos = nullptr;
124 for (size_t i = 0;; ++i) {
125 if (s[i] == c || s[i] == 0) {
126 // If s[i] is the \0 at the end of the string, and \0 is not the
127 // character we are searching for, then return null.
128 *bytes_read = i + 1;
129 match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast<char *>(s + i);
130 break;
131 }
132 }
133 if (flags().strict_data_dependencies)
134 *ret_label = s_label;
135 else
136 *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read),
137 dfsan_union(s_label, c_label));
138 return match_pos;
139 }
140
__dfsw_strchr(const char * s,int c,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label)141 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,
142 dfsan_label s_label,
143 dfsan_label c_label,
144 dfsan_label *ret_label) {
145 size_t bytes_read;
146 return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label,
147 ret_label);
148 }
149
__dfso_strchr(const char * s,int c,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin c_origin,dfsan_origin * ret_origin)150 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr(
151 const char *s, int c, dfsan_label s_label, dfsan_label c_label,
152 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
153 dfsan_origin *ret_origin) {
154 size_t bytes_read;
155 char *r =
156 dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label);
157 if (flags().strict_data_dependencies) {
158 *ret_origin = s_origin;
159 } else if (*ret_label) {
160 dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read);
161 *ret_origin = o ? o : (s_label ? s_origin : c_origin);
162 }
163 return r;
164 }
165
__dfsw_strpbrk(const char * s,const char * accept,dfsan_label s_label,dfsan_label accept_label,dfsan_label * ret_label)166 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s,
167 const char *accept,
168 dfsan_label s_label,
169 dfsan_label accept_label,
170 dfsan_label *ret_label) {
171 const char *ret = strpbrk(s, accept);
172 if (flags().strict_data_dependencies) {
173 *ret_label = ret ? s_label : 0;
174 } else {
175 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1;
176 *ret_label =
177 dfsan_union(dfsan_read_label(s, s_bytes_read),
178 dfsan_union(dfsan_read_label(accept, strlen(accept) + 1),
179 dfsan_union(s_label, accept_label)));
180 }
181 return const_cast<char *>(ret);
182 }
183
__dfso_strpbrk(const char * s,const char * accept,dfsan_label s_label,dfsan_label accept_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin accept_origin,dfsan_origin * ret_origin)184 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk(
185 const char *s, const char *accept, dfsan_label s_label,
186 dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin,
187 dfsan_origin accept_origin, dfsan_origin *ret_origin) {
188 const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label);
189 if (flags().strict_data_dependencies) {
190 if (ret)
191 *ret_origin = s_origin;
192 } else {
193 if (*ret_label) {
194 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1;
195 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read);
196 if (o) {
197 *ret_origin = o;
198 } else {
199 o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1);
200 *ret_origin = o ? o : (s_label ? s_origin : accept_origin);
201 }
202 }
203 }
204 return const_cast<char *>(ret);
205 }
206
dfsan_memcmp_bcmp(const void * s1,const void * s2,size_t n,size_t * bytes_read)207 static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n,
208 size_t *bytes_read) {
209 const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
210 for (size_t i = 0; i != n; ++i) {
211 if (cs1[i] != cs2[i]) {
212 *bytes_read = i + 1;
213 return cs1[i] - cs2[i];
214 }
215 }
216 *bytes_read = n;
217 return 0;
218 }
219
dfsan_get_memcmp_label(const void * s1,const void * s2,size_t pos)220 static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2,
221 size_t pos) {
222 if (flags().strict_data_dependencies)
223 return 0;
224 return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos));
225 }
226
dfsan_get_memcmp_origin(const void * s1,const void * s2,size_t pos,dfsan_label * ret_label,dfsan_origin * ret_origin)227 static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos,
228 dfsan_label *ret_label,
229 dfsan_origin *ret_origin) {
230 *ret_label = dfsan_get_memcmp_label(s1, s2, pos);
231 if (*ret_label == 0)
232 return;
233 dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos);
234 *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos);
235 }
236
dfsan_memcmp_bcmp_label(const void * s1,const void * s2,size_t n,dfsan_label * ret_label)237 static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n,
238 dfsan_label *ret_label) {
239 size_t bytes_read;
240 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
241 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
242 return r;
243 }
244
dfsan_memcmp_bcmp_origin(const void * s1,const void * s2,size_t n,dfsan_label * ret_label,dfsan_origin * ret_origin)245 static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n,
246 dfsan_label *ret_label,
247 dfsan_origin *ret_origin) {
248 size_t bytes_read;
249 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
250 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
251 return r;
252 }
253
DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp,uptr caller_pc,const void * s1,const void * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label)254 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc,
255 const void *s1, const void *s2, size_t n,
256 dfsan_label s1_label, dfsan_label s2_label,
257 dfsan_label n_label)
258
259 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc,
260 const void *s1, const void *s2, size_t n,
261 dfsan_label s1_label, dfsan_label s2_label,
262 dfsan_label n_label, dfsan_origin s1_origin,
263 dfsan_origin s2_origin, dfsan_origin n_origin)
264
265 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
266 size_t n, dfsan_label s1_label,
267 dfsan_label s2_label,
268 dfsan_label n_label,
269 dfsan_label *ret_label) {
270 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n,
271 s1_label, s2_label, n_label);
272 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
273 }
274
__dfso_memcmp(const void * s1,const void * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)275 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp(
276 const void *s1, const void *s2, size_t n, dfsan_label s1_label,
277 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
278 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
279 dfsan_origin *ret_origin) {
280 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1,
281 s2, n, s1_label, s2_label, n_label, s1_origin,
282 s2_origin, n_origin);
283 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
284 }
285
__dfsw_bcmp(const void * s1,const void * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label)286 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2,
287 size_t n, dfsan_label s1_label,
288 dfsan_label s2_label,
289 dfsan_label n_label,
290 dfsan_label *ret_label) {
291 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
292 }
293
__dfso_bcmp(const void * s1,const void * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)294 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp(
295 const void *s1, const void *s2, size_t n, dfsan_label s1_label,
296 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
297 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
298 dfsan_origin *ret_origin) {
299 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
300 }
301
302 // When n == 0, compare strings without byte limit.
303 // When n > 0, compare the first (at most) n bytes of s1 and s2.
dfsan_strncmp(const char * s1,const char * s2,size_t n,size_t * bytes_read)304 static int dfsan_strncmp(const char *s1, const char *s2, size_t n,
305 size_t *bytes_read) {
306 for (size_t i = 0;; ++i) {
307 if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) {
308 *bytes_read = i + 1;
309 return s1[i] - s2[i];
310 }
311 }
312 }
313
DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp,uptr caller_pc,const char * s1,const char * s2,dfsan_label s1_label,dfsan_label s2_label)314 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc,
315 const char *s1, const char *s2,
316 dfsan_label s1_label, dfsan_label s2_label)
317
318 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc,
319 const char *s1, const char *s2,
320 dfsan_label s1_label, dfsan_label s2_label,
321 dfsan_origin s1_origin, dfsan_origin s2_origin)
322
323 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,
324 dfsan_label s1_label,
325 dfsan_label s2_label,
326 dfsan_label *ret_label) {
327 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2,
328 s1_label, s2_label);
329 size_t bytes_read;
330 int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
331 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
332 return r;
333 }
334
__dfso_strcmp(const char * s1,const char * s2,dfsan_label s1_label,dfsan_label s2_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin * ret_origin)335 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp(
336 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
337 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
338 dfsan_origin *ret_origin) {
339 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1,
340 s2, s1_label, s2_label, s1_origin, s2_origin);
341 size_t bytes_read;
342 int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
343 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
344 return r;
345 }
346
347 // When n == 0, compare strings without byte limit.
348 // When n > 0, compare the first (at most) n bytes of s1 and s2.
dfsan_strncasecmp(const char * s1,const char * s2,size_t n,size_t * bytes_read)349 static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n,
350 size_t *bytes_read) {
351 for (size_t i = 0;; ++i) {
352 char s1_lower = tolower(s1[i]);
353 char s2_lower = tolower(s2[i]);
354
355 if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 ||
356 (n > 0 && i == n - 1)) {
357 *bytes_read = i + 1;
358 return s1_lower - s2_lower;
359 }
360 }
361 }
362
__dfsw_strcasecmp(const char * s1,const char * s2,dfsan_label s1_label,dfsan_label s2_label,dfsan_label * ret_label)363 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1,
364 const char *s2,
365 dfsan_label s1_label,
366 dfsan_label s2_label,
367 dfsan_label *ret_label) {
368 size_t bytes_read;
369 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
370 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
371 return r;
372 }
373
__dfso_strcasecmp(const char * s1,const char * s2,dfsan_label s1_label,dfsan_label s2_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin * ret_origin)374 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp(
375 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
376 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
377 dfsan_origin *ret_origin) {
378 size_t bytes_read;
379 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
380 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
381 return r;
382 }
383
DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp,uptr caller_pc,const char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label)384 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,
385 const char *s1, const char *s2, size_t n,
386 dfsan_label s1_label, dfsan_label s2_label,
387 dfsan_label n_label)
388
389 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc,
390 const char *s1, const char *s2, size_t n,
391 dfsan_label s1_label, dfsan_label s2_label,
392 dfsan_label n_label, dfsan_origin s1_origin,
393 dfsan_origin s2_origin, dfsan_origin n_origin)
394
395 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
396 size_t n, dfsan_label s1_label,
397 dfsan_label s2_label,
398 dfsan_label n_label,
399 dfsan_label *ret_label) {
400 if (n == 0) {
401 *ret_label = 0;
402 return 0;
403 }
404
405 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2,
406 n, s1_label, s2_label, n_label);
407
408 size_t bytes_read;
409 int r = dfsan_strncmp(s1, s2, n, &bytes_read);
410 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
411 return r;
412 }
413
__dfso_strncmp(const char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)414 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp(
415 const char *s1, const char *s2, size_t n, dfsan_label s1_label,
416 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
417 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
418 dfsan_origin *ret_origin) {
419 if (n == 0) {
420 *ret_label = 0;
421 return 0;
422 }
423
424 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(),
425 s1, s2, n, s1_label, s2_label, n_label, s1_origin,
426 s2_origin, n_origin);
427
428 size_t bytes_read;
429 int r = dfsan_strncmp(s1, s2, n, &bytes_read);
430 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
431 return r;
432 }
433
__dfsw_strncasecmp(const char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label)434 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp(
435 const char *s1, const char *s2, size_t n, dfsan_label s1_label,
436 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) {
437 if (n == 0) {
438 *ret_label = 0;
439 return 0;
440 }
441
442 size_t bytes_read;
443 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
444 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
445 return r;
446 }
447
__dfso_strncasecmp(const char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)448 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp(
449 const char *s1, const char *s2, size_t n, dfsan_label s1_label,
450 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
451 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
452 dfsan_origin *ret_origin) {
453 if (n == 0) {
454 *ret_label = 0;
455 return 0;
456 }
457
458 size_t bytes_read;
459 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
460 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
461 return r;
462 }
463
464
465 SANITIZER_INTERFACE_ATTRIBUTE size_t
__dfsw_strlen(const char * s,dfsan_label s_label,dfsan_label * ret_label)466 __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
467 size_t ret = strlen(s);
468 if (flags().strict_data_dependencies) {
469 *ret_label = 0;
470 } else {
471 *ret_label = dfsan_read_label(s, ret + 1);
472 }
473 return ret;
474 }
475
__dfso_strlen(const char * s,dfsan_label s_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin * ret_origin)476 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s,
477 dfsan_label s_label,
478 dfsan_label *ret_label,
479 dfsan_origin s_origin,
480 dfsan_origin *ret_origin) {
481 size_t ret = __dfsw_strlen(s, s_label, ret_label);
482 if (!flags().strict_data_dependencies)
483 *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1);
484 return ret;
485 }
486
dfsan_memmove(void * dest,const void * src,size_t n)487 static void *dfsan_memmove(void *dest, const void *src, size_t n) {
488 dfsan_label *sdest = shadow_for(dest);
489 const dfsan_label *ssrc = shadow_for(src);
490 internal_memmove((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label));
491 return internal_memmove(dest, src, n);
492 }
493
dfsan_memmove_with_origin(void * dest,const void * src,size_t n)494 static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) {
495 dfsan_mem_origin_transfer(dest, src, n);
496 return dfsan_memmove(dest, src, n);
497 }
498
dfsan_memcpy(void * dest,const void * src,size_t n)499 static void *dfsan_memcpy(void *dest, const void *src, size_t n) {
500 dfsan_label *sdest = shadow_for(dest);
501 const dfsan_label *ssrc = shadow_for(src);
502 internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label));
503 return internal_memcpy(dest, src, n);
504 }
505
dfsan_memcpy_with_origin(void * dest,const void * src,size_t n)506 static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) {
507 dfsan_mem_origin_transfer(dest, src, n);
508 return dfsan_memcpy(dest, src, n);
509 }
510
dfsan_memset(void * s,int c,dfsan_label c_label,size_t n)511 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {
512 internal_memset(s, c, n);
513 dfsan_set_label(c_label, s, n);
514 }
515
dfsan_memset_with_origin(void * s,int c,dfsan_label c_label,dfsan_origin c_origin,size_t n)516 static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label,
517 dfsan_origin c_origin, size_t n) {
518 internal_memset(s, c, n);
519 dfsan_set_label_origin(c_label, c_origin, s, n);
520 }
521
522 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_memcpy(void * dest,const void * src,size_t n,dfsan_label dest_label,dfsan_label src_label,dfsan_label n_label,dfsan_label * ret_label)523 void *__dfsw_memcpy(void *dest, const void *src, size_t n,
524 dfsan_label dest_label, dfsan_label src_label,
525 dfsan_label n_label, dfsan_label *ret_label) {
526 *ret_label = dest_label;
527 return dfsan_memcpy(dest, src, n);
528 }
529
530 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_memcpy(void * dest,const void * src,size_t n,dfsan_label dest_label,dfsan_label src_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin dest_origin,dfsan_origin src_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)531 void *__dfso_memcpy(void *dest, const void *src, size_t n,
532 dfsan_label dest_label, dfsan_label src_label,
533 dfsan_label n_label, dfsan_label *ret_label,
534 dfsan_origin dest_origin, dfsan_origin src_origin,
535 dfsan_origin n_origin, dfsan_origin *ret_origin) {
536 *ret_label = dest_label;
537 *ret_origin = dest_origin;
538 return dfsan_memcpy_with_origin(dest, src, n);
539 }
540
541 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_memmove(void * dest,const void * src,size_t n,dfsan_label dest_label,dfsan_label src_label,dfsan_label n_label,dfsan_label * ret_label)542 void *__dfsw_memmove(void *dest, const void *src, size_t n,
543 dfsan_label dest_label, dfsan_label src_label,
544 dfsan_label n_label, dfsan_label *ret_label) {
545 *ret_label = dest_label;
546 return dfsan_memmove(dest, src, n);
547 }
548
549 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_memmove(void * dest,const void * src,size_t n,dfsan_label dest_label,dfsan_label src_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin dest_origin,dfsan_origin src_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)550 void *__dfso_memmove(void *dest, const void *src, size_t n,
551 dfsan_label dest_label, dfsan_label src_label,
552 dfsan_label n_label, dfsan_label *ret_label,
553 dfsan_origin dest_origin, dfsan_origin src_origin,
554 dfsan_origin n_origin, dfsan_origin *ret_origin) {
555 *ret_label = dest_label;
556 *ret_origin = dest_origin;
557 return dfsan_memmove_with_origin(dest, src, n);
558 }
559
560 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_memset(void * s,int c,size_t n,dfsan_label s_label,dfsan_label c_label,dfsan_label n_label,dfsan_label * ret_label)561 void *__dfsw_memset(void *s, int c, size_t n,
562 dfsan_label s_label, dfsan_label c_label,
563 dfsan_label n_label, dfsan_label *ret_label) {
564 dfsan_memset(s, c, c_label, n);
565 *ret_label = s_label;
566 return s;
567 }
568
569 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_memset(void * s,int c,size_t n,dfsan_label s_label,dfsan_label c_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin c_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)570 void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label,
571 dfsan_label c_label, dfsan_label n_label,
572 dfsan_label *ret_label, dfsan_origin s_origin,
573 dfsan_origin c_origin, dfsan_origin n_origin,
574 dfsan_origin *ret_origin) {
575 dfsan_memset_with_origin(s, c, c_label, c_origin, n);
576 *ret_label = s_label;
577 *ret_origin = s_origin;
578 return s;
579 }
580
__dfsw_strcat(char * dest,const char * src,dfsan_label dest_label,dfsan_label src_label,dfsan_label * ret_label)581 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
582 dfsan_label dest_label,
583 dfsan_label src_label,
584 dfsan_label *ret_label) {
585 size_t dest_len = strlen(dest);
586 char *ret = strcat(dest, src); // NOLINT
587 dfsan_label *sdest = shadow_for(dest + dest_len);
588 const dfsan_label *ssrc = shadow_for(src);
589 internal_memcpy((void *)sdest, (const void *)ssrc,
590 strlen(src) * sizeof(dfsan_label));
591 *ret_label = dest_label;
592 return ret;
593 }
594
__dfso_strcat(char * dest,const char * src,dfsan_label dest_label,dfsan_label src_label,dfsan_label * ret_label,dfsan_origin dest_origin,dfsan_origin src_origin,dfsan_origin * ret_origin)595 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
596 char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label,
597 dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin,
598 dfsan_origin *ret_origin) {
599 size_t dest_len = strlen(dest);
600 char *ret = strcat(dest, src); // NOLINT
601 dfsan_label *sdest = shadow_for(dest + dest_len);
602 const dfsan_label *ssrc = shadow_for(src);
603 size_t src_len = strlen(src);
604 dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
605 internal_memcpy((void *)sdest, (const void *)ssrc,
606 src_len * sizeof(dfsan_label));
607 *ret_label = dest_label;
608 *ret_origin = dest_origin;
609 return ret;
610 }
611
612 SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strdup(const char * s,dfsan_label s_label,dfsan_label * ret_label)613 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
614 size_t len = strlen(s);
615 void *p = malloc(len+1);
616 dfsan_memcpy(p, s, len+1);
617 *ret_label = 0;
618 return static_cast<char *>(p);
619 }
620
__dfso_strdup(const char * s,dfsan_label s_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin * ret_origin)621 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s,
622 dfsan_label s_label,
623 dfsan_label *ret_label,
624 dfsan_origin s_origin,
625 dfsan_origin *ret_origin) {
626 size_t len = strlen(s);
627 void *p = malloc(len + 1);
628 dfsan_memcpy_with_origin(p, s, len + 1);
629 *ret_label = 0;
630 return static_cast<char *>(p);
631 }
632
633 SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strncpy(char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label)634 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
635 dfsan_label s2_label, dfsan_label n_label,
636 dfsan_label *ret_label) {
637 size_t len = strlen(s2);
638 if (len < n) {
639 dfsan_memcpy(s1, s2, len+1);
640 dfsan_memset(s1+len+1, 0, 0, n-len-1);
641 } else {
642 dfsan_memcpy(s1, s2, n);
643 }
644
645 *ret_label = s1_label;
646 return s1;
647 }
648
__dfso_strncpy(char * s1,const char * s2,size_t n,dfsan_label s1_label,dfsan_label s2_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s1_origin,dfsan_origin s2_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)649 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy(
650 char *s1, const char *s2, size_t n, dfsan_label s1_label,
651 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
652 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
653 dfsan_origin *ret_origin) {
654 size_t len = strlen(s2);
655 if (len < n) {
656 dfsan_memcpy_with_origin(s1, s2, len + 1);
657 dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1);
658 } else {
659 dfsan_memcpy_with_origin(s1, s2, n);
660 }
661
662 *ret_label = s1_label;
663 *ret_origin = s1_origin;
664 return s1;
665 }
666
667 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfsw_pread(int fd,void * buf,size_t count,off_t offset,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label offset_label,dfsan_label * ret_label)668 __dfsw_pread(int fd, void *buf, size_t count, off_t offset,
669 dfsan_label fd_label, dfsan_label buf_label,
670 dfsan_label count_label, dfsan_label offset_label,
671 dfsan_label *ret_label) {
672 ssize_t ret = pread(fd, buf, count, offset);
673 if (ret > 0)
674 dfsan_set_label(0, buf, ret);
675 *ret_label = 0;
676 return ret;
677 }
678
__dfso_pread(int fd,void * buf,size_t count,off_t offset,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label offset_label,dfsan_label * ret_label,dfsan_origin fd_origin,dfsan_origin buf_origin,dfsan_origin count_origin,dfsan_label offset_origin,dfsan_origin * ret_origin)679 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread(
680 int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label,
681 dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label,
682 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
683 dfsan_origin count_origin, dfsan_label offset_origin,
684 dfsan_origin *ret_origin) {
685 return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label,
686 offset_label, ret_label);
687 }
688
689 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfsw_read(int fd,void * buf,size_t count,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label * ret_label)690 __dfsw_read(int fd, void *buf, size_t count,
691 dfsan_label fd_label, dfsan_label buf_label,
692 dfsan_label count_label,
693 dfsan_label *ret_label) {
694 ssize_t ret = read(fd, buf, count);
695 if (ret > 0)
696 dfsan_set_label(0, buf, ret);
697 *ret_label = 0;
698 return ret;
699 }
700
__dfso_read(int fd,void * buf,size_t count,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label * ret_label,dfsan_origin fd_origin,dfsan_origin buf_origin,dfsan_origin count_origin,dfsan_origin * ret_origin)701 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read(
702 int fd, void *buf, size_t count, dfsan_label fd_label,
703 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
704 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
705 dfsan_origin *ret_origin) {
706 return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label,
707 ret_label);
708 }
709
__dfsw_clock_gettime(clockid_t clk_id,struct timespec * tp,dfsan_label clk_id_label,dfsan_label tp_label,dfsan_label * ret_label)710 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
711 struct timespec *tp,
712 dfsan_label clk_id_label,
713 dfsan_label tp_label,
714 dfsan_label *ret_label) {
715 int ret = clock_gettime(clk_id, tp);
716 if (ret == 0)
717 dfsan_set_label(0, tp, sizeof(struct timespec));
718 *ret_label = 0;
719 return ret;
720 }
721
__dfso_clock_gettime(clockid_t clk_id,struct timespec * tp,dfsan_label clk_id_label,dfsan_label tp_label,dfsan_label * ret_label,dfsan_origin clk_id_origin,dfsan_origin tp_origin,dfsan_origin * ret_origin)722 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime(
723 clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label,
724 dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin,
725 dfsan_origin tp_origin, dfsan_origin *ret_origin) {
726 return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label);
727 }
728
dfsan_set_zero_label(const void * ptr,uptr size)729 static void dfsan_set_zero_label(const void *ptr, uptr size) {
730 dfsan_set_label(0, const_cast<void *>(ptr), size);
731 }
732
733 // dlopen() ultimately calls mmap() down inside the loader, which generally
734 // doesn't participate in dynamic symbol resolution. Therefore we won't
735 // intercept its calls to mmap, and we have to hook it here.
736 SANITIZER_INTERFACE_ATTRIBUTE void *
__dfsw_dlopen(const char * filename,int flag,dfsan_label filename_label,dfsan_label flag_label,dfsan_label * ret_label)737 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
738 dfsan_label flag_label, dfsan_label *ret_label) {
739 void *handle = dlopen(filename, flag);
740 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
741 if (map)
742 ForEachMappedRegion(map, dfsan_set_zero_label);
743 *ret_label = 0;
744 return handle;
745 }
746
__dfso_dlopen(const char * filename,int flag,dfsan_label filename_label,dfsan_label flag_label,dfsan_label * ret_label,dfsan_origin filename_origin,dfsan_origin flag_origin,dfsan_origin * ret_origin)747 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen(
748 const char *filename, int flag, dfsan_label filename_label,
749 dfsan_label flag_label, dfsan_label *ret_label,
750 dfsan_origin filename_origin, dfsan_origin flag_origin,
751 dfsan_origin *ret_origin) {
752 return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label);
753 }
754
DFsanThreadStartFunc(void * arg)755 static void *DFsanThreadStartFunc(void *arg) {
756 DFsanThread *t = (DFsanThread *)arg;
757 SetCurrentThread(t);
758 return t->ThreadStart();
759 }
760
dfsan_pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * start_routine_trampoline,void * start_routine,void * arg,dfsan_label * ret_label,bool track_origins=false)761 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
762 void *start_routine_trampoline,
763 void *start_routine, void *arg,
764 dfsan_label *ret_label,
765 bool track_origins = false) {
766 pthread_attr_t myattr;
767 if (!attr) {
768 pthread_attr_init(&myattr);
769 attr = &myattr;
770 }
771
772 // Ensure that the thread stack is large enough to hold all TLS data.
773 AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr)));
774
775 DFsanThread *t =
776 DFsanThread::Create(start_routine_trampoline,
777 (thread_callback_t)start_routine, arg, track_origins);
778 int res = pthread_create(thread, attr, DFsanThreadStartFunc, t);
779
780 if (attr == &myattr)
781 pthread_attr_destroy(&myattr);
782 *ret_label = 0;
783 return res;
784 }
785
__dfsw_pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine_trampoline)(void *,void *,dfsan_label,dfsan_label *),void * start_routine,void * arg,dfsan_label thread_label,dfsan_label attr_label,dfsan_label start_routine_label,dfsan_label arg_label,dfsan_label * ret_label)786 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create(
787 pthread_t *thread, const pthread_attr_t *attr,
788 void *(*start_routine_trampoline)(void *, void *, dfsan_label,
789 dfsan_label *),
790 void *start_routine, void *arg, dfsan_label thread_label,
791 dfsan_label attr_label, dfsan_label start_routine_label,
792 dfsan_label arg_label, dfsan_label *ret_label) {
793 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline,
794 start_routine, arg, ret_label);
795 }
796
__dfso_pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * (* start_routine_trampoline)(void *,void *,dfsan_label,dfsan_label *,dfsan_origin,dfsan_origin *),void * start_routine,void * arg,dfsan_label thread_label,dfsan_label attr_label,dfsan_label start_routine_label,dfsan_label arg_label,dfsan_label * ret_label,dfsan_origin thread_origin,dfsan_origin attr_origin,dfsan_origin start_routine_origin,dfsan_origin arg_origin,dfsan_origin * ret_origin)797 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create(
798 pthread_t *thread, const pthread_attr_t *attr,
799 void *(*start_routine_trampoline)(void *, void *, dfsan_label,
800 dfsan_label *, dfsan_origin,
801 dfsan_origin *),
802 void *start_routine, void *arg, dfsan_label thread_label,
803 dfsan_label attr_label, dfsan_label start_routine_label,
804 dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin,
805 dfsan_origin attr_origin, dfsan_origin start_routine_origin,
806 dfsan_origin arg_origin, dfsan_origin *ret_origin) {
807 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline,
808 start_routine, arg, ret_label, true);
809 }
810
__dfsw_pthread_join(pthread_t thread,void ** retval,dfsan_label thread_label,dfsan_label retval_label,dfsan_label * ret_label)811 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread,
812 void **retval,
813 dfsan_label thread_label,
814 dfsan_label retval_label,
815 dfsan_label *ret_label) {
816 int ret = pthread_join(thread, retval);
817 if (ret == 0 && retval)
818 dfsan_set_label(0, retval, sizeof(*retval));
819 *ret_label = 0;
820 return ret;
821 }
822
__dfso_pthread_join(pthread_t thread,void ** retval,dfsan_label thread_label,dfsan_label retval_label,dfsan_label * ret_label,dfsan_origin thread_origin,dfsan_origin retval_origin,dfsan_origin * ret_origin)823 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join(
824 pthread_t thread, void **retval, dfsan_label thread_label,
825 dfsan_label retval_label, dfsan_label *ret_label,
826 dfsan_origin thread_origin, dfsan_origin retval_origin,
827 dfsan_origin *ret_origin) {
828 return __dfsw_pthread_join(thread, retval, thread_label, retval_label,
829 ret_label);
830 }
831
832 struct dl_iterate_phdr_info {
833 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
834 size_t size, void *data, dfsan_label info_label,
835 dfsan_label size_label, dfsan_label data_label,
836 dfsan_label *ret_label);
837 void *callback;
838 void *data;
839 };
840
841 struct dl_iterate_phdr_origin_info {
842 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
843 size_t size, void *data, dfsan_label info_label,
844 dfsan_label size_label, dfsan_label data_label,
845 dfsan_label *ret_label, dfsan_origin info_origin,
846 dfsan_origin size_origin, dfsan_origin data_origin,
847 dfsan_origin *ret_origin);
848 void *callback;
849 void *data;
850 };
851
dl_iterate_phdr_cb(struct dl_phdr_info * info,size_t size,void * data)852 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
853 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;
854 dfsan_set_label(0, *info);
855 dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
856 strlen(info->dlpi_name) + 1);
857 dfsan_set_label(
858 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
859 sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
860 dfsan_label ret_label;
861 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,
862 0, &ret_label);
863 }
864
dl_iterate_phdr_origin_cb(struct dl_phdr_info * info,size_t size,void * data)865 int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size,
866 void *data) {
867 dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data;
868 dfsan_set_label(0, *info);
869 dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
870 strlen(info->dlpi_name) + 1);
871 dfsan_set_label(
872 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
873 sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
874 dfsan_label ret_label;
875 dfsan_origin ret_origin;
876 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,
877 0, &ret_label, 0, 0, 0, &ret_origin);
878 }
879
__dfsw_dl_iterate_phdr(int (* callback_trampoline)(void * callback,struct dl_phdr_info * info,size_t size,void * data,dfsan_label info_label,dfsan_label size_label,dfsan_label data_label,dfsan_label * ret_label),void * callback,void * data,dfsan_label callback_label,dfsan_label data_label,dfsan_label * ret_label)880 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
881 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
882 size_t size, void *data, dfsan_label info_label,
883 dfsan_label size_label, dfsan_label data_label,
884 dfsan_label *ret_label),
885 void *callback, void *data, dfsan_label callback_label,
886 dfsan_label data_label, dfsan_label *ret_label) {
887 dl_iterate_phdr_info dipi = { callback_trampoline, callback, data };
888 *ret_label = 0;
889 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
890 }
891
__dfso_dl_iterate_phdr(int (* callback_trampoline)(void * callback,struct dl_phdr_info * info,size_t size,void * data,dfsan_label info_label,dfsan_label size_label,dfsan_label data_label,dfsan_label * ret_label,dfsan_origin info_origin,dfsan_origin size_origin,dfsan_origin data_origin,dfsan_origin * ret_origin),void * callback,void * data,dfsan_label callback_label,dfsan_label data_label,dfsan_label * ret_label,dfsan_origin callback_origin,dfsan_origin data_origin,dfsan_origin * ret_origin)892 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr(
893 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
894 size_t size, void *data, dfsan_label info_label,
895 dfsan_label size_label, dfsan_label data_label,
896 dfsan_label *ret_label, dfsan_origin info_origin,
897 dfsan_origin size_origin,
898 dfsan_origin data_origin,
899 dfsan_origin *ret_origin),
900 void *callback, void *data, dfsan_label callback_label,
901 dfsan_label data_label, dfsan_label *ret_label,
902 dfsan_origin callback_origin, dfsan_origin data_origin,
903 dfsan_origin *ret_origin) {
904 dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data};
905 *ret_label = 0;
906 return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi);
907 }
908
909 // This function is only available for glibc 2.27 or newer. Mark it weak so
910 // linking succeeds with older glibcs.
911 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep,
912 size_t *alignp);
913
__dfsw__dl_get_tls_static_info(size_t * sizep,size_t * alignp,dfsan_label sizep_label,dfsan_label alignp_label)914 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info(
915 size_t *sizep, size_t *alignp, dfsan_label sizep_label,
916 dfsan_label alignp_label) {
917 assert(_dl_get_tls_static_info);
918 _dl_get_tls_static_info(sizep, alignp);
919 dfsan_set_label(0, sizep, sizeof(*sizep));
920 dfsan_set_label(0, alignp, sizeof(*alignp));
921 }
922
__dfso__dl_get_tls_static_info(size_t * sizep,size_t * alignp,dfsan_label sizep_label,dfsan_label alignp_label,dfsan_origin sizep_origin,dfsan_origin alignp_origin)923 SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info(
924 size_t *sizep, size_t *alignp, dfsan_label sizep_label,
925 dfsan_label alignp_label, dfsan_origin sizep_origin,
926 dfsan_origin alignp_origin) {
927 __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label);
928 }
929
930 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_ctime_r(const time_t * timep,char * buf,dfsan_label timep_label,dfsan_label buf_label,dfsan_label * ret_label)931 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
932 dfsan_label buf_label, dfsan_label *ret_label) {
933 char *ret = ctime_r(timep, buf);
934 if (ret) {
935 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf,
936 strlen(buf) + 1);
937 *ret_label = buf_label;
938 } else {
939 *ret_label = 0;
940 }
941 return ret;
942 }
943
944 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_ctime_r(const time_t * timep,char * buf,dfsan_label timep_label,dfsan_label buf_label,dfsan_label * ret_label,dfsan_origin timep_origin,dfsan_origin buf_origin,dfsan_origin * ret_origin)945 char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
946 dfsan_label buf_label, dfsan_label *ret_label,
947 dfsan_origin timep_origin, dfsan_origin buf_origin,
948 dfsan_origin *ret_origin) {
949 char *ret = ctime_r(timep, buf);
950 if (ret) {
951 dfsan_set_label_origin(
952 dfsan_read_label(timep, sizeof(time_t)),
953 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf,
954 strlen(buf) + 1);
955 *ret_label = buf_label;
956 *ret_origin = buf_origin;
957 } else {
958 *ret_label = 0;
959 }
960 return ret;
961 }
962
963 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_fgets(char * s,int size,FILE * stream,dfsan_label s_label,dfsan_label size_label,dfsan_label stream_label,dfsan_label * ret_label)964 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
965 dfsan_label size_label, dfsan_label stream_label,
966 dfsan_label *ret_label) {
967 char *ret = fgets(s, size, stream);
968 if (ret) {
969 dfsan_set_label(0, ret, strlen(ret) + 1);
970 *ret_label = s_label;
971 } else {
972 *ret_label = 0;
973 }
974 return ret;
975 }
976
977 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_fgets(char * s,int size,FILE * stream,dfsan_label s_label,dfsan_label size_label,dfsan_label stream_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin size_origin,dfsan_origin stream_origin,dfsan_origin * ret_origin)978 char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
979 dfsan_label size_label, dfsan_label stream_label,
980 dfsan_label *ret_label, dfsan_origin s_origin,
981 dfsan_origin size_origin, dfsan_origin stream_origin,
982 dfsan_origin *ret_origin) {
983 char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label,
984 ret_label);
985 if (ret)
986 *ret_origin = s_origin;
987 return ret;
988 }
989
990 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getcwd(char * buf,size_t size,dfsan_label buf_label,dfsan_label size_label,dfsan_label * ret_label)991 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label,
992 dfsan_label size_label, dfsan_label *ret_label) {
993 char *ret = getcwd(buf, size);
994 if (ret) {
995 dfsan_set_label(0, ret, strlen(ret) + 1);
996 *ret_label = buf_label;
997 } else {
998 *ret_label = 0;
999 }
1000 return ret;
1001 }
1002
1003 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_getcwd(char * buf,size_t size,dfsan_label buf_label,dfsan_label size_label,dfsan_label * ret_label,dfsan_origin buf_origin,dfsan_origin size_origin,dfsan_origin * ret_origin)1004 char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label,
1005 dfsan_label size_label, dfsan_label *ret_label,
1006 dfsan_origin buf_origin, dfsan_origin size_origin,
1007 dfsan_origin *ret_origin) {
1008 char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label);
1009 if (ret)
1010 *ret_origin = buf_origin;
1011 return ret;
1012 }
1013
1014 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_get_current_dir_name(dfsan_label * ret_label)1015 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) {
1016 char *ret = get_current_dir_name();
1017 if (ret)
1018 dfsan_set_label(0, ret, strlen(ret) + 1);
1019 *ret_label = 0;
1020 return ret;
1021 }
1022
1023 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_get_current_dir_name(dfsan_label * ret_label,dfsan_origin * ret_origin)1024 char *__dfso_get_current_dir_name(dfsan_label *ret_label,
1025 dfsan_origin *ret_origin) {
1026 return __dfsw_get_current_dir_name(ret_label);
1027 }
1028
1029 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_gethostname(char * name,size_t len,dfsan_label name_label,dfsan_label len_label,dfsan_label * ret_label)1030 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label,
1031 dfsan_label len_label, dfsan_label *ret_label) {
1032 int ret = gethostname(name, len);
1033 if (ret == 0) {
1034 dfsan_set_label(0, name, strlen(name) + 1);
1035 }
1036 *ret_label = 0;
1037 return ret;
1038 }
1039
1040 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_gethostname(char * name,size_t len,dfsan_label name_label,dfsan_label len_label,dfsan_label * ret_label,dfsan_origin name_origin,dfsan_origin len_origin,dfsan_label * ret_origin)1041 int __dfso_gethostname(char *name, size_t len, dfsan_label name_label,
1042 dfsan_label len_label, dfsan_label *ret_label,
1043 dfsan_origin name_origin, dfsan_origin len_origin,
1044 dfsan_label *ret_origin) {
1045 return __dfsw_gethostname(name, len, name_label, len_label, ret_label);
1046 }
1047
1048 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getrlimit(int resource,struct rlimit * rlim,dfsan_label resource_label,dfsan_label rlim_label,dfsan_label * ret_label)1049 int __dfsw_getrlimit(int resource, struct rlimit *rlim,
1050 dfsan_label resource_label, dfsan_label rlim_label,
1051 dfsan_label *ret_label) {
1052 int ret = getrlimit(resource, rlim);
1053 if (ret == 0) {
1054 dfsan_set_label(0, rlim, sizeof(struct rlimit));
1055 }
1056 *ret_label = 0;
1057 return ret;
1058 }
1059
1060 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_getrlimit(int resource,struct rlimit * rlim,dfsan_label resource_label,dfsan_label rlim_label,dfsan_label * ret_label,dfsan_origin resource_origin,dfsan_origin rlim_origin,dfsan_origin * ret_origin)1061 int __dfso_getrlimit(int resource, struct rlimit *rlim,
1062 dfsan_label resource_label, dfsan_label rlim_label,
1063 dfsan_label *ret_label, dfsan_origin resource_origin,
1064 dfsan_origin rlim_origin, dfsan_origin *ret_origin) {
1065 return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label,
1066 ret_label);
1067 }
1068
1069 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getrusage(int who,struct rusage * usage,dfsan_label who_label,dfsan_label usage_label,dfsan_label * ret_label)1070 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1071 dfsan_label usage_label, dfsan_label *ret_label) {
1072 int ret = getrusage(who, usage);
1073 if (ret == 0) {
1074 dfsan_set_label(0, usage, sizeof(struct rusage));
1075 }
1076 *ret_label = 0;
1077 return ret;
1078 }
1079
1080 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_getrusage(int who,struct rusage * usage,dfsan_label who_label,dfsan_label usage_label,dfsan_label * ret_label,dfsan_origin who_origin,dfsan_origin usage_origin,dfsan_label * ret_origin)1081 int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1082 dfsan_label usage_label, dfsan_label *ret_label,
1083 dfsan_origin who_origin, dfsan_origin usage_origin,
1084 dfsan_label *ret_origin) {
1085 return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label);
1086 }
1087
1088 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strcpy(char * dest,const char * src,dfsan_label dst_label,dfsan_label src_label,dfsan_label * ret_label)1089 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label,
1090 dfsan_label src_label, dfsan_label *ret_label) {
1091 char *ret = strcpy(dest, src); // NOLINT
1092 if (ret) {
1093 internal_memcpy(shadow_for(dest), shadow_for(src),
1094 sizeof(dfsan_label) * (strlen(src) + 1));
1095 }
1096 *ret_label = dst_label;
1097 return ret;
1098 }
1099
1100 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strcpy(char * dest,const char * src,dfsan_label dst_label,dfsan_label src_label,dfsan_label * ret_label,dfsan_origin dst_origin,dfsan_origin src_origin,dfsan_origin * ret_origin)1101 char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label,
1102 dfsan_label src_label, dfsan_label *ret_label,
1103 dfsan_origin dst_origin, dfsan_origin src_origin,
1104 dfsan_origin *ret_origin) {
1105 char *ret = strcpy(dest, src); // NOLINT
1106 if (ret) {
1107 size_t str_len = strlen(src) + 1;
1108 dfsan_mem_origin_transfer(dest, src, str_len);
1109 internal_memcpy(shadow_for(dest), shadow_for(src),
1110 sizeof(dfsan_label) * str_len);
1111 }
1112 *ret_label = dst_label;
1113 *ret_origin = dst_origin;
1114 return ret;
1115 }
1116
dfsan_strtol(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1117 static long int dfsan_strtol(const char *nptr, char **endptr, int base,
1118 char **tmp_endptr) {
1119 assert(tmp_endptr);
1120 long int ret = strtol(nptr, tmp_endptr, base);
1121 if (endptr)
1122 *endptr = *tmp_endptr;
1123 return ret;
1124 }
1125
dfsan_strtolong_label(const char * nptr,const char * tmp_endptr,dfsan_label base_label,dfsan_label * ret_label)1126 static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr,
1127 dfsan_label base_label,
1128 dfsan_label *ret_label) {
1129 if (tmp_endptr > nptr) {
1130 // If *tmp_endptr is '\0' include its label as well.
1131 *ret_label = dfsan_union(
1132 base_label,
1133 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));
1134 } else {
1135 *ret_label = 0;
1136 }
1137 }
1138
dfsan_strtolong_origin(const char * nptr,const char * tmp_endptr,dfsan_label base_label,dfsan_label * ret_label,dfsan_origin base_origin,dfsan_origin * ret_origin)1139 static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr,
1140 dfsan_label base_label,
1141 dfsan_label *ret_label,
1142 dfsan_origin base_origin,
1143 dfsan_origin *ret_origin) {
1144 if (tmp_endptr > nptr) {
1145 // When multiple inputs are tainted, we propagate one of its origins.
1146 // Because checking if base_label is tainted does not need additional
1147 // computation, we prefer to propagating base_origin.
1148 *ret_origin = base_label
1149 ? base_origin
1150 : dfsan_read_origin_of_first_taint(
1151 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1152 }
1153 }
1154
1155 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtol(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label)1156 long int __dfsw_strtol(const char *nptr, char **endptr, int base,
1157 dfsan_label nptr_label, dfsan_label endptr_label,
1158 dfsan_label base_label, dfsan_label *ret_label) {
1159 char *tmp_endptr;
1160 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1161 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1162 return ret;
1163 }
1164
1165 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strtol(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label,dfsan_origin nptr_origin,dfsan_origin endptr_origin,dfsan_origin base_origin,dfsan_origin * ret_origin)1166 long int __dfso_strtol(const char *nptr, char **endptr, int base,
1167 dfsan_label nptr_label, dfsan_label endptr_label,
1168 dfsan_label base_label, dfsan_label *ret_label,
1169 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1170 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1171 char *tmp_endptr;
1172 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1173 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1174 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1175 ret_origin);
1176 return ret;
1177 }
1178
dfsan_strtod(const char * nptr,char ** endptr,char ** tmp_endptr)1179 static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) {
1180 assert(tmp_endptr);
1181 double ret = strtod(nptr, tmp_endptr);
1182 if (endptr)
1183 *endptr = *tmp_endptr;
1184 return ret;
1185 }
1186
dfsan_strtod_label(const char * nptr,const char * tmp_endptr,dfsan_label * ret_label)1187 static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr,
1188 dfsan_label *ret_label) {
1189 if (tmp_endptr > nptr) {
1190 // If *tmp_endptr is '\0' include its label as well.
1191 *ret_label = dfsan_read_label(
1192 nptr,
1193 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1194 } else {
1195 *ret_label = 0;
1196 }
1197 }
1198
1199 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtod(const char * nptr,char ** endptr,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label * ret_label)1200 double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1201 dfsan_label endptr_label, dfsan_label *ret_label) {
1202 char *tmp_endptr;
1203 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1204 dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1205 return ret;
1206 }
1207
1208 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strtod(const char * nptr,char ** endptr,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label * ret_label,dfsan_origin nptr_origin,dfsan_origin endptr_origin,dfsan_origin * ret_origin)1209 double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1210 dfsan_label endptr_label, dfsan_label *ret_label,
1211 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1212 dfsan_origin *ret_origin) {
1213 char *tmp_endptr;
1214 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1215 dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1216 if (tmp_endptr > nptr) {
1217 // If *tmp_endptr is '\0' include its label as well.
1218 *ret_origin = dfsan_read_origin_of_first_taint(
1219 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1220 } else {
1221 *ret_origin = 0;
1222 }
1223 return ret;
1224 }
1225
dfsan_strtoll(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1226 static long long int dfsan_strtoll(const char *nptr, char **endptr, int base,
1227 char **tmp_endptr) {
1228 assert(tmp_endptr);
1229 long long int ret = strtoll(nptr, tmp_endptr, base);
1230 if (endptr)
1231 *endptr = *tmp_endptr;
1232 return ret;
1233 }
1234
1235 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtoll(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label)1236 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base,
1237 dfsan_label nptr_label, dfsan_label endptr_label,
1238 dfsan_label base_label, dfsan_label *ret_label) {
1239 char *tmp_endptr;
1240 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1241 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1242 return ret;
1243 }
1244
1245 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strtoll(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label,dfsan_origin nptr_origin,dfsan_origin endptr_origin,dfsan_origin base_origin,dfsan_origin * ret_origin)1246 long long int __dfso_strtoll(const char *nptr, char **endptr, int base,
1247 dfsan_label nptr_label, dfsan_label endptr_label,
1248 dfsan_label base_label, dfsan_label *ret_label,
1249 dfsan_origin nptr_origin,
1250 dfsan_origin endptr_origin,
1251 dfsan_origin base_origin,
1252 dfsan_origin *ret_origin) {
1253 char *tmp_endptr;
1254 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1255 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1256 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1257 ret_origin);
1258 return ret;
1259 }
1260
dfsan_strtoul(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1261 static unsigned long int dfsan_strtoul(const char *nptr, char **endptr,
1262 int base, char **tmp_endptr) {
1263 assert(tmp_endptr);
1264 unsigned long int ret = strtoul(nptr, tmp_endptr, base);
1265 if (endptr)
1266 *endptr = *tmp_endptr;
1267 return ret;
1268 }
1269
1270 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtoul(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label)1271 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base,
1272 dfsan_label nptr_label, dfsan_label endptr_label,
1273 dfsan_label base_label, dfsan_label *ret_label) {
1274 char *tmp_endptr;
1275 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1276 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1277 return ret;
1278 }
1279
1280 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strtoul(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label,dfsan_origin nptr_origin,dfsan_origin endptr_origin,dfsan_origin base_origin,dfsan_origin * ret_origin)1281 unsigned long int __dfso_strtoul(
1282 const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1283 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1284 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1285 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1286 char *tmp_endptr;
1287 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1288 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1289 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1290 ret_origin);
1291 return ret;
1292 }
1293
dfsan_strtoull(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1294 static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr,
1295 int base, char **tmp_endptr) {
1296 assert(tmp_endptr);
1297 long long unsigned int ret = strtoull(nptr, tmp_endptr, base);
1298 if (endptr)
1299 *endptr = *tmp_endptr;
1300 return ret;
1301 }
1302
1303 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtoull(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label)1304 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr,
1305 int base, dfsan_label nptr_label,
1306 dfsan_label endptr_label,
1307 dfsan_label base_label,
1308 dfsan_label *ret_label) {
1309 char *tmp_endptr;
1310 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1311 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1312 return ret;
1313 }
1314
1315 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_strtoull(const char * nptr,char ** endptr,int base,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label base_label,dfsan_label * ret_label,dfsan_origin nptr_origin,dfsan_origin endptr_origin,dfsan_origin base_origin,dfsan_origin * ret_origin)1316 long long unsigned int __dfso_strtoull(
1317 const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1318 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1319 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1320 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1321 char *tmp_endptr;
1322 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1323 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1324 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1325 ret_origin);
1326 return ret;
1327 }
1328
1329 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_time(time_t * t,dfsan_label t_label,dfsan_label * ret_label)1330 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) {
1331 time_t ret = time(t);
1332 if (ret != (time_t) -1 && t) {
1333 dfsan_set_label(0, t, sizeof(time_t));
1334 }
1335 *ret_label = 0;
1336 return ret;
1337 }
1338
1339 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_time(time_t * t,dfsan_label t_label,dfsan_label * ret_label,dfsan_origin t_origin,dfsan_origin * ret_origin)1340 time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label,
1341 dfsan_origin t_origin, dfsan_origin *ret_origin) {
1342 return __dfsw_time(t, t_label, ret_label);
1343 }
1344
1345 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_inet_pton(int af,const char * src,void * dst,dfsan_label af_label,dfsan_label src_label,dfsan_label dst_label,dfsan_label * ret_label)1346 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1347 dfsan_label src_label, dfsan_label dst_label,
1348 dfsan_label *ret_label) {
1349 int ret = inet_pton(af, src, dst);
1350 if (ret == 1) {
1351 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst,
1352 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1353 }
1354 *ret_label = 0;
1355 return ret;
1356 }
1357
1358 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_inet_pton(int af,const char * src,void * dst,dfsan_label af_label,dfsan_label src_label,dfsan_label dst_label,dfsan_label * ret_label,dfsan_origin af_origin,dfsan_origin src_origin,dfsan_origin dst_origin,dfsan_origin * ret_origin)1359 int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1360 dfsan_label src_label, dfsan_label dst_label,
1361 dfsan_label *ret_label, dfsan_origin af_origin,
1362 dfsan_origin src_origin, dfsan_origin dst_origin,
1363 dfsan_origin *ret_origin) {
1364 int ret = inet_pton(af, src, dst);
1365 if (ret == 1) {
1366 int src_len = strlen(src) + 1;
1367 dfsan_set_label_origin(
1368 dfsan_read_label(src, src_len),
1369 dfsan_read_origin_of_first_taint(src, src_len), dst,
1370 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1371 }
1372 *ret_label = 0;
1373 return ret;
1374 }
1375
1376 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_localtime_r(const time_t * timep,struct tm * result,dfsan_label timep_label,dfsan_label result_label,dfsan_label * ret_label)1377 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result,
1378 dfsan_label timep_label, dfsan_label result_label,
1379 dfsan_label *ret_label) {
1380 struct tm *ret = localtime_r(timep, result);
1381 if (ret) {
1382 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result,
1383 sizeof(struct tm));
1384 *ret_label = result_label;
1385 } else {
1386 *ret_label = 0;
1387 }
1388 return ret;
1389 }
1390
1391 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_localtime_r(const time_t * timep,struct tm * result,dfsan_label timep_label,dfsan_label result_label,dfsan_label * ret_label,dfsan_origin timep_origin,dfsan_origin result_origin,dfsan_origin * ret_origin)1392 struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result,
1393 dfsan_label timep_label, dfsan_label result_label,
1394 dfsan_label *ret_label, dfsan_origin timep_origin,
1395 dfsan_origin result_origin,
1396 dfsan_origin *ret_origin) {
1397 struct tm *ret = localtime_r(timep, result);
1398 if (ret) {
1399 dfsan_set_label_origin(
1400 dfsan_read_label(timep, sizeof(time_t)),
1401 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result,
1402 sizeof(struct tm));
1403 *ret_label = result_label;
1404 *ret_origin = result_origin;
1405 } else {
1406 *ret_label = 0;
1407 }
1408 return ret;
1409 }
1410
1411 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getpwuid_r(id_t uid,struct passwd * pwd,char * buf,size_t buflen,struct passwd ** result,dfsan_label uid_label,dfsan_label pwd_label,dfsan_label buf_label,dfsan_label buflen_label,dfsan_label result_label,dfsan_label * ret_label)1412 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,
1413 char *buf, size_t buflen, struct passwd **result,
1414 dfsan_label uid_label, dfsan_label pwd_label,
1415 dfsan_label buf_label, dfsan_label buflen_label,
1416 dfsan_label result_label, dfsan_label *ret_label) {
1417 // Store the data in pwd, the strings referenced from pwd in buf, and the
1418 // address of pwd in *result. On failure, NULL is stored in *result.
1419 int ret = getpwuid_r(uid, pwd, buf, buflen, result);
1420 if (ret == 0) {
1421 dfsan_set_label(0, pwd, sizeof(struct passwd));
1422 dfsan_set_label(0, buf, strlen(buf) + 1);
1423 }
1424 *ret_label = 0;
1425 dfsan_set_label(0, result, sizeof(struct passwd*));
1426 return ret;
1427 }
1428
1429 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_getpwuid_r(id_t uid,struct passwd * pwd,char * buf,size_t buflen,struct passwd ** result,dfsan_label uid_label,dfsan_label pwd_label,dfsan_label buf_label,dfsan_label buflen_label,dfsan_label result_label,dfsan_label * ret_label,dfsan_origin uid_origin,dfsan_origin pwd_origin,dfsan_origin buf_origin,dfsan_origin buflen_origin,dfsan_origin result_origin,dfsan_origin * ret_origin)1430 int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen,
1431 struct passwd **result, dfsan_label uid_label,
1432 dfsan_label pwd_label, dfsan_label buf_label,
1433 dfsan_label buflen_label, dfsan_label result_label,
1434 dfsan_label *ret_label, dfsan_origin uid_origin,
1435 dfsan_origin pwd_origin, dfsan_origin buf_origin,
1436 dfsan_origin buflen_origin, dfsan_origin result_origin,
1437 dfsan_origin *ret_origin) {
1438 return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label,
1439 buf_label, buflen_label, result_label, ret_label);
1440 }
1441
1442 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout,dfsan_label epfd_label,dfsan_label events_label,dfsan_label maxevents_label,dfsan_label timeout_label,dfsan_label * ret_label)1443 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1444 int timeout, dfsan_label epfd_label,
1445 dfsan_label events_label, dfsan_label maxevents_label,
1446 dfsan_label timeout_label, dfsan_label *ret_label) {
1447 int ret = epoll_wait(epfd, events, maxevents, timeout);
1448 if (ret > 0)
1449 dfsan_set_label(0, events, ret * sizeof(*events));
1450 *ret_label = 0;
1451 return ret;
1452 }
1453
1454 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout,dfsan_label epfd_label,dfsan_label events_label,dfsan_label maxevents_label,dfsan_label timeout_label,dfsan_label * ret_label,dfsan_origin epfd_origin,dfsan_origin events_origin,dfsan_origin maxevents_origin,dfsan_origin timeout_origin,dfsan_origin * ret_origin)1455 int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1456 int timeout, dfsan_label epfd_label,
1457 dfsan_label events_label, dfsan_label maxevents_label,
1458 dfsan_label timeout_label, dfsan_label *ret_label,
1459 dfsan_origin epfd_origin, dfsan_origin events_origin,
1460 dfsan_origin maxevents_origin,
1461 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1462 return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label,
1463 events_label, maxevents_label, timeout_label,
1464 ret_label);
1465 }
1466
1467 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_poll(struct pollfd * fds,nfds_t nfds,int timeout,dfsan_label dfs_label,dfsan_label nfds_label,dfsan_label timeout_label,dfsan_label * ret_label)1468 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1469 dfsan_label dfs_label, dfsan_label nfds_label,
1470 dfsan_label timeout_label, dfsan_label *ret_label) {
1471 int ret = poll(fds, nfds, timeout);
1472 if (ret >= 0) {
1473 for (; nfds > 0; --nfds) {
1474 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents));
1475 }
1476 }
1477 *ret_label = 0;
1478 return ret;
1479 }
1480
1481 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_poll(struct pollfd * fds,nfds_t nfds,int timeout,dfsan_label dfs_label,dfsan_label nfds_label,dfsan_label timeout_label,dfsan_label * ret_label,dfsan_origin dfs_origin,dfsan_origin nfds_origin,dfsan_origin timeout_origin,dfsan_origin * ret_origin)1482 int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1483 dfsan_label dfs_label, dfsan_label nfds_label,
1484 dfsan_label timeout_label, dfsan_label *ret_label,
1485 dfsan_origin dfs_origin, dfsan_origin nfds_origin,
1486 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1487 return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label,
1488 ret_label);
1489 }
1490
1491 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout,dfsan_label nfds_label,dfsan_label readfds_label,dfsan_label writefds_label,dfsan_label exceptfds_label,dfsan_label timeout_label,dfsan_label * ret_label)1492 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds,
1493 fd_set *exceptfds, struct timeval *timeout,
1494 dfsan_label nfds_label, dfsan_label readfds_label,
1495 dfsan_label writefds_label, dfsan_label exceptfds_label,
1496 dfsan_label timeout_label, dfsan_label *ret_label) {
1497 int ret = select(nfds, readfds, writefds, exceptfds, timeout);
1498 // Clear everything (also on error) since their content is either set or
1499 // undefined.
1500 if (readfds) {
1501 dfsan_set_label(0, readfds, sizeof(fd_set));
1502 }
1503 if (writefds) {
1504 dfsan_set_label(0, writefds, sizeof(fd_set));
1505 }
1506 if (exceptfds) {
1507 dfsan_set_label(0, exceptfds, sizeof(fd_set));
1508 }
1509 dfsan_set_label(0, timeout, sizeof(struct timeval));
1510 *ret_label = 0;
1511 return ret;
1512 }
1513
1514 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_select(int nfds,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout,dfsan_label nfds_label,dfsan_label readfds_label,dfsan_label writefds_label,dfsan_label exceptfds_label,dfsan_label timeout_label,dfsan_label * ret_label,dfsan_origin nfds_origin,dfsan_origin readfds_origin,dfsan_origin writefds_origin,dfsan_origin exceptfds_origin,dfsan_origin timeout_origin,dfsan_origin * ret_origin)1515 int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds,
1516 fd_set *exceptfds, struct timeval *timeout,
1517 dfsan_label nfds_label, dfsan_label readfds_label,
1518 dfsan_label writefds_label, dfsan_label exceptfds_label,
1519 dfsan_label timeout_label, dfsan_label *ret_label,
1520 dfsan_origin nfds_origin, dfsan_origin readfds_origin,
1521 dfsan_origin writefds_origin, dfsan_origin exceptfds_origin,
1522 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1523 return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label,
1524 readfds_label, writefds_label, exceptfds_label,
1525 timeout_label, ret_label);
1526 }
1527
1528 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sched_getaffinity(pid_t pid,size_t cpusetsize,cpu_set_t * mask,dfsan_label pid_label,dfsan_label cpusetsize_label,dfsan_label mask_label,dfsan_label * ret_label)1529 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1530 dfsan_label pid_label,
1531 dfsan_label cpusetsize_label,
1532 dfsan_label mask_label, dfsan_label *ret_label) {
1533 int ret = sched_getaffinity(pid, cpusetsize, mask);
1534 if (ret == 0) {
1535 dfsan_set_label(0, mask, cpusetsize);
1536 }
1537 *ret_label = 0;
1538 return ret;
1539 }
1540
1541 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sched_getaffinity(pid_t pid,size_t cpusetsize,cpu_set_t * mask,dfsan_label pid_label,dfsan_label cpusetsize_label,dfsan_label mask_label,dfsan_label * ret_label,dfsan_origin pid_origin,dfsan_origin cpusetsize_origin,dfsan_origin mask_origin,dfsan_origin * ret_origin)1542 int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1543 dfsan_label pid_label,
1544 dfsan_label cpusetsize_label,
1545 dfsan_label mask_label, dfsan_label *ret_label,
1546 dfsan_origin pid_origin,
1547 dfsan_origin cpusetsize_origin,
1548 dfsan_origin mask_origin,
1549 dfsan_origin *ret_origin) {
1550 return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label,
1551 cpusetsize_label, mask_label, ret_label);
1552 }
1553
1554 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sigemptyset(sigset_t * set,dfsan_label set_label,dfsan_label * ret_label)1555 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label,
1556 dfsan_label *ret_label) {
1557 int ret = sigemptyset(set);
1558 dfsan_set_label(0, set, sizeof(sigset_t));
1559 *ret_label = 0;
1560 return ret;
1561 }
1562
1563 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sigemptyset(sigset_t * set,dfsan_label set_label,dfsan_label * ret_label,dfsan_origin set_origin,dfsan_origin * ret_origin)1564 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label,
1565 dfsan_label *ret_label, dfsan_origin set_origin,
1566 dfsan_origin *ret_origin) {
1567 return __dfsw_sigemptyset(set, set_label, ret_label);
1568 }
1569
1570 class SignalHandlerScope {
1571 public:
SignalHandlerScope()1572 SignalHandlerScope() {
1573 if (DFsanThread *t = GetCurrentThread())
1574 t->EnterSignalHandler();
1575 }
~SignalHandlerScope()1576 ~SignalHandlerScope() {
1577 if (DFsanThread *t = GetCurrentThread())
1578 t->LeaveSignalHandler();
1579 }
1580 };
1581
1582 // Clear DFSan runtime TLS state at the end of a scope.
1583 //
1584 // Implementation must be async-signal-safe and use small data size, because
1585 // instances of this class may live on the signal handler stack.
1586 //
1587 // DFSan uses TLS to pass metadata of arguments and return values. When an
1588 // instrumented function accesses the TLS, if a signal callback happens, and the
1589 // callback calls other instrumented functions with updating the same TLS, the
1590 // TLS is in an inconsistent state after the callback ends. This may cause
1591 // either under-tainting or over-tainting.
1592 //
1593 // The current implementation simply resets TLS at restore. This prevents from
1594 // over-tainting. Although under-tainting may still happen, a taint flow can be
1595 // found eventually if we run a DFSan-instrumented program multiple times. The
1596 // alternative option is saving the entire TLS. However the TLS storage takes
1597 // 2k bytes, and signal calls could be nested. So it does not seem worth.
1598 class ScopedClearThreadLocalState {
1599 public:
ScopedClearThreadLocalState()1600 ScopedClearThreadLocalState() {}
~ScopedClearThreadLocalState()1601 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); }
1602 };
1603
1604 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls.
1605 const int kMaxSignals = 1024;
1606 static atomic_uintptr_t sigactions[kMaxSignals];
1607
SignalHandler(int signo)1608 static void SignalHandler(int signo) {
1609 SignalHandlerScope signal_handler_scope;
1610 ScopedClearThreadLocalState scoped_clear_tls;
1611
1612 // Clear shadows for all inputs provided by system. This is why DFSan
1613 // instrumentation generates a trampoline function to each function pointer,
1614 // and uses the trampoline to clear shadows. However sigaction does not use
1615 // a function pointer directly, so we have to do this manually.
1616 dfsan_clear_arg_tls(0, sizeof(dfsan_label));
1617
1618 typedef void (*signal_cb)(int x);
1619 signal_cb cb =
1620 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1621 cb(signo);
1622 }
1623
SignalAction(int signo,siginfo_t * si,void * uc)1624 static void SignalAction(int signo, siginfo_t *si, void *uc) {
1625 SignalHandlerScope signal_handler_scope;
1626 ScopedClearThreadLocalState scoped_clear_tls;
1627
1628 // Clear shadows for all inputs provided by system. Similar to SignalHandler.
1629 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label));
1630 dfsan_set_label(0, si, sizeof(*si));
1631 dfsan_set_label(0, uc, sizeof(ucontext_t));
1632
1633 typedef void (*sigaction_cb)(int, siginfo_t *, void *);
1634 sigaction_cb cb =
1635 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1636 cb(signo, si, uc);
1637 }
1638
1639 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sigaction(int signum,const struct sigaction * act,struct sigaction * oldact,dfsan_label signum_label,dfsan_label act_label,dfsan_label oldact_label,dfsan_label * ret_label)1640 int __dfsw_sigaction(int signum, const struct sigaction *act,
1641 struct sigaction *oldact, dfsan_label signum_label,
1642 dfsan_label act_label, dfsan_label oldact_label,
1643 dfsan_label *ret_label) {
1644 CHECK_LT(signum, kMaxSignals);
1645 SignalSpinLocker lock;
1646 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1647 struct sigaction new_act;
1648 struct sigaction *pnew_act = act ? &new_act : nullptr;
1649 if (act) {
1650 internal_memcpy(pnew_act, act, sizeof(struct sigaction));
1651 if (pnew_act->sa_flags & SA_SIGINFO) {
1652 uptr cb = (uptr)(pnew_act->sa_sigaction);
1653 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1654 atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1655 pnew_act->sa_sigaction = SignalAction;
1656 }
1657 } else {
1658 uptr cb = (uptr)(pnew_act->sa_handler);
1659 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1660 atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1661 pnew_act->sa_handler = SignalHandler;
1662 }
1663 }
1664 }
1665
1666 int ret = sigaction(signum, pnew_act, oldact);
1667
1668 if (ret == 0 && oldact) {
1669 if (oldact->sa_flags & SA_SIGINFO) {
1670 if (oldact->sa_sigaction == SignalAction)
1671 oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb;
1672 } else {
1673 if (oldact->sa_handler == SignalHandler)
1674 oldact->sa_handler = (decltype(oldact->sa_handler))old_cb;
1675 }
1676 }
1677
1678 if (oldact) {
1679 dfsan_set_label(0, oldact, sizeof(struct sigaction));
1680 }
1681 *ret_label = 0;
1682 return ret;
1683 }
1684
1685 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sigaction(int signum,const struct sigaction * act,struct sigaction * oldact,dfsan_label signum_label,dfsan_label act_label,dfsan_label oldact_label,dfsan_label * ret_label,dfsan_origin signum_origin,dfsan_origin act_origin,dfsan_origin oldact_origin,dfsan_origin * ret_origin)1686 int __dfso_sigaction(int signum, const struct sigaction *act,
1687 struct sigaction *oldact, dfsan_label signum_label,
1688 dfsan_label act_label, dfsan_label oldact_label,
1689 dfsan_label *ret_label, dfsan_origin signum_origin,
1690 dfsan_origin act_origin, dfsan_origin oldact_origin,
1691 dfsan_origin *ret_origin) {
1692 return __dfsw_sigaction(signum, act, oldact, signum_label, act_label,
1693 oldact_label, ret_label);
1694 }
1695
dfsan_signal(int signum,sighandler_t handler,dfsan_label * ret_label)1696 static sighandler_t dfsan_signal(int signum, sighandler_t handler,
1697 dfsan_label *ret_label) {
1698 CHECK_LT(signum, kMaxSignals);
1699 SignalSpinLocker lock;
1700 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1701 if (handler != SIG_IGN && handler != SIG_DFL) {
1702 atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed);
1703 handler = &SignalHandler;
1704 }
1705
1706 sighandler_t ret = signal(signum, handler);
1707
1708 if (ret == SignalHandler)
1709 ret = (sighandler_t)old_cb;
1710
1711 *ret_label = 0;
1712 return ret;
1713 }
1714
1715 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_signal(int signum,void * (* handler_trampoline)(void *,int,dfsan_label,dfsan_label *),sighandler_t handler,dfsan_label signum_label,dfsan_label handler_label,dfsan_label * ret_label)1716 sighandler_t __dfsw_signal(int signum,
1717 void *(*handler_trampoline)(void *, int, dfsan_label,
1718 dfsan_label *),
1719 sighandler_t handler, dfsan_label signum_label,
1720 dfsan_label handler_label, dfsan_label *ret_label) {
1721 return dfsan_signal(signum, handler, ret_label);
1722 }
1723
1724 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_signal(int signum,void * (* handler_trampoline)(void *,int,dfsan_label,dfsan_label *,dfsan_origin,dfsan_origin *),sighandler_t handler,dfsan_label signum_label,dfsan_label handler_label,dfsan_label * ret_label,dfsan_origin signum_origin,dfsan_origin handler_origin,dfsan_origin * ret_origin)1725 sighandler_t __dfso_signal(
1726 int signum,
1727 void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *,
1728 dfsan_origin, dfsan_origin *),
1729 sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label,
1730 dfsan_label *ret_label, dfsan_origin signum_origin,
1731 dfsan_origin handler_origin, dfsan_origin *ret_origin) {
1732 return dfsan_signal(signum, handler, ret_label);
1733 }
1734
1735 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sigaltstack(const stack_t * ss,stack_t * old_ss,dfsan_label ss_label,dfsan_label old_ss_label,dfsan_label * ret_label)1736 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1737 dfsan_label old_ss_label, dfsan_label *ret_label) {
1738 int ret = sigaltstack(ss, old_ss);
1739 if (ret != -1 && old_ss)
1740 dfsan_set_label(0, old_ss, sizeof(*old_ss));
1741 *ret_label = 0;
1742 return ret;
1743 }
1744
1745 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sigaltstack(const stack_t * ss,stack_t * old_ss,dfsan_label ss_label,dfsan_label old_ss_label,dfsan_label * ret_label,dfsan_origin ss_origin,dfsan_origin old_ss_origin,dfsan_origin * ret_origin)1746 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1747 dfsan_label old_ss_label, dfsan_label *ret_label,
1748 dfsan_origin ss_origin, dfsan_origin old_ss_origin,
1749 dfsan_origin *ret_origin) {
1750 return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label);
1751 }
1752
1753 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_gettimeofday(struct timeval * tv,struct timezone * tz,dfsan_label tv_label,dfsan_label tz_label,dfsan_label * ret_label)1754 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz,
1755 dfsan_label tv_label, dfsan_label tz_label,
1756 dfsan_label *ret_label) {
1757 int ret = gettimeofday(tv, tz);
1758 if (tv) {
1759 dfsan_set_label(0, tv, sizeof(struct timeval));
1760 }
1761 if (tz) {
1762 dfsan_set_label(0, tz, sizeof(struct timezone));
1763 }
1764 *ret_label = 0;
1765 return ret;
1766 }
1767
1768 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_gettimeofday(struct timeval * tv,struct timezone * tz,dfsan_label tv_label,dfsan_label tz_label,dfsan_label * ret_label,dfsan_origin tv_origin,dfsan_origin tz_origin,dfsan_origin * ret_origin)1769 int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz,
1770 dfsan_label tv_label, dfsan_label tz_label,
1771 dfsan_label *ret_label, dfsan_origin tv_origin,
1772 dfsan_origin tz_origin, dfsan_origin *ret_origin) {
1773 return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label);
1774 }
1775
__dfsw_memchr(void * s,int c,size_t n,dfsan_label s_label,dfsan_label c_label,dfsan_label n_label,dfsan_label * ret_label)1776 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n,
1777 dfsan_label s_label,
1778 dfsan_label c_label,
1779 dfsan_label n_label,
1780 dfsan_label *ret_label) {
1781 void *ret = memchr(s, c, n);
1782 if (flags().strict_data_dependencies) {
1783 *ret_label = ret ? s_label : 0;
1784 } else {
1785 size_t len =
1786 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1787 : n;
1788 *ret_label =
1789 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label));
1790 }
1791 return ret;
1792 }
1793
__dfso_memchr(void * s,int c,size_t n,dfsan_label s_label,dfsan_label c_label,dfsan_label n_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin c_origin,dfsan_origin n_origin,dfsan_origin * ret_origin)1794 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr(
1795 void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label,
1796 dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin,
1797 dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) {
1798 void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label);
1799 if (flags().strict_data_dependencies) {
1800 if (ret)
1801 *ret_origin = s_origin;
1802 } else {
1803 size_t len =
1804 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1805 : n;
1806 dfsan_origin o = dfsan_read_origin_of_first_taint(s, len);
1807 *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1808 }
1809 return ret;
1810 }
1811
__dfsw_strrchr(char * s,int c,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label)1812 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c,
1813 dfsan_label s_label,
1814 dfsan_label c_label,
1815 dfsan_label *ret_label) {
1816 char *ret = strrchr(s, c);
1817 if (flags().strict_data_dependencies) {
1818 *ret_label = ret ? s_label : 0;
1819 } else {
1820 *ret_label =
1821 dfsan_union(dfsan_read_label(s, strlen(s) + 1),
1822 dfsan_union(s_label, c_label));
1823 }
1824
1825 return ret;
1826 }
1827
__dfso_strrchr(char * s,int c,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin c_origin,dfsan_origin * ret_origin)1828 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr(
1829 char *s, int c, dfsan_label s_label, dfsan_label c_label,
1830 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
1831 dfsan_origin *ret_origin) {
1832 char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label);
1833 if (flags().strict_data_dependencies) {
1834 if (ret)
1835 *ret_origin = s_origin;
1836 } else {
1837 size_t s_len = strlen(s) + 1;
1838 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len);
1839 *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1840 }
1841
1842 return ret;
1843 }
1844
__dfsw_strstr(char * haystack,char * needle,dfsan_label haystack_label,dfsan_label needle_label,dfsan_label * ret_label)1845 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle,
1846 dfsan_label haystack_label,
1847 dfsan_label needle_label,
1848 dfsan_label *ret_label) {
1849 char *ret = strstr(haystack, needle);
1850 if (flags().strict_data_dependencies) {
1851 *ret_label = ret ? haystack_label : 0;
1852 } else {
1853 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1;
1854 *ret_label =
1855 dfsan_union(dfsan_read_label(haystack, len),
1856 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1),
1857 dfsan_union(haystack_label, needle_label)));
1858 }
1859
1860 return ret;
1861 }
1862
__dfso_strstr(char * haystack,char * needle,dfsan_label haystack_label,dfsan_label needle_label,dfsan_label * ret_label,dfsan_origin haystack_origin,dfsan_origin needle_origin,dfsan_origin * ret_origin)1863 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle,
1864 dfsan_label haystack_label,
1865 dfsan_label needle_label,
1866 dfsan_label *ret_label,
1867 dfsan_origin haystack_origin,
1868 dfsan_origin needle_origin,
1869 dfsan_origin *ret_origin) {
1870 char *ret =
1871 __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label);
1872 if (flags().strict_data_dependencies) {
1873 if (ret)
1874 *ret_origin = haystack_origin;
1875 } else {
1876 size_t needle_len = strlen(needle);
1877 size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1;
1878 dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len);
1879 if (o) {
1880 *ret_origin = o;
1881 } else {
1882 o = dfsan_read_origin_of_first_taint(needle, needle_len + 1);
1883 *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin);
1884 }
1885 }
1886
1887 return ret;
1888 }
1889
__dfsw_nanosleep(const struct timespec * req,struct timespec * rem,dfsan_label req_label,dfsan_label rem_label,dfsan_label * ret_label)1890 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req,
1891 struct timespec *rem,
1892 dfsan_label req_label,
1893 dfsan_label rem_label,
1894 dfsan_label *ret_label) {
1895 int ret = nanosleep(req, rem);
1896 *ret_label = 0;
1897 if (ret == -1) {
1898 // Interrupted by a signal, rem is filled with the remaining time.
1899 dfsan_set_label(0, rem, sizeof(struct timespec));
1900 }
1901 return ret;
1902 }
1903
__dfso_nanosleep(const struct timespec * req,struct timespec * rem,dfsan_label req_label,dfsan_label rem_label,dfsan_label * ret_label,dfsan_origin req_origin,dfsan_origin rem_origin,dfsan_origin * ret_origin)1904 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep(
1905 const struct timespec *req, struct timespec *rem, dfsan_label req_label,
1906 dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin,
1907 dfsan_origin rem_origin, dfsan_origin *ret_origin) {
1908 return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label);
1909 }
1910
clear_msghdr_labels(size_t bytes_written,struct msghdr * msg)1911 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) {
1912 dfsan_set_label(0, msg, sizeof(*msg));
1913 dfsan_set_label(0, msg->msg_name, msg->msg_namelen);
1914 dfsan_set_label(0, msg->msg_control, msg->msg_controllen);
1915 for (size_t i = 0; bytes_written > 0; ++i) {
1916 assert(i < msg->msg_iovlen);
1917 struct iovec *iov = &msg->msg_iov[i];
1918 size_t iov_written =
1919 bytes_written < iov->iov_len ? bytes_written : iov->iov_len;
1920 dfsan_set_label(0, iov->iov_base, iov_written);
1921 bytes_written -= iov_written;
1922 }
1923 }
1924
__dfsw_recvmmsg(int sockfd,struct mmsghdr * msgvec,unsigned int vlen,int flags,struct timespec * timeout,dfsan_label sockfd_label,dfsan_label msgvec_label,dfsan_label vlen_label,dfsan_label flags_label,dfsan_label timeout_label,dfsan_label * ret_label)1925 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg(
1926 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
1927 struct timespec *timeout, dfsan_label sockfd_label,
1928 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
1929 dfsan_label timeout_label, dfsan_label *ret_label) {
1930 int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout);
1931 for (int i = 0; i < ret; ++i) {
1932 dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len));
1933 clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr);
1934 }
1935 *ret_label = 0;
1936 return ret;
1937 }
1938
__dfso_recvmmsg(int sockfd,struct mmsghdr * msgvec,unsigned int vlen,int flags,struct timespec * timeout,dfsan_label sockfd_label,dfsan_label msgvec_label,dfsan_label vlen_label,dfsan_label flags_label,dfsan_label timeout_label,dfsan_label * ret_label,dfsan_origin sockfd_origin,dfsan_origin msgvec_origin,dfsan_origin vlen_origin,dfsan_origin flags_origin,dfsan_origin timeout_origin,dfsan_origin * ret_origin)1939 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg(
1940 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
1941 struct timespec *timeout, dfsan_label sockfd_label,
1942 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
1943 dfsan_label timeout_label, dfsan_label *ret_label,
1944 dfsan_origin sockfd_origin, dfsan_origin msgvec_origin,
1945 dfsan_origin vlen_origin, dfsan_origin flags_origin,
1946 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1947 return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label,
1948 msgvec_label, vlen_label, flags_label, timeout_label,
1949 ret_label);
1950 }
1951
__dfsw_recvmsg(int sockfd,struct msghdr * msg,int flags,dfsan_label sockfd_label,dfsan_label msg_label,dfsan_label flags_label,dfsan_label * ret_label)1952 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg(
1953 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
1954 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) {
1955 ssize_t ret = recvmsg(sockfd, msg, flags);
1956 if (ret >= 0)
1957 clear_msghdr_labels(ret, msg);
1958 *ret_label = 0;
1959 return ret;
1960 }
1961
__dfso_recvmsg(int sockfd,struct msghdr * msg,int flags,dfsan_label sockfd_label,dfsan_label msg_label,dfsan_label flags_label,dfsan_label * ret_label,dfsan_origin sockfd_origin,dfsan_origin msg_origin,dfsan_origin flags_origin,dfsan_origin * ret_origin)1962 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg(
1963 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
1964 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label,
1965 dfsan_origin sockfd_origin, dfsan_origin msg_origin,
1966 dfsan_origin flags_origin, dfsan_origin *ret_origin) {
1967 return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label,
1968 flags_label, ret_label);
1969 }
1970
1971 SANITIZER_INTERFACE_ATTRIBUTE int
__dfsw_socketpair(int domain,int type,int protocol,int sv[2],dfsan_label domain_label,dfsan_label type_label,dfsan_label protocol_label,dfsan_label sv_label,dfsan_label * ret_label)1972 __dfsw_socketpair(int domain, int type, int protocol, int sv[2],
1973 dfsan_label domain_label, dfsan_label type_label,
1974 dfsan_label protocol_label, dfsan_label sv_label,
1975 dfsan_label *ret_label) {
1976 int ret = socketpair(domain, type, protocol, sv);
1977 *ret_label = 0;
1978 if (ret == 0) {
1979 dfsan_set_label(0, sv, sizeof(*sv) * 2);
1980 }
1981 return ret;
1982 }
1983
__dfso_socketpair(int domain,int type,int protocol,int sv[2],dfsan_label domain_label,dfsan_label type_label,dfsan_label protocol_label,dfsan_label sv_label,dfsan_label * ret_label,dfsan_origin domain_origin,dfsan_origin type_origin,dfsan_origin protocol_origin,dfsan_origin sv_origin,dfsan_origin * ret_origin)1984 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair(
1985 int domain, int type, int protocol, int sv[2], dfsan_label domain_label,
1986 dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label,
1987 dfsan_label *ret_label, dfsan_origin domain_origin,
1988 dfsan_origin type_origin, dfsan_origin protocol_origin,
1989 dfsan_origin sv_origin, dfsan_origin *ret_origin) {
1990 return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label,
1991 protocol_label, sv_label, ret_label);
1992 }
1993
__dfsw_getsockopt(int sockfd,int level,int optname,void * optval,socklen_t * optlen,dfsan_label sockfd_label,dfsan_label level_label,dfsan_label optname_label,dfsan_label optval_label,dfsan_label optlen_label,dfsan_label * ret_label)1994 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt(
1995 int sockfd, int level, int optname, void *optval, socklen_t *optlen,
1996 dfsan_label sockfd_label, dfsan_label level_label,
1997 dfsan_label optname_label, dfsan_label optval_label,
1998 dfsan_label optlen_label, dfsan_label *ret_label) {
1999 int ret = getsockopt(sockfd, level, optname, optval, optlen);
2000 if (ret != -1 && optval && optlen) {
2001 dfsan_set_label(0, optlen, sizeof(*optlen));
2002 dfsan_set_label(0, optval, *optlen);
2003 }
2004 *ret_label = 0;
2005 return ret;
2006 }
2007
__dfso_getsockopt(int sockfd,int level,int optname,void * optval,socklen_t * optlen,dfsan_label sockfd_label,dfsan_label level_label,dfsan_label optname_label,dfsan_label optval_label,dfsan_label optlen_label,dfsan_label * ret_label,dfsan_origin sockfd_origin,dfsan_origin level_origin,dfsan_origin optname_origin,dfsan_origin optval_origin,dfsan_origin optlen_origin,dfsan_origin * ret_origin)2008 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt(
2009 int sockfd, int level, int optname, void *optval, socklen_t *optlen,
2010 dfsan_label sockfd_label, dfsan_label level_label,
2011 dfsan_label optname_label, dfsan_label optval_label,
2012 dfsan_label optlen_label, dfsan_label *ret_label,
2013 dfsan_origin sockfd_origin, dfsan_origin level_origin,
2014 dfsan_origin optname_origin, dfsan_origin optval_origin,
2015 dfsan_origin optlen_origin, dfsan_origin *ret_origin) {
2016 return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label,
2017 level_label, optname_label, optval_label,
2018 optlen_label, ret_label);
2019 }
2020
__dfsw_getsockname(int sockfd,struct sockaddr * addr,socklen_t * addrlen,dfsan_label sockfd_label,dfsan_label addr_label,dfsan_label addrlen_label,dfsan_label * ret_label)2021 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname(
2022 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2023 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2024 dfsan_label *ret_label) {
2025 socklen_t origlen = addrlen ? *addrlen : 0;
2026 int ret = getsockname(sockfd, addr, addrlen);
2027 if (ret != -1 && addr && addrlen) {
2028 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
2029 dfsan_set_label(0, addrlen, sizeof(*addrlen));
2030 dfsan_set_label(0, addr, written_bytes);
2031 }
2032 *ret_label = 0;
2033 return ret;
2034 }
2035
__dfso_getsockname(int sockfd,struct sockaddr * addr,socklen_t * addrlen,dfsan_label sockfd_label,dfsan_label addr_label,dfsan_label addrlen_label,dfsan_label * ret_label,dfsan_origin sockfd_origin,dfsan_origin addr_origin,dfsan_origin addrlen_origin,dfsan_origin * ret_origin)2036 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname(
2037 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2038 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2039 dfsan_label *ret_label, dfsan_origin sockfd_origin,
2040 dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2041 dfsan_origin *ret_origin) {
2042 return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label,
2043 addrlen_label, ret_label);
2044 }
2045
__dfsw_getpeername(int sockfd,struct sockaddr * addr,socklen_t * addrlen,dfsan_label sockfd_label,dfsan_label addr_label,dfsan_label addrlen_label,dfsan_label * ret_label)2046 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername(
2047 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2048 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2049 dfsan_label *ret_label) {
2050 socklen_t origlen = addrlen ? *addrlen : 0;
2051 int ret = getpeername(sockfd, addr, addrlen);
2052 if (ret != -1 && addr && addrlen) {
2053 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
2054 dfsan_set_label(0, addrlen, sizeof(*addrlen));
2055 dfsan_set_label(0, addr, written_bytes);
2056 }
2057 *ret_label = 0;
2058 return ret;
2059 }
2060
__dfso_getpeername(int sockfd,struct sockaddr * addr,socklen_t * addrlen,dfsan_label sockfd_label,dfsan_label addr_label,dfsan_label addrlen_label,dfsan_label * ret_label,dfsan_origin sockfd_origin,dfsan_origin addr_origin,dfsan_origin addrlen_origin,dfsan_origin * ret_origin)2061 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername(
2062 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2063 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2064 dfsan_label *ret_label, dfsan_origin sockfd_origin,
2065 dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2066 dfsan_origin *ret_origin) {
2067 return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label,
2068 addrlen_label, ret_label);
2069 }
2070
2071 // Type of the trampoline function passed to the custom version of
2072 // dfsan_set_write_callback.
2073 typedef void (*write_trampoline_t)(
2074 void *callback,
2075 int fd, const void *buf, ssize_t count,
2076 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label);
2077
2078 typedef void (*write_origin_trampoline_t)(
2079 void *callback, int fd, const void *buf, ssize_t count,
2080 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label,
2081 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin);
2082
2083 // Calls to dfsan_set_write_callback() set the values in this struct.
2084 // Calls to the custom version of write() read (and invoke) them.
2085 static struct {
2086 write_trampoline_t write_callback_trampoline = nullptr;
2087 void *write_callback = nullptr;
2088 } write_callback_info;
2089
2090 static struct {
2091 write_origin_trampoline_t write_callback_trampoline = nullptr;
2092 void *write_callback = nullptr;
2093 } write_origin_callback_info;
2094
2095 SANITIZER_INTERFACE_ATTRIBUTE void
__dfsw_dfsan_set_write_callback(write_trampoline_t write_callback_trampoline,void * write_callback,dfsan_label write_callback_label,dfsan_label * ret_label)2096 __dfsw_dfsan_set_write_callback(
2097 write_trampoline_t write_callback_trampoline,
2098 void *write_callback,
2099 dfsan_label write_callback_label,
2100 dfsan_label *ret_label) {
2101 write_callback_info.write_callback_trampoline = write_callback_trampoline;
2102 write_callback_info.write_callback = write_callback;
2103 }
2104
__dfso_dfsan_set_write_callback(write_origin_trampoline_t write_callback_trampoline,void * write_callback,dfsan_label write_callback_label,dfsan_label * ret_label,dfsan_origin write_callback_origin,dfsan_origin * ret_origin)2105 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback(
2106 write_origin_trampoline_t write_callback_trampoline, void *write_callback,
2107 dfsan_label write_callback_label, dfsan_label *ret_label,
2108 dfsan_origin write_callback_origin, dfsan_origin *ret_origin) {
2109 write_origin_callback_info.write_callback_trampoline =
2110 write_callback_trampoline;
2111 write_origin_callback_info.write_callback = write_callback;
2112 }
2113
2114 SANITIZER_INTERFACE_ATTRIBUTE int
__dfsw_write(int fd,const void * buf,size_t count,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label * ret_label)2115 __dfsw_write(int fd, const void *buf, size_t count,
2116 dfsan_label fd_label, dfsan_label buf_label,
2117 dfsan_label count_label, dfsan_label *ret_label) {
2118 if (write_callback_info.write_callback) {
2119 write_callback_info.write_callback_trampoline(
2120 write_callback_info.write_callback,
2121 fd, buf, count,
2122 fd_label, buf_label, count_label);
2123 }
2124
2125 *ret_label = 0;
2126 return write(fd, buf, count);
2127 }
2128
__dfso_write(int fd,const void * buf,size_t count,dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,dfsan_label * ret_label,dfsan_origin fd_origin,dfsan_origin buf_origin,dfsan_origin count_origin,dfsan_origin * ret_origin)2129 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write(
2130 int fd, const void *buf, size_t count, dfsan_label fd_label,
2131 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
2132 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
2133 dfsan_origin *ret_origin) {
2134 if (write_origin_callback_info.write_callback) {
2135 write_origin_callback_info.write_callback_trampoline(
2136 write_origin_callback_info.write_callback, fd, buf, count, fd_label,
2137 buf_label, count_label, fd_origin, buf_origin, count_origin);
2138 }
2139
2140 *ret_label = 0;
2141 return write(fd, buf, count);
2142 }
2143 } // namespace __dfsan
2144
2145 // Type used to extract a dfsan_label with va_arg()
2146 typedef int dfsan_label_va;
2147
2148 // Formats a chunk either a constant string or a single format directive (e.g.,
2149 // '%.3f').
2150 struct Formatter {
FormatterFormatter2151 Formatter(char *str_, const char *fmt_, size_t size_)
2152 : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_),
2153 width(-1) {}
2154
formatFormatter2155 int format() {
2156 char *tmp_fmt = build_format_string();
2157 int retval =
2158 snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt,
2159 0 /* used only to avoid warnings */);
2160 free(tmp_fmt);
2161 return retval;
2162 }
2163
formatFormatter2164 template <typename T> int format(T arg) {
2165 char *tmp_fmt = build_format_string();
2166 int retval;
2167 if (width >= 0) {
2168 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2169 tmp_fmt, width, arg);
2170 } else {
2171 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2172 tmp_fmt, arg);
2173 }
2174 free(tmp_fmt);
2175 return retval;
2176 }
2177
build_format_stringFormatter2178 char *build_format_string() {
2179 size_t fmt_size = fmt_cur - fmt_start + 1;
2180 char *new_fmt = (char *)malloc(fmt_size + 1);
2181 assert(new_fmt);
2182 internal_memcpy(new_fmt, fmt_start, fmt_size);
2183 new_fmt[fmt_size] = '\0';
2184 return new_fmt;
2185 }
2186
str_curFormatter2187 char *str_cur() { return str + str_off; }
2188
num_written_bytesFormatter2189 size_t num_written_bytes(int retval) {
2190 if (retval < 0) {
2191 return 0;
2192 }
2193
2194 size_t num_avail = str_off < size ? size - str_off : 0;
2195 if (num_avail == 0) {
2196 return 0;
2197 }
2198
2199 size_t num_written = retval;
2200 // A return value of {v,}snprintf of size or more means that the output was
2201 // truncated.
2202 if (num_written >= num_avail) {
2203 num_written -= num_avail;
2204 }
2205
2206 return num_written;
2207 }
2208
2209 char *str;
2210 size_t str_off;
2211 size_t size;
2212 const char *fmt_start;
2213 const char *fmt_cur;
2214 int width;
2215 };
2216
2217 // Formats the input and propagates the input labels to the output. The output
2218 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and
2219 // 'ap' are the format string and the list of arguments for formatting. Returns
2220 // the return value vsnprintf would return.
2221 //
2222 // The function tokenizes the format string in chunks representing either a
2223 // constant string or a single format directive (e.g., '%.3f') and formats each
2224 // chunk independently into the output string. This approach allows to figure
2225 // out which bytes of the output string depends on which argument and thus to
2226 // propagate labels more precisely.
2227 //
2228 // WARNING: This implementation does not support conversion specifiers with
2229 // positional arguments.
format_buffer(char * str,size_t size,const char * fmt,dfsan_label * va_labels,dfsan_label * ret_label,dfsan_origin * va_origins,dfsan_origin * ret_origin,va_list ap)2230 static int format_buffer(char *str, size_t size, const char *fmt,
2231 dfsan_label *va_labels, dfsan_label *ret_label,
2232 dfsan_origin *va_origins, dfsan_origin *ret_origin,
2233 va_list ap) {
2234 Formatter formatter(str, fmt, size);
2235
2236 while (*formatter.fmt_cur) {
2237 formatter.fmt_start = formatter.fmt_cur;
2238 formatter.width = -1;
2239 int retval = 0;
2240
2241 if (*formatter.fmt_cur != '%') {
2242 // Ordinary character. Consume all the characters until a '%' or the end
2243 // of the string.
2244 for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';
2245 ++formatter.fmt_cur) {}
2246 retval = formatter.format();
2247 dfsan_set_label(0, formatter.str_cur(),
2248 formatter.num_written_bytes(retval));
2249 } else {
2250 // Conversion directive. Consume all the characters until a conversion
2251 // specifier or the end of the string.
2252 bool end_fmt = false;
2253 for (; *formatter.fmt_cur && !end_fmt; ) {
2254 switch (*++formatter.fmt_cur) {
2255 case 'd':
2256 case 'i':
2257 case 'o':
2258 case 'u':
2259 case 'x':
2260 case 'X':
2261 switch (*(formatter.fmt_cur - 1)) {
2262 case 'h':
2263 // Also covers the 'hh' case (since the size of the arg is still
2264 // an int).
2265 retval = formatter.format(va_arg(ap, int));
2266 break;
2267 case 'l':
2268 if (formatter.fmt_cur - formatter.fmt_start >= 2 &&
2269 *(formatter.fmt_cur - 2) == 'l') {
2270 retval = formatter.format(va_arg(ap, long long int));
2271 } else {
2272 retval = formatter.format(va_arg(ap, long int));
2273 }
2274 break;
2275 case 'q':
2276 retval = formatter.format(va_arg(ap, long long int));
2277 break;
2278 case 'j':
2279 retval = formatter.format(va_arg(ap, intmax_t));
2280 break;
2281 case 'z':
2282 case 't':
2283 retval = formatter.format(va_arg(ap, size_t));
2284 break;
2285 default:
2286 retval = formatter.format(va_arg(ap, int));
2287 }
2288 if (va_origins == nullptr)
2289 dfsan_set_label(*va_labels++, formatter.str_cur(),
2290 formatter.num_written_bytes(retval));
2291 else
2292 dfsan_set_label_origin(*va_labels++, *va_origins++,
2293 formatter.str_cur(),
2294 formatter.num_written_bytes(retval));
2295 end_fmt = true;
2296 break;
2297
2298 case 'a':
2299 case 'A':
2300 case 'e':
2301 case 'E':
2302 case 'f':
2303 case 'F':
2304 case 'g':
2305 case 'G':
2306 if (*(formatter.fmt_cur - 1) == 'L') {
2307 retval = formatter.format(va_arg(ap, long double));
2308 } else {
2309 retval = formatter.format(va_arg(ap, double));
2310 }
2311 if (va_origins == nullptr)
2312 dfsan_set_label(*va_labels++, formatter.str_cur(),
2313 formatter.num_written_bytes(retval));
2314 else
2315 dfsan_set_label_origin(*va_labels++, *va_origins++,
2316 formatter.str_cur(),
2317 formatter.num_written_bytes(retval));
2318 end_fmt = true;
2319 break;
2320
2321 case 'c':
2322 retval = formatter.format(va_arg(ap, int));
2323 if (va_origins == nullptr)
2324 dfsan_set_label(*va_labels++, formatter.str_cur(),
2325 formatter.num_written_bytes(retval));
2326 else
2327 dfsan_set_label_origin(*va_labels++, *va_origins++,
2328 formatter.str_cur(),
2329 formatter.num_written_bytes(retval));
2330 end_fmt = true;
2331 break;
2332
2333 case 's': {
2334 char *arg = va_arg(ap, char *);
2335 retval = formatter.format(arg);
2336 if (va_origins) {
2337 va_origins++;
2338 dfsan_mem_origin_transfer(formatter.str_cur(), arg,
2339 formatter.num_written_bytes(retval));
2340 }
2341 va_labels++;
2342 internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg),
2343 sizeof(dfsan_label) *
2344 formatter.num_written_bytes(retval));
2345 end_fmt = true;
2346 break;
2347 }
2348
2349 case 'p':
2350 retval = formatter.format(va_arg(ap, void *));
2351 if (va_origins == nullptr)
2352 dfsan_set_label(*va_labels++, formatter.str_cur(),
2353 formatter.num_written_bytes(retval));
2354 else
2355 dfsan_set_label_origin(*va_labels++, *va_origins++,
2356 formatter.str_cur(),
2357 formatter.num_written_bytes(retval));
2358 end_fmt = true;
2359 break;
2360
2361 case 'n': {
2362 int *ptr = va_arg(ap, int *);
2363 *ptr = (int)formatter.str_off;
2364 va_labels++;
2365 if (va_origins)
2366 va_origins++;
2367 dfsan_set_label(0, ptr, sizeof(ptr));
2368 end_fmt = true;
2369 break;
2370 }
2371
2372 case '%':
2373 retval = formatter.format();
2374 dfsan_set_label(0, formatter.str_cur(),
2375 formatter.num_written_bytes(retval));
2376 end_fmt = true;
2377 break;
2378
2379 case '*':
2380 formatter.width = va_arg(ap, int);
2381 va_labels++;
2382 if (va_origins)
2383 va_origins++;
2384 break;
2385
2386 default:
2387 break;
2388 }
2389 }
2390 }
2391
2392 if (retval < 0) {
2393 return retval;
2394 }
2395
2396 formatter.fmt_cur++;
2397 formatter.str_off += retval;
2398 }
2399
2400 *ret_label = 0;
2401 if (ret_origin)
2402 *ret_origin = 0;
2403
2404 // Number of bytes written in total.
2405 return formatter.str_off;
2406 }
2407
2408 extern "C" {
2409 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sprintf(char * str,const char * format,dfsan_label str_label,dfsan_label format_label,dfsan_label * va_labels,dfsan_label * ret_label,...)2410 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,
2411 dfsan_label format_label, dfsan_label *va_labels,
2412 dfsan_label *ret_label, ...) {
2413 va_list ap;
2414 va_start(ap, ret_label);
2415 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
2416 nullptr, ap);
2417 va_end(ap);
2418 return ret;
2419 }
2420
2421 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sprintf(char * str,const char * format,dfsan_label str_label,dfsan_label format_label,dfsan_label * va_labels,dfsan_label * ret_label,dfsan_origin str_origin,dfsan_origin format_origin,dfsan_origin * va_origins,dfsan_origin * ret_origin,...)2422 int __dfso_sprintf(char *str, const char *format, dfsan_label str_label,
2423 dfsan_label format_label, dfsan_label *va_labels,
2424 dfsan_label *ret_label, dfsan_origin str_origin,
2425 dfsan_origin format_origin, dfsan_origin *va_origins,
2426 dfsan_origin *ret_origin, ...) {
2427 va_list ap;
2428 va_start(ap, ret_origin);
2429 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins,
2430 ret_origin, ap);
2431 va_end(ap);
2432 return ret;
2433 }
2434
2435 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_snprintf(char * str,size_t size,const char * format,dfsan_label str_label,dfsan_label size_label,dfsan_label format_label,dfsan_label * va_labels,dfsan_label * ret_label,...)2436 int __dfsw_snprintf(char *str, size_t size, const char *format,
2437 dfsan_label str_label, dfsan_label size_label,
2438 dfsan_label format_label, dfsan_label *va_labels,
2439 dfsan_label *ret_label, ...) {
2440 va_list ap;
2441 va_start(ap, ret_label);
2442 int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr,
2443 nullptr, ap);
2444 va_end(ap);
2445 return ret;
2446 }
2447
2448 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_snprintf(char * str,size_t size,const char * format,dfsan_label str_label,dfsan_label size_label,dfsan_label format_label,dfsan_label * va_labels,dfsan_label * ret_label,dfsan_origin str_origin,dfsan_origin size_origin,dfsan_origin format_origin,dfsan_origin * va_origins,dfsan_origin * ret_origin,...)2449 int __dfso_snprintf(char *str, size_t size, const char *format,
2450 dfsan_label str_label, dfsan_label size_label,
2451 dfsan_label format_label, dfsan_label *va_labels,
2452 dfsan_label *ret_label, dfsan_origin str_origin,
2453 dfsan_origin size_origin, dfsan_origin format_origin,
2454 dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) {
2455 va_list ap;
2456 va_start(ap, ret_origin);
2457 int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins,
2458 ret_origin, ap);
2459 va_end(ap);
2460 return ret;
2461 }
2462
BeforeFork()2463 static void BeforeFork() {
2464 StackDepotLockAll();
2465 GetChainedOriginDepot()->LockAll();
2466 }
2467
AfterFork()2468 static void AfterFork() {
2469 GetChainedOriginDepot()->UnlockAll();
2470 StackDepotUnlockAll();
2471 }
2472
2473 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_fork(dfsan_label * ret_label)2474 pid_t __dfsw_fork(dfsan_label *ret_label) {
2475 pid_t pid = fork();
2476 *ret_label = 0;
2477 return pid;
2478 }
2479
2480 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_fork(dfsan_label * ret_label,dfsan_origin * ret_origin)2481 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) {
2482 BeforeFork();
2483 pid_t pid = __dfsw_fork(ret_label);
2484 AfterFork();
2485 return pid;
2486 }
2487
2488 // Default empty implementations (weak). Users should redefine them.
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_guard,u32 *)2489 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_guard_init,u32 *,u32 *)2490 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *,
2491 u32 *) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_pcs_init,void)2492 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_indir,void)2493 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
2494
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp,void)2495 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp1,void)2496 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp2,void)2497 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp4,void)2498 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp8,void)2499 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp1,void)2500 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1,
2501 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp2,void)2502 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2,
2503 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp4,void)2504 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4,
2505 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp8,void)2506 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8,
2507 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_switch,void)2508 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {}
2509 } // extern "C"
2510