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_mem_shadow_transfer(dest, src, n);
501 return internal_memcpy(dest, src, n);
502 }
503
dfsan_memcpy_with_origin(void * dest,const void * src,size_t n)504 static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) {
505 dfsan_mem_origin_transfer(dest, src, n);
506 return dfsan_memcpy(dest, src, n);
507 }
508
dfsan_memset(void * s,int c,dfsan_label c_label,size_t n)509 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {
510 internal_memset(s, c, n);
511 dfsan_set_label(c_label, s, n);
512 }
513
dfsan_memset_with_origin(void * s,int c,dfsan_label c_label,dfsan_origin c_origin,size_t n)514 static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label,
515 dfsan_origin c_origin, size_t n) {
516 internal_memset(s, c, n);
517 dfsan_set_label_origin(c_label, c_origin, s, n);
518 }
519
520 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)521 void *__dfsw_memcpy(void *dest, const void *src, size_t n,
522 dfsan_label dest_label, dfsan_label src_label,
523 dfsan_label n_label, dfsan_label *ret_label) {
524 *ret_label = dest_label;
525 return dfsan_memcpy(dest, src, n);
526 }
527
528 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)529 void *__dfso_memcpy(void *dest, const void *src, size_t n,
530 dfsan_label dest_label, dfsan_label src_label,
531 dfsan_label n_label, dfsan_label *ret_label,
532 dfsan_origin dest_origin, dfsan_origin src_origin,
533 dfsan_origin n_origin, dfsan_origin *ret_origin) {
534 *ret_label = dest_label;
535 *ret_origin = dest_origin;
536 return dfsan_memcpy_with_origin(dest, src, n);
537 }
538
539 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)540 void *__dfsw_memmove(void *dest, const void *src, size_t n,
541 dfsan_label dest_label, dfsan_label src_label,
542 dfsan_label n_label, dfsan_label *ret_label) {
543 *ret_label = dest_label;
544 return dfsan_memmove(dest, src, n);
545 }
546
547 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)548 void *__dfso_memmove(void *dest, const void *src, size_t n,
549 dfsan_label dest_label, dfsan_label src_label,
550 dfsan_label n_label, dfsan_label *ret_label,
551 dfsan_origin dest_origin, dfsan_origin src_origin,
552 dfsan_origin n_origin, dfsan_origin *ret_origin) {
553 *ret_label = dest_label;
554 *ret_origin = dest_origin;
555 return dfsan_memmove_with_origin(dest, src, n);
556 }
557
558 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)559 void *__dfsw_memset(void *s, int c, size_t n,
560 dfsan_label s_label, dfsan_label c_label,
561 dfsan_label n_label, dfsan_label *ret_label) {
562 dfsan_memset(s, c, c_label, n);
563 *ret_label = s_label;
564 return s;
565 }
566
567 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)568 void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label,
569 dfsan_label c_label, dfsan_label n_label,
570 dfsan_label *ret_label, dfsan_origin s_origin,
571 dfsan_origin c_origin, dfsan_origin n_origin,
572 dfsan_origin *ret_origin) {
573 dfsan_memset_with_origin(s, c, c_label, c_origin, n);
574 *ret_label = s_label;
575 *ret_origin = s_origin;
576 return s;
577 }
578
__dfsw_strcat(char * dest,const char * src,dfsan_label dest_label,dfsan_label src_label,dfsan_label * ret_label)579 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
580 dfsan_label dest_label,
581 dfsan_label src_label,
582 dfsan_label *ret_label) {
583 size_t dest_len = strlen(dest);
584 char *ret = strcat(dest, src);
585 dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src));
586 *ret_label = dest_label;
587 return ret;
588 }
589
__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)590 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
591 char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label,
592 dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin,
593 dfsan_origin *ret_origin) {
594 size_t dest_len = strlen(dest);
595 char *ret = strcat(dest, src);
596 size_t src_len = strlen(src);
597 dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
598 dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
599 *ret_label = dest_label;
600 *ret_origin = dest_origin;
601 return ret;
602 }
603
604 SANITIZER_INTERFACE_ATTRIBUTE char *
__dfsw_strdup(const char * s,dfsan_label s_label,dfsan_label * ret_label)605 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
606 size_t len = strlen(s);
607 void *p = malloc(len+1);
608 dfsan_memcpy(p, s, len+1);
609 *ret_label = 0;
610 return static_cast<char *>(p);
611 }
612
__dfso_strdup(const char * s,dfsan_label s_label,dfsan_label * ret_label,dfsan_origin s_origin,dfsan_origin * ret_origin)613 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s,
614 dfsan_label s_label,
615 dfsan_label *ret_label,
616 dfsan_origin s_origin,
617 dfsan_origin *ret_origin) {
618 size_t len = strlen(s);
619 void *p = malloc(len + 1);
620 dfsan_memcpy_with_origin(p, s, len + 1);
621 *ret_label = 0;
622 return static_cast<char *>(p);
623 }
624
625 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)626 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
627 dfsan_label s2_label, dfsan_label n_label,
628 dfsan_label *ret_label) {
629 size_t len = strlen(s2);
630 if (len < n) {
631 dfsan_memcpy(s1, s2, len+1);
632 dfsan_memset(s1+len+1, 0, 0, n-len-1);
633 } else {
634 dfsan_memcpy(s1, s2, n);
635 }
636
637 *ret_label = s1_label;
638 return s1;
639 }
640
__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)641 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy(
642 char *s1, const char *s2, size_t n, dfsan_label s1_label,
643 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
644 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
645 dfsan_origin *ret_origin) {
646 size_t len = strlen(s2);
647 if (len < n) {
648 dfsan_memcpy_with_origin(s1, s2, len + 1);
649 dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1);
650 } else {
651 dfsan_memcpy_with_origin(s1, s2, n);
652 }
653
654 *ret_label = s1_label;
655 *ret_origin = s1_origin;
656 return s1;
657 }
658
659 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)660 __dfsw_pread(int fd, void *buf, size_t count, off_t offset,
661 dfsan_label fd_label, dfsan_label buf_label,
662 dfsan_label count_label, dfsan_label offset_label,
663 dfsan_label *ret_label) {
664 ssize_t ret = pread(fd, buf, count, offset);
665 if (ret > 0)
666 dfsan_set_label(0, buf, ret);
667 *ret_label = 0;
668 return ret;
669 }
670
__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)671 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread(
672 int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label,
673 dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label,
674 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
675 dfsan_origin count_origin, dfsan_label offset_origin,
676 dfsan_origin *ret_origin) {
677 return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label,
678 offset_label, ret_label);
679 }
680
681 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)682 __dfsw_read(int fd, void *buf, size_t count,
683 dfsan_label fd_label, dfsan_label buf_label,
684 dfsan_label count_label,
685 dfsan_label *ret_label) {
686 ssize_t ret = read(fd, buf, count);
687 if (ret > 0)
688 dfsan_set_label(0, buf, ret);
689 *ret_label = 0;
690 return ret;
691 }
692
__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)693 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read(
694 int fd, void *buf, size_t count, dfsan_label fd_label,
695 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
696 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
697 dfsan_origin *ret_origin) {
698 return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label,
699 ret_label);
700 }
701
__dfsw_clock_gettime(clockid_t clk_id,struct timespec * tp,dfsan_label clk_id_label,dfsan_label tp_label,dfsan_label * ret_label)702 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
703 struct timespec *tp,
704 dfsan_label clk_id_label,
705 dfsan_label tp_label,
706 dfsan_label *ret_label) {
707 int ret = clock_gettime(clk_id, tp);
708 if (ret == 0)
709 dfsan_set_label(0, tp, sizeof(struct timespec));
710 *ret_label = 0;
711 return ret;
712 }
713
__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)714 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime(
715 clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label,
716 dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin,
717 dfsan_origin tp_origin, dfsan_origin *ret_origin) {
718 return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label);
719 }
720
dfsan_set_zero_label(const void * ptr,uptr size)721 static void dfsan_set_zero_label(const void *ptr, uptr size) {
722 dfsan_set_label(0, const_cast<void *>(ptr), size);
723 }
724
725 // dlopen() ultimately calls mmap() down inside the loader, which generally
726 // doesn't participate in dynamic symbol resolution. Therefore we won't
727 // intercept its calls to mmap, and we have to hook it here.
728 SANITIZER_INTERFACE_ATTRIBUTE void *
__dfsw_dlopen(const char * filename,int flag,dfsan_label filename_label,dfsan_label flag_label,dfsan_label * ret_label)729 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
730 dfsan_label flag_label, dfsan_label *ret_label) {
731 void *handle = dlopen(filename, flag);
732 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
733 if (map)
734 ForEachMappedRegion(map, dfsan_set_zero_label);
735 *ret_label = 0;
736 return handle;
737 }
738
__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)739 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen(
740 const char *filename, int flag, dfsan_label filename_label,
741 dfsan_label flag_label, dfsan_label *ret_label,
742 dfsan_origin filename_origin, dfsan_origin flag_origin,
743 dfsan_origin *ret_origin) {
744 return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label);
745 }
746
DFsanThreadStartFunc(void * arg)747 static void *DFsanThreadStartFunc(void *arg) {
748 DFsanThread *t = (DFsanThread *)arg;
749 SetCurrentThread(t);
750 t->Init();
751 SetSigProcMask(&t->starting_sigset_, nullptr);
752 return t->ThreadStart();
753 }
754
dfsan_pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * start_routine,void * arg,dfsan_label * ret_label,bool track_origins=false)755 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
756 void *start_routine, void *arg,
757 dfsan_label *ret_label,
758 bool track_origins = false) {
759 pthread_attr_t myattr;
760 if (!attr) {
761 pthread_attr_init(&myattr);
762 attr = &myattr;
763 }
764
765 // Ensure that the thread stack is large enough to hold all TLS data.
766 AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr)));
767
768 DFsanThread *t =
769 DFsanThread::Create((thread_callback_t)start_routine, arg, track_origins);
770 ScopedBlockSignals block(&t->starting_sigset_);
771 int res = pthread_create(thread, attr, DFsanThreadStartFunc, t);
772
773 if (attr == &myattr)
774 pthread_attr_destroy(&myattr);
775 *ret_label = 0;
776 return res;
777 }
778
__dfsw_pthread_create(pthread_t * thread,const pthread_attr_t * attr,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)779 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create(
780 pthread_t *thread, const pthread_attr_t *attr, void *start_routine,
781 void *arg, dfsan_label thread_label, dfsan_label attr_label,
782 dfsan_label start_routine_label, dfsan_label arg_label,
783 dfsan_label *ret_label) {
784 return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label);
785 }
786
__dfso_pthread_create(pthread_t * thread,const pthread_attr_t * attr,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)787 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create(
788 pthread_t *thread, const pthread_attr_t *attr, void *start_routine,
789 void *arg, dfsan_label thread_label, dfsan_label attr_label,
790 dfsan_label start_routine_label, dfsan_label arg_label,
791 dfsan_label *ret_label, dfsan_origin thread_origin,
792 dfsan_origin attr_origin, dfsan_origin start_routine_origin,
793 dfsan_origin arg_origin, dfsan_origin *ret_origin) {
794 return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label,
795 true);
796 }
797
__dfsw_pthread_join(pthread_t thread,void ** retval,dfsan_label thread_label,dfsan_label retval_label,dfsan_label * ret_label)798 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread,
799 void **retval,
800 dfsan_label thread_label,
801 dfsan_label retval_label,
802 dfsan_label *ret_label) {
803 int ret = pthread_join(thread, retval);
804 if (ret == 0 && retval)
805 dfsan_set_label(0, retval, sizeof(*retval));
806 *ret_label = 0;
807 return ret;
808 }
809
__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)810 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join(
811 pthread_t thread, void **retval, dfsan_label thread_label,
812 dfsan_label retval_label, dfsan_label *ret_label,
813 dfsan_origin thread_origin, dfsan_origin retval_origin,
814 dfsan_origin *ret_origin) {
815 return __dfsw_pthread_join(thread, retval, thread_label, retval_label,
816 ret_label);
817 }
818
819 struct dl_iterate_phdr_info {
820 int (*callback)(struct dl_phdr_info *info, size_t size, void *data);
821 void *data;
822 };
823
dl_iterate_phdr_cb(struct dl_phdr_info * info,size_t size,void * data)824 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
825 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;
826 dfsan_set_label(0, *info);
827 dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
828 strlen(info->dlpi_name) + 1);
829 dfsan_set_label(
830 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
831 sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
832
833 dfsan_clear_thread_local_state();
834 return dipi->callback(info, size, dipi->data);
835 }
836
__dfsw_dl_iterate_phdr(int (* callback)(struct dl_phdr_info * info,size_t size,void * data),void * data,dfsan_label callback_label,dfsan_label data_label,dfsan_label * ret_label)837 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
838 int (*callback)(struct dl_phdr_info *info, size_t size, void *data),
839 void *data, dfsan_label callback_label, dfsan_label data_label,
840 dfsan_label *ret_label) {
841 dl_iterate_phdr_info dipi = {callback, data};
842 *ret_label = 0;
843 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
844 }
845
__dfso_dl_iterate_phdr(int (* callback)(struct dl_phdr_info * info,size_t size,void * data),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)846 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr(
847 int (*callback)(struct dl_phdr_info *info, size_t size, void *data),
848 void *data, dfsan_label callback_label, dfsan_label data_label,
849 dfsan_label *ret_label, dfsan_origin callback_origin,
850 dfsan_origin data_origin, dfsan_origin *ret_origin) {
851 dl_iterate_phdr_info dipi = {callback, data};
852 *ret_label = 0;
853 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
854 }
855
856 // This function is only available for glibc 2.27 or newer. Mark it weak so
857 // linking succeeds with older glibcs.
858 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep,
859 size_t *alignp);
860
__dfsw__dl_get_tls_static_info(size_t * sizep,size_t * alignp,dfsan_label sizep_label,dfsan_label alignp_label)861 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info(
862 size_t *sizep, size_t *alignp, dfsan_label sizep_label,
863 dfsan_label alignp_label) {
864 assert(_dl_get_tls_static_info);
865 _dl_get_tls_static_info(sizep, alignp);
866 dfsan_set_label(0, sizep, sizeof(*sizep));
867 dfsan_set_label(0, alignp, sizeof(*alignp));
868 }
869
__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)870 SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info(
871 size_t *sizep, size_t *alignp, dfsan_label sizep_label,
872 dfsan_label alignp_label, dfsan_origin sizep_origin,
873 dfsan_origin alignp_origin) {
874 __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label);
875 }
876
877 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_ctime_r(const time_t * timep,char * buf,dfsan_label timep_label,dfsan_label buf_label,dfsan_label * ret_label)878 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
879 dfsan_label buf_label, dfsan_label *ret_label) {
880 char *ret = ctime_r(timep, buf);
881 if (ret) {
882 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf,
883 strlen(buf) + 1);
884 *ret_label = buf_label;
885 } else {
886 *ret_label = 0;
887 }
888 return ret;
889 }
890
891 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)892 char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
893 dfsan_label buf_label, dfsan_label *ret_label,
894 dfsan_origin timep_origin, dfsan_origin buf_origin,
895 dfsan_origin *ret_origin) {
896 char *ret = ctime_r(timep, buf);
897 if (ret) {
898 dfsan_set_label_origin(
899 dfsan_read_label(timep, sizeof(time_t)),
900 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf,
901 strlen(buf) + 1);
902 *ret_label = buf_label;
903 *ret_origin = buf_origin;
904 } else {
905 *ret_label = 0;
906 }
907 return ret;
908 }
909
910 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)911 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
912 dfsan_label size_label, dfsan_label stream_label,
913 dfsan_label *ret_label) {
914 char *ret = fgets(s, size, stream);
915 if (ret) {
916 dfsan_set_label(0, ret, strlen(ret) + 1);
917 *ret_label = s_label;
918 } else {
919 *ret_label = 0;
920 }
921 return ret;
922 }
923
924 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)925 char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
926 dfsan_label size_label, dfsan_label stream_label,
927 dfsan_label *ret_label, dfsan_origin s_origin,
928 dfsan_origin size_origin, dfsan_origin stream_origin,
929 dfsan_origin *ret_origin) {
930 char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label,
931 ret_label);
932 if (ret)
933 *ret_origin = s_origin;
934 return ret;
935 }
936
937 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getcwd(char * buf,size_t size,dfsan_label buf_label,dfsan_label size_label,dfsan_label * ret_label)938 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label,
939 dfsan_label size_label, dfsan_label *ret_label) {
940 char *ret = getcwd(buf, size);
941 if (ret) {
942 dfsan_set_label(0, ret, strlen(ret) + 1);
943 *ret_label = buf_label;
944 } else {
945 *ret_label = 0;
946 }
947 return ret;
948 }
949
950 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)951 char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label,
952 dfsan_label size_label, dfsan_label *ret_label,
953 dfsan_origin buf_origin, dfsan_origin size_origin,
954 dfsan_origin *ret_origin) {
955 char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label);
956 if (ret)
957 *ret_origin = buf_origin;
958 return ret;
959 }
960
961 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_get_current_dir_name(dfsan_label * ret_label)962 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) {
963 char *ret = get_current_dir_name();
964 if (ret)
965 dfsan_set_label(0, ret, strlen(ret) + 1);
966 *ret_label = 0;
967 return ret;
968 }
969
970 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_get_current_dir_name(dfsan_label * ret_label,dfsan_origin * ret_origin)971 char *__dfso_get_current_dir_name(dfsan_label *ret_label,
972 dfsan_origin *ret_origin) {
973 return __dfsw_get_current_dir_name(ret_label);
974 }
975
976 // This function is only available for glibc 2.25 or newer. Mark it weak so
977 // linking succeeds with older glibcs.
978 SANITIZER_WEAK_ATTRIBUTE int getentropy(void *buffer, size_t length);
979
__dfsw_getentropy(void * buffer,size_t length,dfsan_label buffer_label,dfsan_label length_label,dfsan_label * ret_label)980 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getentropy(void *buffer, size_t length,
981 dfsan_label buffer_label,
982 dfsan_label length_label,
983 dfsan_label *ret_label) {
984 int ret = getentropy(buffer, length);
985 if (ret == 0) {
986 dfsan_set_label(0, buffer, length);
987 }
988 *ret_label = 0;
989 return ret;
990 }
991
__dfso_getentropy(void * buffer,size_t length,dfsan_label buffer_label,dfsan_label length_label,dfsan_label * ret_label,dfsan_origin buffer_origin,dfsan_origin length_origin,dfsan_origin * ret_origin)992 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getentropy(void *buffer, size_t length,
993 dfsan_label buffer_label,
994 dfsan_label length_label,
995 dfsan_label *ret_label,
996 dfsan_origin buffer_origin,
997 dfsan_origin length_origin,
998 dfsan_origin *ret_origin) {
999 return __dfsw_getentropy(buffer, length, buffer_label, length_label,
1000 ret_label);
1001 }
1002
1003 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_gethostname(char * name,size_t len,dfsan_label name_label,dfsan_label len_label,dfsan_label * ret_label)1004 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label,
1005 dfsan_label len_label, dfsan_label *ret_label) {
1006 int ret = gethostname(name, len);
1007 if (ret == 0) {
1008 dfsan_set_label(0, name, strlen(name) + 1);
1009 }
1010 *ret_label = 0;
1011 return ret;
1012 }
1013
1014 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)1015 int __dfso_gethostname(char *name, size_t len, dfsan_label name_label,
1016 dfsan_label len_label, dfsan_label *ret_label,
1017 dfsan_origin name_origin, dfsan_origin len_origin,
1018 dfsan_label *ret_origin) {
1019 return __dfsw_gethostname(name, len, name_label, len_label, ret_label);
1020 }
1021
1022 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getrlimit(int resource,struct rlimit * rlim,dfsan_label resource_label,dfsan_label rlim_label,dfsan_label * ret_label)1023 int __dfsw_getrlimit(int resource, struct rlimit *rlim,
1024 dfsan_label resource_label, dfsan_label rlim_label,
1025 dfsan_label *ret_label) {
1026 int ret = getrlimit(resource, rlim);
1027 if (ret == 0) {
1028 dfsan_set_label(0, rlim, sizeof(struct rlimit));
1029 }
1030 *ret_label = 0;
1031 return ret;
1032 }
1033
1034 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)1035 int __dfso_getrlimit(int resource, struct rlimit *rlim,
1036 dfsan_label resource_label, dfsan_label rlim_label,
1037 dfsan_label *ret_label, dfsan_origin resource_origin,
1038 dfsan_origin rlim_origin, dfsan_origin *ret_origin) {
1039 return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label,
1040 ret_label);
1041 }
1042
1043 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_getrusage(int who,struct rusage * usage,dfsan_label who_label,dfsan_label usage_label,dfsan_label * ret_label)1044 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1045 dfsan_label usage_label, dfsan_label *ret_label) {
1046 int ret = getrusage(who, usage);
1047 if (ret == 0) {
1048 dfsan_set_label(0, usage, sizeof(struct rusage));
1049 }
1050 *ret_label = 0;
1051 return ret;
1052 }
1053
1054 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)1055 int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1056 dfsan_label usage_label, dfsan_label *ret_label,
1057 dfsan_origin who_origin, dfsan_origin usage_origin,
1058 dfsan_label *ret_origin) {
1059 return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label);
1060 }
1061
1062 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strcpy(char * dest,const char * src,dfsan_label dst_label,dfsan_label src_label,dfsan_label * ret_label)1063 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label,
1064 dfsan_label src_label, dfsan_label *ret_label) {
1065 char *ret = strcpy(dest, src);
1066 if (ret) {
1067 dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1);
1068 }
1069 *ret_label = dst_label;
1070 return ret;
1071 }
1072
1073 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)1074 char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label,
1075 dfsan_label src_label, dfsan_label *ret_label,
1076 dfsan_origin dst_origin, dfsan_origin src_origin,
1077 dfsan_origin *ret_origin) {
1078 char *ret = strcpy(dest, src);
1079 if (ret) {
1080 size_t str_len = strlen(src) + 1;
1081 dfsan_mem_origin_transfer(dest, src, str_len);
1082 dfsan_mem_shadow_transfer(dest, src, str_len);
1083 }
1084 *ret_label = dst_label;
1085 *ret_origin = dst_origin;
1086 return ret;
1087 }
1088
dfsan_strtol(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1089 static long int dfsan_strtol(const char *nptr, char **endptr, int base,
1090 char **tmp_endptr) {
1091 assert(tmp_endptr);
1092 long int ret = strtol(nptr, tmp_endptr, base);
1093 if (endptr)
1094 *endptr = *tmp_endptr;
1095 return ret;
1096 }
1097
dfsan_strtolong_label(const char * nptr,const char * tmp_endptr,dfsan_label base_label,dfsan_label * ret_label)1098 static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr,
1099 dfsan_label base_label,
1100 dfsan_label *ret_label) {
1101 if (tmp_endptr > nptr) {
1102 // If *tmp_endptr is '\0' include its label as well.
1103 *ret_label = dfsan_union(
1104 base_label,
1105 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));
1106 } else {
1107 *ret_label = 0;
1108 }
1109 }
1110
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)1111 static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr,
1112 dfsan_label base_label,
1113 dfsan_label *ret_label,
1114 dfsan_origin base_origin,
1115 dfsan_origin *ret_origin) {
1116 if (tmp_endptr > nptr) {
1117 // When multiple inputs are tainted, we propagate one of its origins.
1118 // Because checking if base_label is tainted does not need additional
1119 // computation, we prefer to propagating base_origin.
1120 *ret_origin = base_label
1121 ? base_origin
1122 : dfsan_read_origin_of_first_taint(
1123 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1124 }
1125 }
1126
1127 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)1128 long int __dfsw_strtol(const char *nptr, char **endptr, int base,
1129 dfsan_label nptr_label, dfsan_label endptr_label,
1130 dfsan_label base_label, dfsan_label *ret_label) {
1131 char *tmp_endptr;
1132 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1133 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1134 return ret;
1135 }
1136
1137 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)1138 long int __dfso_strtol(const char *nptr, char **endptr, int base,
1139 dfsan_label nptr_label, dfsan_label endptr_label,
1140 dfsan_label base_label, dfsan_label *ret_label,
1141 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1142 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1143 char *tmp_endptr;
1144 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1145 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1146 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1147 ret_origin);
1148 return ret;
1149 }
1150
dfsan_strtod(const char * nptr,char ** endptr,char ** tmp_endptr)1151 static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) {
1152 assert(tmp_endptr);
1153 double ret = strtod(nptr, tmp_endptr);
1154 if (endptr)
1155 *endptr = *tmp_endptr;
1156 return ret;
1157 }
1158
dfsan_strtod_label(const char * nptr,const char * tmp_endptr,dfsan_label * ret_label)1159 static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr,
1160 dfsan_label *ret_label) {
1161 if (tmp_endptr > nptr) {
1162 // If *tmp_endptr is '\0' include its label as well.
1163 *ret_label = dfsan_read_label(
1164 nptr,
1165 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1166 } else {
1167 *ret_label = 0;
1168 }
1169 }
1170
1171 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_strtod(const char * nptr,char ** endptr,dfsan_label nptr_label,dfsan_label endptr_label,dfsan_label * ret_label)1172 double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1173 dfsan_label endptr_label, dfsan_label *ret_label) {
1174 char *tmp_endptr;
1175 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1176 dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1177 return ret;
1178 }
1179
1180 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)1181 double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1182 dfsan_label endptr_label, dfsan_label *ret_label,
1183 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1184 dfsan_origin *ret_origin) {
1185 char *tmp_endptr;
1186 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1187 dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1188 if (tmp_endptr > nptr) {
1189 // If *tmp_endptr is '\0' include its label as well.
1190 *ret_origin = dfsan_read_origin_of_first_taint(
1191 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1192 } else {
1193 *ret_origin = 0;
1194 }
1195 return ret;
1196 }
1197
dfsan_strtoll(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1198 static long long int dfsan_strtoll(const char *nptr, char **endptr, int base,
1199 char **tmp_endptr) {
1200 assert(tmp_endptr);
1201 long long int ret = strtoll(nptr, tmp_endptr, base);
1202 if (endptr)
1203 *endptr = *tmp_endptr;
1204 return ret;
1205 }
1206
1207 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)1208 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base,
1209 dfsan_label nptr_label, dfsan_label endptr_label,
1210 dfsan_label base_label, dfsan_label *ret_label) {
1211 char *tmp_endptr;
1212 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1213 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1214 return ret;
1215 }
1216
1217 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)1218 long long int __dfso_strtoll(const char *nptr, char **endptr, int base,
1219 dfsan_label nptr_label, dfsan_label endptr_label,
1220 dfsan_label base_label, dfsan_label *ret_label,
1221 dfsan_origin nptr_origin,
1222 dfsan_origin endptr_origin,
1223 dfsan_origin base_origin,
1224 dfsan_origin *ret_origin) {
1225 char *tmp_endptr;
1226 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1227 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1228 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1229 ret_origin);
1230 return ret;
1231 }
1232
dfsan_strtoul(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1233 static unsigned long int dfsan_strtoul(const char *nptr, char **endptr,
1234 int base, char **tmp_endptr) {
1235 assert(tmp_endptr);
1236 unsigned long int ret = strtoul(nptr, tmp_endptr, base);
1237 if (endptr)
1238 *endptr = *tmp_endptr;
1239 return ret;
1240 }
1241
1242 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)1243 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base,
1244 dfsan_label nptr_label, dfsan_label endptr_label,
1245 dfsan_label base_label, dfsan_label *ret_label) {
1246 char *tmp_endptr;
1247 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1248 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1249 return ret;
1250 }
1251
1252 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)1253 unsigned long int __dfso_strtoul(
1254 const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1255 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1256 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1257 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1258 char *tmp_endptr;
1259 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1260 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1261 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1262 ret_origin);
1263 return ret;
1264 }
1265
dfsan_strtoull(const char * nptr,char ** endptr,int base,char ** tmp_endptr)1266 static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr,
1267 int base, char **tmp_endptr) {
1268 assert(tmp_endptr);
1269 long long unsigned int ret = strtoull(nptr, tmp_endptr, base);
1270 if (endptr)
1271 *endptr = *tmp_endptr;
1272 return ret;
1273 }
1274
1275 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)1276 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr,
1277 int base, dfsan_label nptr_label,
1278 dfsan_label endptr_label,
1279 dfsan_label base_label,
1280 dfsan_label *ret_label) {
1281 char *tmp_endptr;
1282 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1283 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1284 return ret;
1285 }
1286
1287 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)1288 long long unsigned int __dfso_strtoull(
1289 const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1290 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1291 dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1292 dfsan_origin base_origin, dfsan_origin *ret_origin) {
1293 char *tmp_endptr;
1294 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1295 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1296 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1297 ret_origin);
1298 return ret;
1299 }
1300
1301 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_time(time_t * t,dfsan_label t_label,dfsan_label * ret_label)1302 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) {
1303 time_t ret = time(t);
1304 if (ret != (time_t) -1 && t) {
1305 dfsan_set_label(0, t, sizeof(time_t));
1306 }
1307 *ret_label = 0;
1308 return ret;
1309 }
1310
1311 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_time(time_t * t,dfsan_label t_label,dfsan_label * ret_label,dfsan_origin t_origin,dfsan_origin * ret_origin)1312 time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label,
1313 dfsan_origin t_origin, dfsan_origin *ret_origin) {
1314 return __dfsw_time(t, t_label, ret_label);
1315 }
1316
1317 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)1318 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1319 dfsan_label src_label, dfsan_label dst_label,
1320 dfsan_label *ret_label) {
1321 int ret = inet_pton(af, src, dst);
1322 if (ret == 1) {
1323 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst,
1324 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1325 }
1326 *ret_label = 0;
1327 return ret;
1328 }
1329
1330 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)1331 int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1332 dfsan_label src_label, dfsan_label dst_label,
1333 dfsan_label *ret_label, dfsan_origin af_origin,
1334 dfsan_origin src_origin, dfsan_origin dst_origin,
1335 dfsan_origin *ret_origin) {
1336 int ret = inet_pton(af, src, dst);
1337 if (ret == 1) {
1338 int src_len = strlen(src) + 1;
1339 dfsan_set_label_origin(
1340 dfsan_read_label(src, src_len),
1341 dfsan_read_origin_of_first_taint(src, src_len), dst,
1342 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1343 }
1344 *ret_label = 0;
1345 return ret;
1346 }
1347
1348 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)1349 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result,
1350 dfsan_label timep_label, dfsan_label result_label,
1351 dfsan_label *ret_label) {
1352 struct tm *ret = localtime_r(timep, result);
1353 if (ret) {
1354 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result,
1355 sizeof(struct tm));
1356 *ret_label = result_label;
1357 } else {
1358 *ret_label = 0;
1359 }
1360 return ret;
1361 }
1362
1363 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)1364 struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result,
1365 dfsan_label timep_label, dfsan_label result_label,
1366 dfsan_label *ret_label, dfsan_origin timep_origin,
1367 dfsan_origin result_origin,
1368 dfsan_origin *ret_origin) {
1369 struct tm *ret = localtime_r(timep, result);
1370 if (ret) {
1371 dfsan_set_label_origin(
1372 dfsan_read_label(timep, sizeof(time_t)),
1373 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result,
1374 sizeof(struct tm));
1375 *ret_label = result_label;
1376 *ret_origin = result_origin;
1377 } else {
1378 *ret_label = 0;
1379 }
1380 return ret;
1381 }
1382
1383 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)1384 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,
1385 char *buf, size_t buflen, struct passwd **result,
1386 dfsan_label uid_label, dfsan_label pwd_label,
1387 dfsan_label buf_label, dfsan_label buflen_label,
1388 dfsan_label result_label, dfsan_label *ret_label) {
1389 // Store the data in pwd, the strings referenced from pwd in buf, and the
1390 // address of pwd in *result. On failure, NULL is stored in *result.
1391 int ret = getpwuid_r(uid, pwd, buf, buflen, result);
1392 if (ret == 0) {
1393 dfsan_set_label(0, pwd, sizeof(struct passwd));
1394 dfsan_set_label(0, buf, strlen(buf) + 1);
1395 }
1396 *ret_label = 0;
1397 dfsan_set_label(0, result, sizeof(struct passwd*));
1398 return ret;
1399 }
1400
1401 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)1402 int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen,
1403 struct passwd **result, dfsan_label uid_label,
1404 dfsan_label pwd_label, dfsan_label buf_label,
1405 dfsan_label buflen_label, dfsan_label result_label,
1406 dfsan_label *ret_label, dfsan_origin uid_origin,
1407 dfsan_origin pwd_origin, dfsan_origin buf_origin,
1408 dfsan_origin buflen_origin, dfsan_origin result_origin,
1409 dfsan_origin *ret_origin) {
1410 return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label,
1411 buf_label, buflen_label, result_label, ret_label);
1412 }
1413
1414 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)1415 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1416 int timeout, dfsan_label epfd_label,
1417 dfsan_label events_label, dfsan_label maxevents_label,
1418 dfsan_label timeout_label, dfsan_label *ret_label) {
1419 int ret = epoll_wait(epfd, events, maxevents, timeout);
1420 if (ret > 0)
1421 dfsan_set_label(0, events, ret * sizeof(*events));
1422 *ret_label = 0;
1423 return ret;
1424 }
1425
1426 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)1427 int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1428 int timeout, dfsan_label epfd_label,
1429 dfsan_label events_label, dfsan_label maxevents_label,
1430 dfsan_label timeout_label, dfsan_label *ret_label,
1431 dfsan_origin epfd_origin, dfsan_origin events_origin,
1432 dfsan_origin maxevents_origin,
1433 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1434 return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label,
1435 events_label, maxevents_label, timeout_label,
1436 ret_label);
1437 }
1438
1439 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)1440 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1441 dfsan_label dfs_label, dfsan_label nfds_label,
1442 dfsan_label timeout_label, dfsan_label *ret_label) {
1443 int ret = poll(fds, nfds, timeout);
1444 if (ret >= 0) {
1445 for (; nfds > 0; --nfds) {
1446 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents));
1447 }
1448 }
1449 *ret_label = 0;
1450 return ret;
1451 }
1452
1453 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)1454 int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1455 dfsan_label dfs_label, dfsan_label nfds_label,
1456 dfsan_label timeout_label, dfsan_label *ret_label,
1457 dfsan_origin dfs_origin, dfsan_origin nfds_origin,
1458 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1459 return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label,
1460 ret_label);
1461 }
1462
1463 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)1464 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds,
1465 fd_set *exceptfds, struct timeval *timeout,
1466 dfsan_label nfds_label, dfsan_label readfds_label,
1467 dfsan_label writefds_label, dfsan_label exceptfds_label,
1468 dfsan_label timeout_label, dfsan_label *ret_label) {
1469 int ret = select(nfds, readfds, writefds, exceptfds, timeout);
1470 // Clear everything (also on error) since their content is either set or
1471 // undefined.
1472 if (readfds) {
1473 dfsan_set_label(0, readfds, sizeof(fd_set));
1474 }
1475 if (writefds) {
1476 dfsan_set_label(0, writefds, sizeof(fd_set));
1477 }
1478 if (exceptfds) {
1479 dfsan_set_label(0, exceptfds, sizeof(fd_set));
1480 }
1481 dfsan_set_label(0, timeout, sizeof(struct timeval));
1482 *ret_label = 0;
1483 return ret;
1484 }
1485
1486 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)1487 int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds,
1488 fd_set *exceptfds, struct timeval *timeout,
1489 dfsan_label nfds_label, dfsan_label readfds_label,
1490 dfsan_label writefds_label, dfsan_label exceptfds_label,
1491 dfsan_label timeout_label, dfsan_label *ret_label,
1492 dfsan_origin nfds_origin, dfsan_origin readfds_origin,
1493 dfsan_origin writefds_origin, dfsan_origin exceptfds_origin,
1494 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1495 return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label,
1496 readfds_label, writefds_label, exceptfds_label,
1497 timeout_label, ret_label);
1498 }
1499
1500 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)1501 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1502 dfsan_label pid_label,
1503 dfsan_label cpusetsize_label,
1504 dfsan_label mask_label, dfsan_label *ret_label) {
1505 int ret = sched_getaffinity(pid, cpusetsize, mask);
1506 if (ret == 0) {
1507 dfsan_set_label(0, mask, cpusetsize);
1508 }
1509 *ret_label = 0;
1510 return ret;
1511 }
1512
1513 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)1514 int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1515 dfsan_label pid_label,
1516 dfsan_label cpusetsize_label,
1517 dfsan_label mask_label, dfsan_label *ret_label,
1518 dfsan_origin pid_origin,
1519 dfsan_origin cpusetsize_origin,
1520 dfsan_origin mask_origin,
1521 dfsan_origin *ret_origin) {
1522 return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label,
1523 cpusetsize_label, mask_label, ret_label);
1524 }
1525
1526 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_sigemptyset(sigset_t * set,dfsan_label set_label,dfsan_label * ret_label)1527 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label,
1528 dfsan_label *ret_label) {
1529 int ret = sigemptyset(set);
1530 dfsan_set_label(0, set, sizeof(sigset_t));
1531 *ret_label = 0;
1532 return ret;
1533 }
1534
1535 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_sigemptyset(sigset_t * set,dfsan_label set_label,dfsan_label * ret_label,dfsan_origin set_origin,dfsan_origin * ret_origin)1536 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label,
1537 dfsan_label *ret_label, dfsan_origin set_origin,
1538 dfsan_origin *ret_origin) {
1539 return __dfsw_sigemptyset(set, set_label, ret_label);
1540 }
1541
1542 class SignalHandlerScope {
1543 public:
SignalHandlerScope()1544 SignalHandlerScope() {
1545 if (DFsanThread *t = GetCurrentThread())
1546 t->EnterSignalHandler();
1547 }
~SignalHandlerScope()1548 ~SignalHandlerScope() {
1549 if (DFsanThread *t = GetCurrentThread())
1550 t->LeaveSignalHandler();
1551 }
1552 };
1553
1554 // Clear DFSan runtime TLS state at the end of a scope.
1555 //
1556 // Implementation must be async-signal-safe and use small data size, because
1557 // instances of this class may live on the signal handler stack.
1558 //
1559 // DFSan uses TLS to pass metadata of arguments and return values. When an
1560 // instrumented function accesses the TLS, if a signal callback happens, and the
1561 // callback calls other instrumented functions with updating the same TLS, the
1562 // TLS is in an inconsistent state after the callback ends. This may cause
1563 // either under-tainting or over-tainting.
1564 //
1565 // The current implementation simply resets TLS at restore. This prevents from
1566 // over-tainting. Although under-tainting may still happen, a taint flow can be
1567 // found eventually if we run a DFSan-instrumented program multiple times. The
1568 // alternative option is saving the entire TLS. However the TLS storage takes
1569 // 2k bytes, and signal calls could be nested. So it does not seem worth.
1570 class ScopedClearThreadLocalState {
1571 public:
ScopedClearThreadLocalState()1572 ScopedClearThreadLocalState() {}
~ScopedClearThreadLocalState()1573 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); }
1574 };
1575
1576 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls.
1577 const int kMaxSignals = 1024;
1578 static atomic_uintptr_t sigactions[kMaxSignals];
1579
SignalHandler(int signo)1580 static void SignalHandler(int signo) {
1581 SignalHandlerScope signal_handler_scope;
1582 ScopedClearThreadLocalState scoped_clear_tls;
1583
1584 // Clear shadows for all inputs provided by system.
1585 dfsan_clear_arg_tls(0, sizeof(dfsan_label));
1586
1587 typedef void (*signal_cb)(int x);
1588 signal_cb cb =
1589 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1590 cb(signo);
1591 }
1592
SignalAction(int signo,siginfo_t * si,void * uc)1593 static void SignalAction(int signo, siginfo_t *si, void *uc) {
1594 SignalHandlerScope signal_handler_scope;
1595 ScopedClearThreadLocalState scoped_clear_tls;
1596
1597 // Clear shadows for all inputs provided by system. Similar to SignalHandler.
1598 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label));
1599 dfsan_set_label(0, si, sizeof(*si));
1600 dfsan_set_label(0, uc, sizeof(ucontext_t));
1601
1602 typedef void (*sigaction_cb)(int, siginfo_t *, void *);
1603 sigaction_cb cb =
1604 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1605 cb(signo, si, uc);
1606 }
1607
1608 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)1609 int __dfsw_sigaction(int signum, const struct sigaction *act,
1610 struct sigaction *oldact, dfsan_label signum_label,
1611 dfsan_label act_label, dfsan_label oldact_label,
1612 dfsan_label *ret_label) {
1613 CHECK_LT(signum, kMaxSignals);
1614 SignalSpinLocker lock;
1615 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1616 struct sigaction new_act;
1617 struct sigaction *pnew_act = act ? &new_act : nullptr;
1618 if (act) {
1619 internal_memcpy(pnew_act, act, sizeof(struct sigaction));
1620 if (pnew_act->sa_flags & SA_SIGINFO) {
1621 uptr cb = (uptr)(pnew_act->sa_sigaction);
1622 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1623 atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1624 pnew_act->sa_sigaction = SignalAction;
1625 }
1626 } else {
1627 uptr cb = (uptr)(pnew_act->sa_handler);
1628 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1629 atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1630 pnew_act->sa_handler = SignalHandler;
1631 }
1632 }
1633 }
1634
1635 int ret = sigaction(signum, pnew_act, oldact);
1636
1637 if (ret == 0 && oldact) {
1638 if (oldact->sa_flags & SA_SIGINFO) {
1639 if (oldact->sa_sigaction == SignalAction)
1640 oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb;
1641 } else {
1642 if (oldact->sa_handler == SignalHandler)
1643 oldact->sa_handler = (decltype(oldact->sa_handler))old_cb;
1644 }
1645 }
1646
1647 if (oldact) {
1648 dfsan_set_label(0, oldact, sizeof(struct sigaction));
1649 }
1650 *ret_label = 0;
1651 return ret;
1652 }
1653
1654 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)1655 int __dfso_sigaction(int signum, const struct sigaction *act,
1656 struct sigaction *oldact, dfsan_label signum_label,
1657 dfsan_label act_label, dfsan_label oldact_label,
1658 dfsan_label *ret_label, dfsan_origin signum_origin,
1659 dfsan_origin act_origin, dfsan_origin oldact_origin,
1660 dfsan_origin *ret_origin) {
1661 return __dfsw_sigaction(signum, act, oldact, signum_label, act_label,
1662 oldact_label, ret_label);
1663 }
1664
dfsan_signal(int signum,sighandler_t handler,dfsan_label * ret_label)1665 static sighandler_t dfsan_signal(int signum, sighandler_t handler,
1666 dfsan_label *ret_label) {
1667 CHECK_LT(signum, kMaxSignals);
1668 SignalSpinLocker lock;
1669 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1670 if (handler != SIG_IGN && handler != SIG_DFL) {
1671 atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed);
1672 handler = &SignalHandler;
1673 }
1674
1675 sighandler_t ret = signal(signum, handler);
1676
1677 if (ret == SignalHandler)
1678 ret = (sighandler_t)old_cb;
1679
1680 *ret_label = 0;
1681 return ret;
1682 }
1683
1684 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_signal(int signum,sighandler_t handler,dfsan_label signum_label,dfsan_label handler_label,dfsan_label * ret_label)1685 sighandler_t __dfsw_signal(int signum, sighandler_t handler,
1686 dfsan_label signum_label, dfsan_label handler_label,
1687 dfsan_label *ret_label) {
1688 return dfsan_signal(signum, handler, ret_label);
1689 }
1690
1691 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_signal(int signum,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)1692 sighandler_t __dfso_signal(int signum, sighandler_t handler,
1693 dfsan_label signum_label, dfsan_label handler_label,
1694 dfsan_label *ret_label, dfsan_origin signum_origin,
1695 dfsan_origin handler_origin,
1696 dfsan_origin *ret_origin) {
1697 return dfsan_signal(signum, handler, ret_label);
1698 }
1699
1700 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)1701 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1702 dfsan_label old_ss_label, dfsan_label *ret_label) {
1703 int ret = sigaltstack(ss, old_ss);
1704 if (ret != -1 && old_ss)
1705 dfsan_set_label(0, old_ss, sizeof(*old_ss));
1706 *ret_label = 0;
1707 return ret;
1708 }
1709
1710 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)1711 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1712 dfsan_label old_ss_label, dfsan_label *ret_label,
1713 dfsan_origin ss_origin, dfsan_origin old_ss_origin,
1714 dfsan_origin *ret_origin) {
1715 return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label);
1716 }
1717
1718 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_gettimeofday(struct timeval * tv,struct timezone * tz,dfsan_label tv_label,dfsan_label tz_label,dfsan_label * ret_label)1719 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz,
1720 dfsan_label tv_label, dfsan_label tz_label,
1721 dfsan_label *ret_label) {
1722 int ret = gettimeofday(tv, tz);
1723 if (tv) {
1724 dfsan_set_label(0, tv, sizeof(struct timeval));
1725 }
1726 if (tz) {
1727 dfsan_set_label(0, tz, sizeof(struct timezone));
1728 }
1729 *ret_label = 0;
1730 return ret;
1731 }
1732
1733 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)1734 int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz,
1735 dfsan_label tv_label, dfsan_label tz_label,
1736 dfsan_label *ret_label, dfsan_origin tv_origin,
1737 dfsan_origin tz_origin, dfsan_origin *ret_origin) {
1738 return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label);
1739 }
1740
__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)1741 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n,
1742 dfsan_label s_label,
1743 dfsan_label c_label,
1744 dfsan_label n_label,
1745 dfsan_label *ret_label) {
1746 void *ret = memchr(s, c, n);
1747 if (flags().strict_data_dependencies) {
1748 *ret_label = ret ? s_label : 0;
1749 } else {
1750 size_t len =
1751 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1752 : n;
1753 *ret_label =
1754 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label));
1755 }
1756 return ret;
1757 }
1758
__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)1759 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr(
1760 void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label,
1761 dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin,
1762 dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) {
1763 void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label);
1764 if (flags().strict_data_dependencies) {
1765 if (ret)
1766 *ret_origin = s_origin;
1767 } else {
1768 size_t len =
1769 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1770 : n;
1771 dfsan_origin o = dfsan_read_origin_of_first_taint(s, len);
1772 *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1773 }
1774 return ret;
1775 }
1776
__dfsw_strrchr(char * s,int c,dfsan_label s_label,dfsan_label c_label,dfsan_label * ret_label)1777 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c,
1778 dfsan_label s_label,
1779 dfsan_label c_label,
1780 dfsan_label *ret_label) {
1781 char *ret = strrchr(s, c);
1782 if (flags().strict_data_dependencies) {
1783 *ret_label = ret ? s_label : 0;
1784 } else {
1785 *ret_label =
1786 dfsan_union(dfsan_read_label(s, strlen(s) + 1),
1787 dfsan_union(s_label, c_label));
1788 }
1789
1790 return ret;
1791 }
1792
__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)1793 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr(
1794 char *s, int c, dfsan_label s_label, dfsan_label c_label,
1795 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
1796 dfsan_origin *ret_origin) {
1797 char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label);
1798 if (flags().strict_data_dependencies) {
1799 if (ret)
1800 *ret_origin = s_origin;
1801 } else {
1802 size_t s_len = strlen(s) + 1;
1803 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len);
1804 *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1805 }
1806
1807 return ret;
1808 }
1809
__dfsw_strstr(char * haystack,char * needle,dfsan_label haystack_label,dfsan_label needle_label,dfsan_label * ret_label)1810 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle,
1811 dfsan_label haystack_label,
1812 dfsan_label needle_label,
1813 dfsan_label *ret_label) {
1814 char *ret = strstr(haystack, needle);
1815 if (flags().strict_data_dependencies) {
1816 *ret_label = ret ? haystack_label : 0;
1817 } else {
1818 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1;
1819 *ret_label =
1820 dfsan_union(dfsan_read_label(haystack, len),
1821 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1),
1822 dfsan_union(haystack_label, needle_label)));
1823 }
1824
1825 return ret;
1826 }
1827
__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)1828 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle,
1829 dfsan_label haystack_label,
1830 dfsan_label needle_label,
1831 dfsan_label *ret_label,
1832 dfsan_origin haystack_origin,
1833 dfsan_origin needle_origin,
1834 dfsan_origin *ret_origin) {
1835 char *ret =
1836 __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label);
1837 if (flags().strict_data_dependencies) {
1838 if (ret)
1839 *ret_origin = haystack_origin;
1840 } else {
1841 size_t needle_len = strlen(needle);
1842 size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1;
1843 dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len);
1844 if (o) {
1845 *ret_origin = o;
1846 } else {
1847 o = dfsan_read_origin_of_first_taint(needle, needle_len + 1);
1848 *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin);
1849 }
1850 }
1851
1852 return ret;
1853 }
1854
__dfsw_nanosleep(const struct timespec * req,struct timespec * rem,dfsan_label req_label,dfsan_label rem_label,dfsan_label * ret_label)1855 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req,
1856 struct timespec *rem,
1857 dfsan_label req_label,
1858 dfsan_label rem_label,
1859 dfsan_label *ret_label) {
1860 int ret = nanosleep(req, rem);
1861 *ret_label = 0;
1862 if (ret == -1) {
1863 // Interrupted by a signal, rem is filled with the remaining time.
1864 dfsan_set_label(0, rem, sizeof(struct timespec));
1865 }
1866 return ret;
1867 }
1868
__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)1869 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep(
1870 const struct timespec *req, struct timespec *rem, dfsan_label req_label,
1871 dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin,
1872 dfsan_origin rem_origin, dfsan_origin *ret_origin) {
1873 return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label);
1874 }
1875
clear_msghdr_labels(size_t bytes_written,struct msghdr * msg)1876 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) {
1877 dfsan_set_label(0, msg, sizeof(*msg));
1878 dfsan_set_label(0, msg->msg_name, msg->msg_namelen);
1879 dfsan_set_label(0, msg->msg_control, msg->msg_controllen);
1880 for (size_t i = 0; bytes_written > 0; ++i) {
1881 assert(i < msg->msg_iovlen);
1882 struct iovec *iov = &msg->msg_iov[i];
1883 size_t iov_written =
1884 bytes_written < iov->iov_len ? bytes_written : iov->iov_len;
1885 dfsan_set_label(0, iov->iov_base, iov_written);
1886 bytes_written -= iov_written;
1887 }
1888 }
1889
__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)1890 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg(
1891 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
1892 struct timespec *timeout, dfsan_label sockfd_label,
1893 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
1894 dfsan_label timeout_label, dfsan_label *ret_label) {
1895 int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout);
1896 for (int i = 0; i < ret; ++i) {
1897 dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len));
1898 clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr);
1899 }
1900 *ret_label = 0;
1901 return ret;
1902 }
1903
__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)1904 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg(
1905 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
1906 struct timespec *timeout, dfsan_label sockfd_label,
1907 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
1908 dfsan_label timeout_label, dfsan_label *ret_label,
1909 dfsan_origin sockfd_origin, dfsan_origin msgvec_origin,
1910 dfsan_origin vlen_origin, dfsan_origin flags_origin,
1911 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1912 return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label,
1913 msgvec_label, vlen_label, flags_label, timeout_label,
1914 ret_label);
1915 }
1916
__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)1917 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg(
1918 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
1919 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) {
1920 ssize_t ret = recvmsg(sockfd, msg, flags);
1921 if (ret >= 0)
1922 clear_msghdr_labels(ret, msg);
1923 *ret_label = 0;
1924 return ret;
1925 }
1926
__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)1927 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg(
1928 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
1929 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label,
1930 dfsan_origin sockfd_origin, dfsan_origin msg_origin,
1931 dfsan_origin flags_origin, dfsan_origin *ret_origin) {
1932 return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label,
1933 flags_label, ret_label);
1934 }
1935
1936 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)1937 __dfsw_socketpair(int domain, int type, int protocol, int sv[2],
1938 dfsan_label domain_label, dfsan_label type_label,
1939 dfsan_label protocol_label, dfsan_label sv_label,
1940 dfsan_label *ret_label) {
1941 int ret = socketpair(domain, type, protocol, sv);
1942 *ret_label = 0;
1943 if (ret == 0) {
1944 dfsan_set_label(0, sv, sizeof(*sv) * 2);
1945 }
1946 return ret;
1947 }
1948
__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)1949 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair(
1950 int domain, int type, int protocol, int sv[2], dfsan_label domain_label,
1951 dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label,
1952 dfsan_label *ret_label, dfsan_origin domain_origin,
1953 dfsan_origin type_origin, dfsan_origin protocol_origin,
1954 dfsan_origin sv_origin, dfsan_origin *ret_origin) {
1955 return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label,
1956 protocol_label, sv_label, ret_label);
1957 }
1958
__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)1959 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt(
1960 int sockfd, int level, int optname, void *optval, socklen_t *optlen,
1961 dfsan_label sockfd_label, dfsan_label level_label,
1962 dfsan_label optname_label, dfsan_label optval_label,
1963 dfsan_label optlen_label, dfsan_label *ret_label) {
1964 int ret = getsockopt(sockfd, level, optname, optval, optlen);
1965 if (ret != -1 && optval && optlen) {
1966 dfsan_set_label(0, optlen, sizeof(*optlen));
1967 dfsan_set_label(0, optval, *optlen);
1968 }
1969 *ret_label = 0;
1970 return ret;
1971 }
1972
__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)1973 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt(
1974 int sockfd, int level, int optname, void *optval, socklen_t *optlen,
1975 dfsan_label sockfd_label, dfsan_label level_label,
1976 dfsan_label optname_label, dfsan_label optval_label,
1977 dfsan_label optlen_label, dfsan_label *ret_label,
1978 dfsan_origin sockfd_origin, dfsan_origin level_origin,
1979 dfsan_origin optname_origin, dfsan_origin optval_origin,
1980 dfsan_origin optlen_origin, dfsan_origin *ret_origin) {
1981 return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label,
1982 level_label, optname_label, optval_label,
1983 optlen_label, ret_label);
1984 }
1985
__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)1986 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname(
1987 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
1988 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
1989 dfsan_label *ret_label) {
1990 socklen_t origlen = addrlen ? *addrlen : 0;
1991 int ret = getsockname(sockfd, addr, addrlen);
1992 if (ret != -1 && addr && addrlen) {
1993 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
1994 dfsan_set_label(0, addrlen, sizeof(*addrlen));
1995 dfsan_set_label(0, addr, written_bytes);
1996 }
1997 *ret_label = 0;
1998 return ret;
1999 }
2000
__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)2001 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname(
2002 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2003 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2004 dfsan_label *ret_label, dfsan_origin sockfd_origin,
2005 dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2006 dfsan_origin *ret_origin) {
2007 return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label,
2008 addrlen_label, ret_label);
2009 }
2010
__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)2011 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername(
2012 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2013 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2014 dfsan_label *ret_label) {
2015 socklen_t origlen = addrlen ? *addrlen : 0;
2016 int ret = getpeername(sockfd, addr, addrlen);
2017 if (ret != -1 && addr && addrlen) {
2018 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
2019 dfsan_set_label(0, addrlen, sizeof(*addrlen));
2020 dfsan_set_label(0, addr, written_bytes);
2021 }
2022 *ret_label = 0;
2023 return ret;
2024 }
2025
__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)2026 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername(
2027 int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2028 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2029 dfsan_label *ret_label, dfsan_origin sockfd_origin,
2030 dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2031 dfsan_origin *ret_origin) {
2032 return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label,
2033 addrlen_label, ret_label);
2034 }
2035
2036 // Type of the function passed to dfsan_set_write_callback.
2037 typedef void (*write_dfsan_callback_t)(int fd, const void *buf, ssize_t count);
2038
2039 // Calls to dfsan_set_write_callback() set the values in this struct.
2040 // Calls to the custom version of write() read (and invoke) them.
2041 static struct {
2042 write_dfsan_callback_t write_callback = nullptr;
2043 } write_callback_info;
2044
__dfsw_dfsan_set_write_callback(write_dfsan_callback_t write_callback,dfsan_label write_callback_label,dfsan_label * ret_label)2045 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw_dfsan_set_write_callback(
2046 write_dfsan_callback_t write_callback, dfsan_label write_callback_label,
2047 dfsan_label *ret_label) {
2048 write_callback_info.write_callback = write_callback;
2049 }
2050
__dfso_dfsan_set_write_callback(write_dfsan_callback_t write_callback,dfsan_label write_callback_label,dfsan_label * ret_label,dfsan_origin write_callback_origin,dfsan_origin * ret_origin)2051 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback(
2052 write_dfsan_callback_t write_callback, dfsan_label write_callback_label,
2053 dfsan_label *ret_label, dfsan_origin write_callback_origin,
2054 dfsan_origin *ret_origin) {
2055 write_callback_info.write_callback = write_callback;
2056 }
2057
setup_tls_args_for_write_callback(dfsan_label fd_label,dfsan_label buf_label,dfsan_label count_label,bool origins,dfsan_origin fd_origin,dfsan_origin buf_origin,dfsan_origin count_origin)2058 static inline void setup_tls_args_for_write_callback(
2059 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label,
2060 bool origins, dfsan_origin fd_origin, dfsan_origin buf_origin,
2061 dfsan_origin count_origin) {
2062 // The callback code will expect argument shadow labels in the args TLS,
2063 // and origin labels in the origin args TLS.
2064 // Previously this was done by a trampoline, but we want to remove this:
2065 // https://github.com/llvm/llvm-project/issues/54172
2066 //
2067 // Instead, this code is manually setting up the args TLS data.
2068 //
2069 // The offsets used need to correspond with the instrumentation code,
2070 // see llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
2071 // DFSanFunction::getShadowForTLSArgument.
2072 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L1684
2073 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L125
2074 //
2075 // Here the arguments are all primitives, but it can be more complex
2076 // to compute offsets for array/aggregate type arguments.
2077 //
2078 // TODO(browneee): Consider a builtin to improve maintainabliity.
2079 // With a builtin, we would provide the argument labels via builtin,
2080 // and the builtin would reuse parts of the instrumentation code to ensure
2081 // that this code and the instrumentation can never be out of sync.
2082 // Note: Currently DFSan instrumentation does not run on this code, so
2083 // the builtin may need to be handled outside DFSan instrumentation.
2084 dfsan_set_arg_tls(0, fd_label);
2085 dfsan_set_arg_tls(1, buf_label);
2086 dfsan_set_arg_tls(2, count_label);
2087 if (origins) {
2088 dfsan_set_arg_origin_tls(0, fd_origin);
2089 dfsan_set_arg_origin_tls(1, buf_origin);
2090 dfsan_set_arg_origin_tls(2, count_origin);
2091 }
2092 }
2093
2094 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)2095 __dfsw_write(int fd, const void *buf, size_t count,
2096 dfsan_label fd_label, dfsan_label buf_label,
2097 dfsan_label count_label, dfsan_label *ret_label) {
2098 if (write_callback_info.write_callback) {
2099 setup_tls_args_for_write_callback(fd_label, buf_label, count_label, false,
2100 0, 0, 0);
2101 write_callback_info.write_callback(fd, buf, count);
2102 }
2103
2104 *ret_label = 0;
2105 return write(fd, buf, count);
2106 }
2107
__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)2108 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write(
2109 int fd, const void *buf, size_t count, dfsan_label fd_label,
2110 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
2111 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
2112 dfsan_origin *ret_origin) {
2113 if (write_callback_info.write_callback) {
2114 setup_tls_args_for_write_callback(fd_label, buf_label, count_label, true,
2115 fd_origin, buf_origin, count_origin);
2116 write_callback_info.write_callback(fd, buf, count);
2117 }
2118
2119 *ret_label = 0;
2120 return write(fd, buf, count);
2121 }
2122 } // namespace __dfsan
2123
2124 // Type used to extract a dfsan_label with va_arg()
2125 typedef int dfsan_label_va;
2126
2127 // Formats a chunk either a constant string or a single format directive (e.g.,
2128 // '%.3f').
2129 struct Formatter {
FormatterFormatter2130 Formatter(char *str_, const char *fmt_, size_t size_)
2131 : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_),
2132 width(-1) {}
2133
formatFormatter2134 int format() {
2135 char *tmp_fmt = build_format_string();
2136 int retval =
2137 snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt,
2138 0 /* used only to avoid warnings */);
2139 free(tmp_fmt);
2140 return retval;
2141 }
2142
formatFormatter2143 template <typename T> int format(T arg) {
2144 char *tmp_fmt = build_format_string();
2145 int retval;
2146 if (width >= 0) {
2147 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2148 tmp_fmt, width, arg);
2149 } else {
2150 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2151 tmp_fmt, arg);
2152 }
2153 free(tmp_fmt);
2154 return retval;
2155 }
2156
build_format_stringFormatter2157 char *build_format_string() {
2158 size_t fmt_size = fmt_cur - fmt_start + 1;
2159 char *new_fmt = (char *)malloc(fmt_size + 1);
2160 assert(new_fmt);
2161 internal_memcpy(new_fmt, fmt_start, fmt_size);
2162 new_fmt[fmt_size] = '\0';
2163 return new_fmt;
2164 }
2165
str_curFormatter2166 char *str_cur() { return str + str_off; }
2167
num_written_bytesFormatter2168 size_t num_written_bytes(int retval) {
2169 if (retval < 0) {
2170 return 0;
2171 }
2172
2173 size_t num_avail = str_off < size ? size - str_off : 0;
2174 if (num_avail == 0) {
2175 return 0;
2176 }
2177
2178 size_t num_written = retval;
2179 // A return value of {v,}snprintf of size or more means that the output was
2180 // truncated.
2181 if (num_written >= num_avail) {
2182 num_written -= num_avail;
2183 }
2184
2185 return num_written;
2186 }
2187
2188 char *str;
2189 size_t str_off;
2190 size_t size;
2191 const char *fmt_start;
2192 const char *fmt_cur;
2193 int width;
2194 };
2195
2196 // Formats the input and propagates the input labels to the output. The output
2197 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and
2198 // 'ap' are the format string and the list of arguments for formatting. Returns
2199 // the return value vsnprintf would return.
2200 //
2201 // The function tokenizes the format string in chunks representing either a
2202 // constant string or a single format directive (e.g., '%.3f') and formats each
2203 // chunk independently into the output string. This approach allows to figure
2204 // out which bytes of the output string depends on which argument and thus to
2205 // propagate labels more precisely.
2206 //
2207 // WARNING: This implementation does not support conversion specifiers with
2208 // 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)2209 static int format_buffer(char *str, size_t size, const char *fmt,
2210 dfsan_label *va_labels, dfsan_label *ret_label,
2211 dfsan_origin *va_origins, dfsan_origin *ret_origin,
2212 va_list ap) {
2213 Formatter formatter(str, fmt, size);
2214
2215 while (*formatter.fmt_cur) {
2216 formatter.fmt_start = formatter.fmt_cur;
2217 formatter.width = -1;
2218 int retval = 0;
2219
2220 if (*formatter.fmt_cur != '%') {
2221 // Ordinary character. Consume all the characters until a '%' or the end
2222 // of the string.
2223 for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';
2224 ++formatter.fmt_cur) {}
2225 retval = formatter.format();
2226 dfsan_set_label(0, formatter.str_cur(),
2227 formatter.num_written_bytes(retval));
2228 } else {
2229 // Conversion directive. Consume all the characters until a conversion
2230 // specifier or the end of the string.
2231 bool end_fmt = false;
2232 for (; *formatter.fmt_cur && !end_fmt; ) {
2233 switch (*++formatter.fmt_cur) {
2234 case 'd':
2235 case 'i':
2236 case 'o':
2237 case 'u':
2238 case 'x':
2239 case 'X':
2240 switch (*(formatter.fmt_cur - 1)) {
2241 case 'h':
2242 // Also covers the 'hh' case (since the size of the arg is still
2243 // an int).
2244 retval = formatter.format(va_arg(ap, int));
2245 break;
2246 case 'l':
2247 if (formatter.fmt_cur - formatter.fmt_start >= 2 &&
2248 *(formatter.fmt_cur - 2) == 'l') {
2249 retval = formatter.format(va_arg(ap, long long int));
2250 } else {
2251 retval = formatter.format(va_arg(ap, long int));
2252 }
2253 break;
2254 case 'q':
2255 retval = formatter.format(va_arg(ap, long long int));
2256 break;
2257 case 'j':
2258 retval = formatter.format(va_arg(ap, intmax_t));
2259 break;
2260 case 'z':
2261 case 't':
2262 retval = formatter.format(va_arg(ap, size_t));
2263 break;
2264 default:
2265 retval = formatter.format(va_arg(ap, int));
2266 }
2267 if (va_origins == nullptr)
2268 dfsan_set_label(*va_labels++, formatter.str_cur(),
2269 formatter.num_written_bytes(retval));
2270 else
2271 dfsan_set_label_origin(*va_labels++, *va_origins++,
2272 formatter.str_cur(),
2273 formatter.num_written_bytes(retval));
2274 end_fmt = true;
2275 break;
2276
2277 case 'a':
2278 case 'A':
2279 case 'e':
2280 case 'E':
2281 case 'f':
2282 case 'F':
2283 case 'g':
2284 case 'G':
2285 if (*(formatter.fmt_cur - 1) == 'L') {
2286 retval = formatter.format(va_arg(ap, long double));
2287 } else {
2288 retval = formatter.format(va_arg(ap, double));
2289 }
2290 if (va_origins == nullptr)
2291 dfsan_set_label(*va_labels++, formatter.str_cur(),
2292 formatter.num_written_bytes(retval));
2293 else
2294 dfsan_set_label_origin(*va_labels++, *va_origins++,
2295 formatter.str_cur(),
2296 formatter.num_written_bytes(retval));
2297 end_fmt = true;
2298 break;
2299
2300 case 'c':
2301 retval = formatter.format(va_arg(ap, int));
2302 if (va_origins == nullptr)
2303 dfsan_set_label(*va_labels++, formatter.str_cur(),
2304 formatter.num_written_bytes(retval));
2305 else
2306 dfsan_set_label_origin(*va_labels++, *va_origins++,
2307 formatter.str_cur(),
2308 formatter.num_written_bytes(retval));
2309 end_fmt = true;
2310 break;
2311
2312 case 's': {
2313 char *arg = va_arg(ap, char *);
2314 retval = formatter.format(arg);
2315 if (va_origins) {
2316 va_origins++;
2317 dfsan_mem_origin_transfer(formatter.str_cur(), arg,
2318 formatter.num_written_bytes(retval));
2319 }
2320 va_labels++;
2321 dfsan_mem_shadow_transfer(formatter.str_cur(), arg,
2322 formatter.num_written_bytes(retval));
2323 end_fmt = true;
2324 break;
2325 }
2326
2327 case 'p':
2328 retval = formatter.format(va_arg(ap, void *));
2329 if (va_origins == nullptr)
2330 dfsan_set_label(*va_labels++, formatter.str_cur(),
2331 formatter.num_written_bytes(retval));
2332 else
2333 dfsan_set_label_origin(*va_labels++, *va_origins++,
2334 formatter.str_cur(),
2335 formatter.num_written_bytes(retval));
2336 end_fmt = true;
2337 break;
2338
2339 case 'n': {
2340 int *ptr = va_arg(ap, int *);
2341 *ptr = (int)formatter.str_off;
2342 va_labels++;
2343 if (va_origins)
2344 va_origins++;
2345 dfsan_set_label(0, ptr, sizeof(ptr));
2346 end_fmt = true;
2347 break;
2348 }
2349
2350 case '%':
2351 retval = formatter.format();
2352 dfsan_set_label(0, formatter.str_cur(),
2353 formatter.num_written_bytes(retval));
2354 end_fmt = true;
2355 break;
2356
2357 case '*':
2358 formatter.width = va_arg(ap, int);
2359 va_labels++;
2360 if (va_origins)
2361 va_origins++;
2362 break;
2363
2364 default:
2365 break;
2366 }
2367 }
2368 }
2369
2370 if (retval < 0) {
2371 return retval;
2372 }
2373
2374 formatter.fmt_cur++;
2375 formatter.str_off += retval;
2376 }
2377
2378 *ret_label = 0;
2379 if (ret_origin)
2380 *ret_origin = 0;
2381
2382 // Number of bytes written in total.
2383 return formatter.str_off;
2384 }
2385
2386 extern "C" {
2387 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,...)2388 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,
2389 dfsan_label format_label, dfsan_label *va_labels,
2390 dfsan_label *ret_label, ...) {
2391 va_list ap;
2392 va_start(ap, ret_label);
2393 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
2394 nullptr, ap);
2395 va_end(ap);
2396 return ret;
2397 }
2398
2399 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,...)2400 int __dfso_sprintf(char *str, const char *format, dfsan_label str_label,
2401 dfsan_label format_label, dfsan_label *va_labels,
2402 dfsan_label *ret_label, dfsan_origin str_origin,
2403 dfsan_origin format_origin, dfsan_origin *va_origins,
2404 dfsan_origin *ret_origin, ...) {
2405 va_list ap;
2406 va_start(ap, ret_origin);
2407 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins,
2408 ret_origin, ap);
2409 va_end(ap);
2410 return ret;
2411 }
2412
2413 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,...)2414 int __dfsw_snprintf(char *str, size_t size, const char *format,
2415 dfsan_label str_label, dfsan_label size_label,
2416 dfsan_label format_label, dfsan_label *va_labels,
2417 dfsan_label *ret_label, ...) {
2418 va_list ap;
2419 va_start(ap, ret_label);
2420 int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr,
2421 nullptr, ap);
2422 va_end(ap);
2423 return ret;
2424 }
2425
2426 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,...)2427 int __dfso_snprintf(char *str, size_t size, const char *format,
2428 dfsan_label str_label, dfsan_label size_label,
2429 dfsan_label format_label, dfsan_label *va_labels,
2430 dfsan_label *ret_label, dfsan_origin str_origin,
2431 dfsan_origin size_origin, dfsan_origin format_origin,
2432 dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) {
2433 va_list ap;
2434 va_start(ap, ret_origin);
2435 int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins,
2436 ret_origin, ap);
2437 va_end(ap);
2438 return ret;
2439 }
2440
BeforeFork()2441 static void BeforeFork() {
2442 StackDepotLockAll();
2443 GetChainedOriginDepot()->LockAll();
2444 }
2445
AfterFork()2446 static void AfterFork() {
2447 GetChainedOriginDepot()->UnlockAll();
2448 StackDepotUnlockAll();
2449 }
2450
2451 SANITIZER_INTERFACE_ATTRIBUTE
__dfsw_fork(dfsan_label * ret_label)2452 pid_t __dfsw_fork(dfsan_label *ret_label) {
2453 pid_t pid = fork();
2454 *ret_label = 0;
2455 return pid;
2456 }
2457
2458 SANITIZER_INTERFACE_ATTRIBUTE
__dfso_fork(dfsan_label * ret_label,dfsan_origin * ret_origin)2459 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) {
2460 BeforeFork();
2461 pid_t pid = __dfsw_fork(ret_label);
2462 AfterFork();
2463 return pid;
2464 }
2465
2466 // Default empty implementations (weak). Users should redefine them.
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_guard,u32 *)2467 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_guard_init,u32 *,u32 *)2468 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *,
2469 u32 *) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_pcs_init,const uptr * beg,const uptr * end)2470 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg,
2471 const uptr *end) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__sanitizer_cov_trace_pc_indir,void)2472 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
2473
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp,void)2474 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp1,void)2475 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp2,void)2476 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp4,void)2477 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_cmp8,void)2478 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp1,void)2479 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1,
2480 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp2,void)2481 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2,
2482 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp4,void)2483 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4,
2484 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_const_cmp8,void)2485 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8,
2486 void) {}
SANITIZER_INTERFACE_WEAK_DEF(void,__dfsw___sanitizer_cov_trace_switch,void)2487 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {}
2488 } // extern "C"
2489