1 //===-- dfsan_custom.cpp --------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file is a part of DataFlowSanitizer.
11 // This file defines the custom functions listed in done_abilist.txt.
12 //===----------------------------------------------------------------------===//
14 #include <arpa/inet.h>
29 #include <sys/epoll.h>
30 #include <sys/resource.h>
31 #include <sys/select.h>
32 #include <sys/socket.h>
35 #include <sys/types.h>
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"
48 using namespace __dfsan
;
50 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \
55 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
56 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);
58 // Async-safe, non-reentrant spin lock.
59 class SignalSpinLocker
{
64 pthread_sigmask(SIG_SETMASK
, &all_set
, &saved_thread_mask_
);
68 sigactions_mu
.Unlock();
69 pthread_sigmask(SIG_SETMASK
, &saved_thread_mask_
, nullptr);
73 static StaticSpinMutex sigactions_mu
;
74 sigset_t saved_thread_mask_
;
76 SignalSpinLocker(const SignalSpinLocker
&) = delete;
77 SignalSpinLocker
&operator=(const SignalSpinLocker
&) = delete;
80 StaticSpinMutex
SignalSpinLocker::sigactions_mu
;
83 SANITIZER_INTERFACE_ATTRIBUTE
int
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
);
88 dfsan_set_label(0, buf
, sizeof(struct stat
));
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
);
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
);
107 dfsan_set_label(0, buf
, sizeof(struct stat
));
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
);
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.
129 match_pos
= s
[i
] == 0 && c
!= 0 ? nullptr : const_cast<char *>(s
+ i
);
133 if (flags().strict_data_dependencies
)
134 *ret_label
= s_label
;
136 *ret_label
= dfsan_union(dfsan_read_label(s
, *bytes_read
),
137 dfsan_union(s_label
, c_label
));
141 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strchr(const char *s
, int c
,
144 dfsan_label
*ret_label
) {
146 return dfsan_strchr_with_label(s
, c
, &bytes_read
, s_label
, c_label
,
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
) {
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
);
166 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strpbrk(const char *s
,
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;
175 size_t s_bytes_read
= (ret
? ret
- s
: strlen(s
)) + 1;
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
)));
181 return const_cast<char *>(ret
);
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
) {
191 *ret_origin
= s_origin
;
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
);
199 o
= dfsan_read_origin_of_first_taint(accept
, strlen(accept
) + 1);
200 *ret_origin
= o
? o
: (s_label
? s_origin
: accept_origin
);
204 return const_cast<char *>(ret
);
207 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strsep(char **s
, const char *delim
,
209 dfsan_label delim_label
,
210 dfsan_label
*ret_label
) {
211 dfsan_label base_label
= dfsan_read_label(s
, sizeof(*s
));
213 char *res
= strsep(s
, delim
);
215 char *token_start
= res
;
216 int token_length
= strlen(res
);
217 // the delimiter byte has been set to NULL
218 dfsan_set_label(0, token_start
+ token_length
, 1);
221 if (flags().strict_data_dependencies
) {
222 *ret_label
= res
? base_label
: 0;
224 size_t s_bytes_read
= (res
? strlen(res
) : strlen(base
)) + 1;
225 *ret_label
= dfsan_union(
226 dfsan_union(base_label
, dfsan_read_label(base
, sizeof(s_bytes_read
))),
227 dfsan_union(dfsan_read_label(delim
, strlen(delim
) + 1),
228 dfsan_union(s_label
, delim_label
)));
234 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strsep(
235 char **s
, const char *delim
, dfsan_label s_label
, dfsan_label delim_label
,
236 dfsan_label
*ret_label
, dfsan_origin s_origin
, dfsan_origin delim_origin
,
237 dfsan_origin
*ret_origin
) {
238 dfsan_origin base_origin
= dfsan_read_origin_of_first_taint(s
, sizeof(*s
));
239 char *res
= __dfsw_strsep(s
, delim
, s_label
, delim_label
, ret_label
);
240 if (flags().strict_data_dependencies
) {
242 *ret_origin
= base_origin
;
246 *ret_origin
= base_origin
;
249 dfsan_read_origin_of_first_taint(delim
, strlen(delim
) + 1);
250 *ret_origin
= o
? o
: (s_label
? s_origin
: delim_origin
);
258 static int dfsan_memcmp_bcmp(const void *s1
, const void *s2
, size_t n
,
259 size_t *bytes_read
) {
260 const char *cs1
= (const char *) s1
, *cs2
= (const char *) s2
;
261 for (size_t i
= 0; i
!= n
; ++i
) {
262 if (cs1
[i
] != cs2
[i
]) {
264 return cs1
[i
] - cs2
[i
];
271 static dfsan_label
dfsan_get_memcmp_label(const void *s1
, const void *s2
,
273 if (flags().strict_data_dependencies
)
275 return dfsan_union(dfsan_read_label(s1
, pos
), dfsan_read_label(s2
, pos
));
278 static void dfsan_get_memcmp_origin(const void *s1
, const void *s2
, size_t pos
,
279 dfsan_label
*ret_label
,
280 dfsan_origin
*ret_origin
) {
281 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, pos
);
284 dfsan_origin o
= dfsan_read_origin_of_first_taint(s1
, pos
);
285 *ret_origin
= o
? o
: dfsan_read_origin_of_first_taint(s2
, pos
);
288 static int dfsan_memcmp_bcmp_label(const void *s1
, const void *s2
, size_t n
,
289 dfsan_label
*ret_label
) {
291 int r
= dfsan_memcmp_bcmp(s1
, s2
, n
, &bytes_read
);
292 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, bytes_read
);
296 static int dfsan_memcmp_bcmp_origin(const void *s1
, const void *s2
, size_t n
,
297 dfsan_label
*ret_label
,
298 dfsan_origin
*ret_origin
) {
300 int r
= dfsan_memcmp_bcmp(s1
, s2
, n
, &bytes_read
);
301 dfsan_get_memcmp_origin(s1
, s2
, bytes_read
, ret_label
, ret_origin
);
305 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp
, uptr caller_pc
,
306 const void *s1
, const void *s2
, size_t n
,
307 dfsan_label s1_label
, dfsan_label s2_label
,
310 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp
, uptr caller_pc
,
311 const void *s1
, const void *s2
, size_t n
,
312 dfsan_label s1_label
, dfsan_label s2_label
,
313 dfsan_label n_label
, dfsan_origin s1_origin
,
314 dfsan_origin s2_origin
, dfsan_origin n_origin
)
316 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_memcmp(const void *s1
, const void *s2
,
317 size_t n
, dfsan_label s1_label
,
318 dfsan_label s2_label
,
320 dfsan_label
*ret_label
) {
321 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp
, GET_CALLER_PC(), s1
, s2
, n
,
322 s1_label
, s2_label
, n_label
);
323 return dfsan_memcmp_bcmp_label(s1
, s2
, n
, ret_label
);
326 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_memcmp(
327 const void *s1
, const void *s2
, size_t n
, dfsan_label s1_label
,
328 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
,
329 dfsan_origin s1_origin
, dfsan_origin s2_origin
, dfsan_origin n_origin
,
330 dfsan_origin
*ret_origin
) {
331 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp
, GET_CALLER_PC(), s1
,
332 s2
, n
, s1_label
, s2_label
, n_label
, s1_origin
,
333 s2_origin
, n_origin
);
334 return dfsan_memcmp_bcmp_origin(s1
, s2
, n
, ret_label
, ret_origin
);
337 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_bcmp(const void *s1
, const void *s2
,
338 size_t n
, dfsan_label s1_label
,
339 dfsan_label s2_label
,
341 dfsan_label
*ret_label
) {
342 return dfsan_memcmp_bcmp_label(s1
, s2
, n
, ret_label
);
345 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_bcmp(
346 const void *s1
, const void *s2
, size_t n
, dfsan_label s1_label
,
347 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
,
348 dfsan_origin s1_origin
, dfsan_origin s2_origin
, dfsan_origin n_origin
,
349 dfsan_origin
*ret_origin
) {
350 return dfsan_memcmp_bcmp_origin(s1
, s2
, n
, ret_label
, ret_origin
);
353 // When n == 0, compare strings without byte limit.
354 // When n > 0, compare the first (at most) n bytes of s1 and s2.
355 static int dfsan_strncmp(const char *s1
, const char *s2
, size_t n
,
356 size_t *bytes_read
) {
357 for (size_t i
= 0;; ++i
) {
358 if (s1
[i
] != s2
[i
] || s1
[i
] == 0 || s2
[i
] == 0 || (n
> 0 && i
== n
- 1)) {
360 return s1
[i
] - s2
[i
];
365 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp
, uptr caller_pc
,
366 const char *s1
, const char *s2
,
367 dfsan_label s1_label
, dfsan_label s2_label
)
369 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp
, uptr caller_pc
,
370 const char *s1
, const char *s2
,
371 dfsan_label s1_label
, dfsan_label s2_label
,
372 dfsan_origin s1_origin
, dfsan_origin s2_origin
)
374 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strcmp(const char *s1
, const char *s2
,
375 dfsan_label s1_label
,
376 dfsan_label s2_label
,
377 dfsan_label
*ret_label
) {
378 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp
, GET_CALLER_PC(), s1
, s2
,
381 int r
= dfsan_strncmp(s1
, s2
, 0, &bytes_read
);
382 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, bytes_read
);
386 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_strcmp(
387 const char *s1
, const char *s2
, dfsan_label s1_label
, dfsan_label s2_label
,
388 dfsan_label
*ret_label
, dfsan_origin s1_origin
, dfsan_origin s2_origin
,
389 dfsan_origin
*ret_origin
) {
390 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp
, GET_CALLER_PC(), s1
,
391 s2
, s1_label
, s2_label
, s1_origin
, s2_origin
);
393 int r
= dfsan_strncmp(s1
, s2
, 0, &bytes_read
);
394 dfsan_get_memcmp_origin(s1
, s2
, bytes_read
, ret_label
, ret_origin
);
398 // When n == 0, compare strings without byte limit.
399 // When n > 0, compare the first (at most) n bytes of s1 and s2.
400 static int dfsan_strncasecmp(const char *s1
, const char *s2
, size_t n
,
401 size_t *bytes_read
) {
402 for (size_t i
= 0;; ++i
) {
403 char s1_lower
= tolower(s1
[i
]);
404 char s2_lower
= tolower(s2
[i
]);
406 if (s1_lower
!= s2_lower
|| s1
[i
] == 0 || s2
[i
] == 0 ||
407 (n
> 0 && i
== n
- 1)) {
409 return s1_lower
- s2_lower
;
414 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strcasecmp(const char *s1
,
416 dfsan_label s1_label
,
417 dfsan_label s2_label
,
418 dfsan_label
*ret_label
) {
420 int r
= dfsan_strncasecmp(s1
, s2
, 0, &bytes_read
);
421 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, bytes_read
);
425 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_strcasecmp(
426 const char *s1
, const char *s2
, dfsan_label s1_label
, dfsan_label s2_label
,
427 dfsan_label
*ret_label
, dfsan_origin s1_origin
, dfsan_origin s2_origin
,
428 dfsan_origin
*ret_origin
) {
430 int r
= dfsan_strncasecmp(s1
, s2
, 0, &bytes_read
);
431 dfsan_get_memcmp_origin(s1
, s2
, bytes_read
, ret_label
, ret_origin
);
435 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp
, uptr caller_pc
,
436 const char *s1
, const char *s2
, size_t n
,
437 dfsan_label s1_label
, dfsan_label s2_label
,
440 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp
, uptr caller_pc
,
441 const char *s1
, const char *s2
, size_t n
,
442 dfsan_label s1_label
, dfsan_label s2_label
,
443 dfsan_label n_label
, dfsan_origin s1_origin
,
444 dfsan_origin s2_origin
, dfsan_origin n_origin
)
446 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strncmp(const char *s1
, const char *s2
,
447 size_t n
, dfsan_label s1_label
,
448 dfsan_label s2_label
,
450 dfsan_label
*ret_label
) {
456 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp
, GET_CALLER_PC(), s1
, s2
,
457 n
, s1_label
, s2_label
, n_label
);
460 int r
= dfsan_strncmp(s1
, s2
, n
, &bytes_read
);
461 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, bytes_read
);
465 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_strncmp(
466 const char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
467 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
,
468 dfsan_origin s1_origin
, dfsan_origin s2_origin
, dfsan_origin n_origin
,
469 dfsan_origin
*ret_origin
) {
475 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp
, GET_CALLER_PC(),
476 s1
, s2
, n
, s1_label
, s2_label
, n_label
, s1_origin
,
477 s2_origin
, n_origin
);
480 int r
= dfsan_strncmp(s1
, s2
, n
, &bytes_read
);
481 dfsan_get_memcmp_origin(s1
, s2
, bytes_read
, ret_label
, ret_origin
);
485 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strncasecmp(
486 const char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
487 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
) {
494 int r
= dfsan_strncasecmp(s1
, s2
, n
, &bytes_read
);
495 *ret_label
= dfsan_get_memcmp_label(s1
, s2
, bytes_read
);
499 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_strncasecmp(
500 const char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
501 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
,
502 dfsan_origin s1_origin
, dfsan_origin s2_origin
, dfsan_origin n_origin
,
503 dfsan_origin
*ret_origin
) {
510 int r
= dfsan_strncasecmp(s1
, s2
, n
, &bytes_read
);
511 dfsan_get_memcmp_origin(s1
, s2
, bytes_read
, ret_label
, ret_origin
);
516 SANITIZER_INTERFACE_ATTRIBUTE
size_t
517 __dfsw_strlen(const char *s
, dfsan_label s_label
, dfsan_label
*ret_label
) {
518 size_t ret
= strlen(s
);
519 if (flags().strict_data_dependencies
) {
522 *ret_label
= dfsan_read_label(s
, ret
+ 1);
527 SANITIZER_INTERFACE_ATTRIBUTE
size_t __dfso_strlen(const char *s
,
529 dfsan_label
*ret_label
,
530 dfsan_origin s_origin
,
531 dfsan_origin
*ret_origin
) {
532 size_t ret
= __dfsw_strlen(s
, s_label
, ret_label
);
533 if (!flags().strict_data_dependencies
)
534 *ret_origin
= dfsan_read_origin_of_first_taint(s
, ret
+ 1);
538 SANITIZER_INTERFACE_ATTRIBUTE
size_t __dfsw_strnlen(const char *s
,
541 dfsan_label maxlen_label
,
542 dfsan_label
*ret_label
) {
543 size_t ret
= strnlen(s
, maxlen
);
544 if (flags().strict_data_dependencies
) {
547 size_t full_len
= strlen(s
);
548 size_t covered_len
= maxlen
> (full_len
+ 1) ? (full_len
+ 1) : maxlen
;
549 *ret_label
= dfsan_union(maxlen_label
, dfsan_read_label(s
, covered_len
));
554 SANITIZER_INTERFACE_ATTRIBUTE
size_t __dfso_strnlen(
555 const char *s
, size_t maxlen
, dfsan_label s_label
, dfsan_label maxlen_label
,
556 dfsan_label
*ret_label
, dfsan_origin s_origin
, dfsan_origin maxlen_origin
,
557 dfsan_origin
*ret_origin
) {
558 size_t ret
= __dfsw_strnlen(s
, maxlen
, s_label
, maxlen_label
, ret_label
);
559 if (!flags().strict_data_dependencies
) {
560 size_t full_len
= strlen(s
);
561 size_t covered_len
= maxlen
> (full_len
+ 1) ? (full_len
+ 1) : maxlen
;
562 dfsan_origin o
= dfsan_read_origin_of_first_taint(s
, covered_len
);
563 *ret_origin
= o
? o
: maxlen_origin
;
568 static void *dfsan_memmove(void *dest
, const void *src
, size_t n
) {
569 dfsan_label
*sdest
= shadow_for(dest
);
570 const dfsan_label
*ssrc
= shadow_for(src
);
571 internal_memmove((void *)sdest
, (const void *)ssrc
, n
* sizeof(dfsan_label
));
572 return internal_memmove(dest
, src
, n
);
575 static void *dfsan_memmove_with_origin(void *dest
, const void *src
, size_t n
) {
576 dfsan_mem_origin_transfer(dest
, src
, n
);
577 return dfsan_memmove(dest
, src
, n
);
580 static void *dfsan_memcpy(void *dest
, const void *src
, size_t n
) {
581 dfsan_mem_shadow_transfer(dest
, src
, n
);
582 return internal_memcpy(dest
, src
, n
);
585 static void *dfsan_memcpy_with_origin(void *dest
, const void *src
, size_t n
) {
586 dfsan_mem_origin_transfer(dest
, src
, n
);
587 return dfsan_memcpy(dest
, src
, n
);
590 static void dfsan_memset(void *s
, int c
, dfsan_label c_label
, size_t n
) {
591 internal_memset(s
, c
, n
);
592 dfsan_set_label(c_label
, s
, n
);
595 static void dfsan_memset_with_origin(void *s
, int c
, dfsan_label c_label
,
596 dfsan_origin c_origin
, size_t n
) {
597 internal_memset(s
, c
, n
);
598 dfsan_set_label_origin(c_label
, c_origin
, s
, n
);
601 SANITIZER_INTERFACE_ATTRIBUTE
602 void *__dfsw_memcpy(void *dest
, const void *src
, size_t n
,
603 dfsan_label dest_label
, dfsan_label src_label
,
604 dfsan_label n_label
, dfsan_label
*ret_label
) {
605 *ret_label
= dest_label
;
606 return dfsan_memcpy(dest
, src
, n
);
609 SANITIZER_INTERFACE_ATTRIBUTE
610 void *__dfso_memcpy(void *dest
, const void *src
, size_t n
,
611 dfsan_label dest_label
, dfsan_label src_label
,
612 dfsan_label n_label
, dfsan_label
*ret_label
,
613 dfsan_origin dest_origin
, dfsan_origin src_origin
,
614 dfsan_origin n_origin
, dfsan_origin
*ret_origin
) {
615 *ret_label
= dest_label
;
616 *ret_origin
= dest_origin
;
617 return dfsan_memcpy_with_origin(dest
, src
, n
);
620 SANITIZER_INTERFACE_ATTRIBUTE
621 void *__dfsw_memmove(void *dest
, const void *src
, size_t n
,
622 dfsan_label dest_label
, dfsan_label src_label
,
623 dfsan_label n_label
, dfsan_label
*ret_label
) {
624 *ret_label
= dest_label
;
625 return dfsan_memmove(dest
, src
, n
);
628 SANITIZER_INTERFACE_ATTRIBUTE
629 void *__dfso_memmove(void *dest
, const void *src
, size_t n
,
630 dfsan_label dest_label
, dfsan_label src_label
,
631 dfsan_label n_label
, dfsan_label
*ret_label
,
632 dfsan_origin dest_origin
, dfsan_origin src_origin
,
633 dfsan_origin n_origin
, dfsan_origin
*ret_origin
) {
634 *ret_label
= dest_label
;
635 *ret_origin
= dest_origin
;
636 return dfsan_memmove_with_origin(dest
, src
, n
);
639 SANITIZER_INTERFACE_ATTRIBUTE
640 void *__dfsw_memset(void *s
, int c
, size_t n
,
641 dfsan_label s_label
, dfsan_label c_label
,
642 dfsan_label n_label
, dfsan_label
*ret_label
) {
643 dfsan_memset(s
, c
, c_label
, n
);
644 *ret_label
= s_label
;
648 SANITIZER_INTERFACE_ATTRIBUTE
649 void *__dfso_memset(void *s
, int c
, size_t n
, dfsan_label s_label
,
650 dfsan_label c_label
, dfsan_label n_label
,
651 dfsan_label
*ret_label
, dfsan_origin s_origin
,
652 dfsan_origin c_origin
, dfsan_origin n_origin
,
653 dfsan_origin
*ret_origin
) {
654 dfsan_memset_with_origin(s
, c
, c_label
, c_origin
, n
);
655 *ret_label
= s_label
;
656 *ret_origin
= s_origin
;
660 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strcat(char *dest
, const char *src
,
661 dfsan_label dest_label
,
662 dfsan_label src_label
,
663 dfsan_label
*ret_label
) {
664 size_t dest_len
= strlen(dest
);
665 char *ret
= strcat(dest
, src
);
666 dfsan_mem_shadow_transfer(dest
+ dest_len
, src
, strlen(src
));
667 *ret_label
= dest_label
;
671 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strcat(
672 char *dest
, const char *src
, dfsan_label dest_label
, dfsan_label src_label
,
673 dfsan_label
*ret_label
, dfsan_origin dest_origin
, dfsan_origin src_origin
,
674 dfsan_origin
*ret_origin
) {
675 size_t dest_len
= strlen(dest
);
676 char *ret
= strcat(dest
, src
);
677 size_t src_len
= strlen(src
);
678 dfsan_mem_origin_transfer(dest
+ dest_len
, src
, src_len
);
679 dfsan_mem_shadow_transfer(dest
+ dest_len
, src
, src_len
);
680 *ret_label
= dest_label
;
681 *ret_origin
= dest_origin
;
685 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strncat(
686 char *dest
, const char *src
, size_t num
, dfsan_label dest_label
,
687 dfsan_label src_label
, dfsan_label num_label
, dfsan_label
*ret_label
) {
688 size_t src_len
= strlen(src
);
689 src_len
= src_len
< num
? src_len
: num
;
690 size_t dest_len
= strlen(dest
);
692 char *ret
= strncat(dest
, src
, num
);
693 dfsan_mem_shadow_transfer(dest
+ dest_len
, src
, src_len
);
694 *ret_label
= dest_label
;
698 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strncat(
699 char *dest
, const char *src
, size_t num
, dfsan_label dest_label
,
700 dfsan_label src_label
, dfsan_label num_label
, dfsan_label
*ret_label
,
701 dfsan_origin dest_origin
, dfsan_origin src_origin
, dfsan_origin num_origin
,
702 dfsan_origin
*ret_origin
) {
703 size_t src_len
= strlen(src
);
704 src_len
= src_len
< num
? src_len
: num
;
705 size_t dest_len
= strlen(dest
);
707 char *ret
= strncat(dest
, src
, num
);
709 dfsan_mem_origin_transfer(dest
+ dest_len
, src
, src_len
);
710 dfsan_mem_shadow_transfer(dest
+ dest_len
, src
, src_len
);
711 *ret_label
= dest_label
;
712 *ret_origin
= dest_origin
;
716 SANITIZER_INTERFACE_ATTRIBUTE
char *
717 __dfsw_strdup(const char *s
, dfsan_label s_label
, dfsan_label
*ret_label
) {
718 size_t len
= strlen(s
);
719 void *p
= malloc(len
+1);
720 dfsan_memcpy(p
, s
, len
+1);
722 return static_cast<char *>(p
);
725 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strdup(const char *s
,
727 dfsan_label
*ret_label
,
728 dfsan_origin s_origin
,
729 dfsan_origin
*ret_origin
) {
730 size_t len
= strlen(s
);
731 void *p
= malloc(len
+ 1);
732 dfsan_memcpy_with_origin(p
, s
, len
+ 1);
734 return static_cast<char *>(p
);
737 SANITIZER_INTERFACE_ATTRIBUTE
char *
738 __dfsw_strncpy(char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
739 dfsan_label s2_label
, dfsan_label n_label
,
740 dfsan_label
*ret_label
) {
741 size_t len
= strlen(s2
);
743 dfsan_memcpy(s1
, s2
, len
+1);
744 dfsan_memset(s1
+len
+1, 0, 0, n
-len
-1);
746 dfsan_memcpy(s1
, s2
, n
);
749 *ret_label
= s1_label
;
753 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strncpy(
754 char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
755 dfsan_label s2_label
, dfsan_label n_label
, dfsan_label
*ret_label
,
756 dfsan_origin s1_origin
, dfsan_origin s2_origin
, dfsan_origin n_origin
,
757 dfsan_origin
*ret_origin
) {
758 size_t len
= strlen(s2
);
760 dfsan_memcpy_with_origin(s1
, s2
, len
+ 1);
761 dfsan_memset_with_origin(s1
+ len
+ 1, 0, 0, 0, n
- len
- 1);
763 dfsan_memcpy_with_origin(s1
, s2
, n
);
766 *ret_label
= s1_label
;
767 *ret_origin
= s1_origin
;
771 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
772 __dfsw_pread(int fd
, void *buf
, size_t count
, off_t offset
,
773 dfsan_label fd_label
, dfsan_label buf_label
,
774 dfsan_label count_label
, dfsan_label offset_label
,
775 dfsan_label
*ret_label
) {
776 ssize_t ret
= pread(fd
, buf
, count
, offset
);
778 dfsan_set_label(0, buf
, ret
);
783 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfso_pread(
784 int fd
, void *buf
, size_t count
, off_t offset
, dfsan_label fd_label
,
785 dfsan_label buf_label
, dfsan_label count_label
, dfsan_label offset_label
,
786 dfsan_label
*ret_label
, dfsan_origin fd_origin
, dfsan_origin buf_origin
,
787 dfsan_origin count_origin
, dfsan_label offset_origin
,
788 dfsan_origin
*ret_origin
) {
789 return __dfsw_pread(fd
, buf
, count
, offset
, fd_label
, buf_label
, count_label
,
790 offset_label
, ret_label
);
793 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
794 __dfsw_read(int fd
, void *buf
, size_t count
,
795 dfsan_label fd_label
, dfsan_label buf_label
,
796 dfsan_label count_label
,
797 dfsan_label
*ret_label
) {
798 ssize_t ret
= read(fd
, buf
, count
);
800 dfsan_set_label(0, buf
, ret
);
805 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfso_read(
806 int fd
, void *buf
, size_t count
, dfsan_label fd_label
,
807 dfsan_label buf_label
, dfsan_label count_label
, dfsan_label
*ret_label
,
808 dfsan_origin fd_origin
, dfsan_origin buf_origin
, dfsan_origin count_origin
,
809 dfsan_origin
*ret_origin
) {
810 return __dfsw_read(fd
, buf
, count
, fd_label
, buf_label
, count_label
,
814 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_clock_gettime(clockid_t clk_id
,
816 dfsan_label clk_id_label
,
817 dfsan_label tp_label
,
818 dfsan_label
*ret_label
) {
819 int ret
= clock_gettime(clk_id
, tp
);
821 dfsan_set_label(0, tp
, sizeof(struct timespec
));
826 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_clock_gettime(
827 clockid_t clk_id
, struct timespec
*tp
, dfsan_label clk_id_label
,
828 dfsan_label tp_label
, dfsan_label
*ret_label
, dfsan_origin clk_id_origin
,
829 dfsan_origin tp_origin
, dfsan_origin
*ret_origin
) {
830 return __dfsw_clock_gettime(clk_id
, tp
, clk_id_label
, tp_label
, ret_label
);
833 static void dfsan_set_zero_label(const void *ptr
, uptr size
) {
834 dfsan_set_label(0, const_cast<void *>(ptr
), size
);
837 // dlopen() ultimately calls mmap() down inside the loader, which generally
838 // doesn't participate in dynamic symbol resolution. Therefore we won't
839 // intercept its calls to mmap, and we have to hook it here.
840 SANITIZER_INTERFACE_ATTRIBUTE
void *
841 __dfsw_dlopen(const char *filename
, int flag
, dfsan_label filename_label
,
842 dfsan_label flag_label
, dfsan_label
*ret_label
) {
843 void *handle
= dlopen(filename
, flag
);
844 link_map
*map
= GET_LINK_MAP_BY_DLOPEN_HANDLE(handle
);
846 ForEachMappedRegion(map
, dfsan_set_zero_label
);
851 SANITIZER_INTERFACE_ATTRIBUTE
void *__dfso_dlopen(
852 const char *filename
, int flag
, dfsan_label filename_label
,
853 dfsan_label flag_label
, dfsan_label
*ret_label
,
854 dfsan_origin filename_origin
, dfsan_origin flag_origin
,
855 dfsan_origin
*ret_origin
) {
856 return __dfsw_dlopen(filename
, flag
, filename_label
, flag_label
, ret_label
);
859 static void *DFsanThreadStartFunc(void *arg
) {
860 DFsanThread
*t
= (DFsanThread
*)arg
;
863 SetSigProcMask(&t
->starting_sigset_
, nullptr);
864 return t
->ThreadStart();
867 static int dfsan_pthread_create(pthread_t
*thread
, const pthread_attr_t
*attr
,
868 void *start_routine
, void *arg
,
869 dfsan_label
*ret_label
,
870 bool track_origins
= false) {
871 pthread_attr_t myattr
;
873 pthread_attr_init(&myattr
);
877 // Ensure that the thread stack is large enough to hold all TLS data.
878 AdjustStackSize((void *)(const_cast<pthread_attr_t
*>(attr
)));
881 DFsanThread::Create((thread_callback_t
)start_routine
, arg
, track_origins
);
882 ScopedBlockSignals
block(&t
->starting_sigset_
);
883 int res
= pthread_create(thread
, attr
, DFsanThreadStartFunc
, t
);
886 pthread_attr_destroy(&myattr
);
891 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_pthread_create(
892 pthread_t
*thread
, const pthread_attr_t
*attr
, void *start_routine
,
893 void *arg
, dfsan_label thread_label
, dfsan_label attr_label
,
894 dfsan_label start_routine_label
, dfsan_label arg_label
,
895 dfsan_label
*ret_label
) {
896 return dfsan_pthread_create(thread
, attr
, start_routine
, arg
, ret_label
);
899 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_pthread_create(
900 pthread_t
*thread
, const pthread_attr_t
*attr
, void *start_routine
,
901 void *arg
, dfsan_label thread_label
, dfsan_label attr_label
,
902 dfsan_label start_routine_label
, dfsan_label arg_label
,
903 dfsan_label
*ret_label
, dfsan_origin thread_origin
,
904 dfsan_origin attr_origin
, dfsan_origin start_routine_origin
,
905 dfsan_origin arg_origin
, dfsan_origin
*ret_origin
) {
906 return dfsan_pthread_create(thread
, attr
, start_routine
, arg
, ret_label
,
910 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_pthread_join(pthread_t thread
,
912 dfsan_label thread_label
,
913 dfsan_label retval_label
,
914 dfsan_label
*ret_label
) {
915 int ret
= pthread_join(thread
, retval
);
916 if (ret
== 0 && retval
)
917 dfsan_set_label(0, retval
, sizeof(*retval
));
922 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_pthread_join(
923 pthread_t thread
, void **retval
, dfsan_label thread_label
,
924 dfsan_label retval_label
, dfsan_label
*ret_label
,
925 dfsan_origin thread_origin
, dfsan_origin retval_origin
,
926 dfsan_origin
*ret_origin
) {
927 return __dfsw_pthread_join(thread
, retval
, thread_label
, retval_label
,
931 struct dl_iterate_phdr_info
{
932 int (*callback
)(struct dl_phdr_info
*info
, size_t size
, void *data
);
936 int dl_iterate_phdr_cb(struct dl_phdr_info
*info
, size_t size
, void *data
) {
937 dl_iterate_phdr_info
*dipi
= (dl_iterate_phdr_info
*)data
;
938 dfsan_set_label(0, *info
);
939 dfsan_set_label(0, const_cast<char *>(info
->dlpi_name
),
940 strlen(info
->dlpi_name
) + 1);
942 0, const_cast<char *>(reinterpret_cast<const char *>(info
->dlpi_phdr
)),
943 sizeof(*info
->dlpi_phdr
) * info
->dlpi_phnum
);
945 dfsan_clear_thread_local_state();
946 return dipi
->callback(info
, size
, dipi
->data
);
949 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_dl_iterate_phdr(
950 int (*callback
)(struct dl_phdr_info
*info
, size_t size
, void *data
),
951 void *data
, dfsan_label callback_label
, dfsan_label data_label
,
952 dfsan_label
*ret_label
) {
953 dl_iterate_phdr_info dipi
= {callback
, data
};
955 return dl_iterate_phdr(dl_iterate_phdr_cb
, &dipi
);
958 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_dl_iterate_phdr(
959 int (*callback
)(struct dl_phdr_info
*info
, size_t size
, void *data
),
960 void *data
, dfsan_label callback_label
, dfsan_label data_label
,
961 dfsan_label
*ret_label
, dfsan_origin callback_origin
,
962 dfsan_origin data_origin
, dfsan_origin
*ret_origin
) {
963 dl_iterate_phdr_info dipi
= {callback
, data
};
965 return dl_iterate_phdr(dl_iterate_phdr_cb
, &dipi
);
968 // This function is only available for glibc 2.27 or newer. Mark it weak so
969 // linking succeeds with older glibcs.
970 SANITIZER_WEAK_ATTRIBUTE
void _dl_get_tls_static_info(size_t *sizep
,
973 SANITIZER_INTERFACE_ATTRIBUTE
void __dfsw__dl_get_tls_static_info(
974 size_t *sizep
, size_t *alignp
, dfsan_label sizep_label
,
975 dfsan_label alignp_label
) {
976 assert(_dl_get_tls_static_info
);
977 _dl_get_tls_static_info(sizep
, alignp
);
978 dfsan_set_label(0, sizep
, sizeof(*sizep
));
979 dfsan_set_label(0, alignp
, sizeof(*alignp
));
982 SANITIZER_INTERFACE_ATTRIBUTE
void __dfso__dl_get_tls_static_info(
983 size_t *sizep
, size_t *alignp
, dfsan_label sizep_label
,
984 dfsan_label alignp_label
, dfsan_origin sizep_origin
,
985 dfsan_origin alignp_origin
) {
986 __dfsw__dl_get_tls_static_info(sizep
, alignp
, sizep_label
, alignp_label
);
989 SANITIZER_INTERFACE_ATTRIBUTE
990 char *__dfsw_ctime_r(const time_t *timep
, char *buf
, dfsan_label timep_label
,
991 dfsan_label buf_label
, dfsan_label
*ret_label
) {
992 char *ret
= ctime_r(timep
, buf
);
994 dfsan_set_label(dfsan_read_label(timep
, sizeof(time_t)), buf
,
996 *ret_label
= buf_label
;
1003 SANITIZER_INTERFACE_ATTRIBUTE
1004 char *__dfso_ctime_r(const time_t *timep
, char *buf
, dfsan_label timep_label
,
1005 dfsan_label buf_label
, dfsan_label
*ret_label
,
1006 dfsan_origin timep_origin
, dfsan_origin buf_origin
,
1007 dfsan_origin
*ret_origin
) {
1008 char *ret
= ctime_r(timep
, buf
);
1010 dfsan_set_label_origin(
1011 dfsan_read_label(timep
, sizeof(time_t)),
1012 dfsan_read_origin_of_first_taint(timep
, sizeof(time_t)), buf
,
1014 *ret_label
= buf_label
;
1015 *ret_origin
= buf_origin
;
1022 SANITIZER_INTERFACE_ATTRIBUTE
1023 char *__dfsw_fgets(char *s
, int size
, FILE *stream
, dfsan_label s_label
,
1024 dfsan_label size_label
, dfsan_label stream_label
,
1025 dfsan_label
*ret_label
) {
1026 char *ret
= fgets(s
, size
, stream
);
1028 dfsan_set_label(0, ret
, strlen(ret
) + 1);
1029 *ret_label
= s_label
;
1036 SANITIZER_INTERFACE_ATTRIBUTE
1037 char *__dfso_fgets(char *s
, int size
, FILE *stream
, dfsan_label s_label
,
1038 dfsan_label size_label
, dfsan_label stream_label
,
1039 dfsan_label
*ret_label
, dfsan_origin s_origin
,
1040 dfsan_origin size_origin
, dfsan_origin stream_origin
,
1041 dfsan_origin
*ret_origin
) {
1042 char *ret
= __dfsw_fgets(s
, size
, stream
, s_label
, size_label
, stream_label
,
1045 *ret_origin
= s_origin
;
1049 SANITIZER_INTERFACE_ATTRIBUTE
1050 char *__dfsw_getcwd(char *buf
, size_t size
, dfsan_label buf_label
,
1051 dfsan_label size_label
, dfsan_label
*ret_label
) {
1052 char *ret
= getcwd(buf
, size
);
1054 dfsan_set_label(0, ret
, strlen(ret
) + 1);
1055 *ret_label
= buf_label
;
1062 SANITIZER_INTERFACE_ATTRIBUTE
1063 char *__dfso_getcwd(char *buf
, size_t size
, dfsan_label buf_label
,
1064 dfsan_label size_label
, dfsan_label
*ret_label
,
1065 dfsan_origin buf_origin
, dfsan_origin size_origin
,
1066 dfsan_origin
*ret_origin
) {
1067 char *ret
= __dfsw_getcwd(buf
, size
, buf_label
, size_label
, ret_label
);
1069 *ret_origin
= buf_origin
;
1073 SANITIZER_INTERFACE_ATTRIBUTE
1074 char *__dfsw_get_current_dir_name(dfsan_label
*ret_label
) {
1075 char *ret
= get_current_dir_name();
1077 dfsan_set_label(0, ret
, strlen(ret
) + 1);
1082 SANITIZER_INTERFACE_ATTRIBUTE
1083 char *__dfso_get_current_dir_name(dfsan_label
*ret_label
,
1084 dfsan_origin
*ret_origin
) {
1085 return __dfsw_get_current_dir_name(ret_label
);
1088 // This function is only available for glibc 2.25 or newer. Mark it weak so
1089 // linking succeeds with older glibcs.
1090 SANITIZER_WEAK_ATTRIBUTE
int getentropy(void *buffer
, size_t length
);
1092 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_getentropy(void *buffer
, size_t length
,
1093 dfsan_label buffer_label
,
1094 dfsan_label length_label
,
1095 dfsan_label
*ret_label
) {
1096 int ret
= getentropy(buffer
, length
);
1098 dfsan_set_label(0, buffer
, length
);
1104 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_getentropy(void *buffer
, size_t length
,
1105 dfsan_label buffer_label
,
1106 dfsan_label length_label
,
1107 dfsan_label
*ret_label
,
1108 dfsan_origin buffer_origin
,
1109 dfsan_origin length_origin
,
1110 dfsan_origin
*ret_origin
) {
1111 return __dfsw_getentropy(buffer
, length
, buffer_label
, length_label
,
1115 SANITIZER_INTERFACE_ATTRIBUTE
1116 int __dfsw_gethostname(char *name
, size_t len
, dfsan_label name_label
,
1117 dfsan_label len_label
, dfsan_label
*ret_label
) {
1118 int ret
= gethostname(name
, len
);
1120 dfsan_set_label(0, name
, strlen(name
) + 1);
1126 SANITIZER_INTERFACE_ATTRIBUTE
1127 int __dfso_gethostname(char *name
, size_t len
, dfsan_label name_label
,
1128 dfsan_label len_label
, dfsan_label
*ret_label
,
1129 dfsan_origin name_origin
, dfsan_origin len_origin
,
1130 dfsan_label
*ret_origin
) {
1131 return __dfsw_gethostname(name
, len
, name_label
, len_label
, ret_label
);
1134 SANITIZER_INTERFACE_ATTRIBUTE
1135 int __dfsw_getrlimit(int resource
, struct rlimit
*rlim
,
1136 dfsan_label resource_label
, dfsan_label rlim_label
,
1137 dfsan_label
*ret_label
) {
1138 int ret
= getrlimit(resource
, rlim
);
1140 dfsan_set_label(0, rlim
, sizeof(struct rlimit
));
1146 SANITIZER_INTERFACE_ATTRIBUTE
1147 int __dfso_getrlimit(int resource
, struct rlimit
*rlim
,
1148 dfsan_label resource_label
, dfsan_label rlim_label
,
1149 dfsan_label
*ret_label
, dfsan_origin resource_origin
,
1150 dfsan_origin rlim_origin
, dfsan_origin
*ret_origin
) {
1151 return __dfsw_getrlimit(resource
, rlim
, resource_label
, rlim_label
,
1155 SANITIZER_INTERFACE_ATTRIBUTE
1156 int __dfsw_getrusage(int who
, struct rusage
*usage
, dfsan_label who_label
,
1157 dfsan_label usage_label
, dfsan_label
*ret_label
) {
1158 int ret
= getrusage(who
, usage
);
1160 dfsan_set_label(0, usage
, sizeof(struct rusage
));
1166 SANITIZER_INTERFACE_ATTRIBUTE
1167 int __dfso_getrusage(int who
, struct rusage
*usage
, dfsan_label who_label
,
1168 dfsan_label usage_label
, dfsan_label
*ret_label
,
1169 dfsan_origin who_origin
, dfsan_origin usage_origin
,
1170 dfsan_label
*ret_origin
) {
1171 return __dfsw_getrusage(who
, usage
, who_label
, usage_label
, ret_label
);
1174 SANITIZER_INTERFACE_ATTRIBUTE
1175 char *__dfsw_strcpy(char *dest
, const char *src
, dfsan_label dst_label
,
1176 dfsan_label src_label
, dfsan_label
*ret_label
) {
1177 char *ret
= strcpy(dest
, src
);
1179 dfsan_mem_shadow_transfer(dest
, src
, strlen(src
) + 1);
1181 *ret_label
= dst_label
;
1185 SANITIZER_INTERFACE_ATTRIBUTE
1186 char *__dfso_strcpy(char *dest
, const char *src
, dfsan_label dst_label
,
1187 dfsan_label src_label
, dfsan_label
*ret_label
,
1188 dfsan_origin dst_origin
, dfsan_origin src_origin
,
1189 dfsan_origin
*ret_origin
) {
1190 char *ret
= strcpy(dest
, src
);
1192 size_t str_len
= strlen(src
) + 1;
1193 dfsan_mem_origin_transfer(dest
, src
, str_len
);
1194 dfsan_mem_shadow_transfer(dest
, src
, str_len
);
1196 *ret_label
= dst_label
;
1197 *ret_origin
= dst_origin
;
1201 static long int dfsan_strtol(const char *nptr
, char **endptr
, int base
,
1202 char **tmp_endptr
) {
1204 long int ret
= strtol(nptr
, tmp_endptr
, base
);
1206 *endptr
= *tmp_endptr
;
1210 static void dfsan_strtolong_label(const char *nptr
, const char *tmp_endptr
,
1211 dfsan_label base_label
,
1212 dfsan_label
*ret_label
) {
1213 if (tmp_endptr
> nptr
) {
1214 // If *tmp_endptr is '\0' include its label as well.
1215 *ret_label
= dfsan_union(
1217 dfsan_read_label(nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1)));
1223 static void dfsan_strtolong_origin(const char *nptr
, const char *tmp_endptr
,
1224 dfsan_label base_label
,
1225 dfsan_label
*ret_label
,
1226 dfsan_origin base_origin
,
1227 dfsan_origin
*ret_origin
) {
1228 if (tmp_endptr
> nptr
) {
1229 // When multiple inputs are tainted, we propagate one of its origins.
1230 // Because checking if base_label is tainted does not need additional
1231 // computation, we prefer to propagating base_origin.
1232 *ret_origin
= base_label
1234 : dfsan_read_origin_of_first_taint(
1235 nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1));
1239 SANITIZER_INTERFACE_ATTRIBUTE
1240 long int __dfsw_strtol(const char *nptr
, char **endptr
, int base
,
1241 dfsan_label nptr_label
, dfsan_label endptr_label
,
1242 dfsan_label base_label
, dfsan_label
*ret_label
) {
1244 long int ret
= dfsan_strtol(nptr
, endptr
, base
, &tmp_endptr
);
1245 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1249 SANITIZER_INTERFACE_ATTRIBUTE
1250 long int __dfso_strtol(const char *nptr
, char **endptr
, int base
,
1251 dfsan_label nptr_label
, dfsan_label endptr_label
,
1252 dfsan_label base_label
, dfsan_label
*ret_label
,
1253 dfsan_origin nptr_origin
, dfsan_origin endptr_origin
,
1254 dfsan_origin base_origin
, dfsan_origin
*ret_origin
) {
1256 long int ret
= dfsan_strtol(nptr
, endptr
, base
, &tmp_endptr
);
1257 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1258 dfsan_strtolong_origin(nptr
, tmp_endptr
, base_label
, ret_label
, base_origin
,
1263 static double dfsan_strtod(const char *nptr
, char **endptr
, char **tmp_endptr
) {
1265 double ret
= strtod(nptr
, tmp_endptr
);
1267 *endptr
= *tmp_endptr
;
1271 static void dfsan_strtod_label(const char *nptr
, const char *tmp_endptr
,
1272 dfsan_label
*ret_label
) {
1273 if (tmp_endptr
> nptr
) {
1274 // If *tmp_endptr is '\0' include its label as well.
1275 *ret_label
= dfsan_read_label(
1277 tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1));
1283 SANITIZER_INTERFACE_ATTRIBUTE
1284 double __dfsw_strtod(const char *nptr
, char **endptr
, dfsan_label nptr_label
,
1285 dfsan_label endptr_label
, dfsan_label
*ret_label
) {
1287 double ret
= dfsan_strtod(nptr
, endptr
, &tmp_endptr
);
1288 dfsan_strtod_label(nptr
, tmp_endptr
, ret_label
);
1292 SANITIZER_INTERFACE_ATTRIBUTE
1293 double __dfso_strtod(const char *nptr
, char **endptr
, dfsan_label nptr_label
,
1294 dfsan_label endptr_label
, dfsan_label
*ret_label
,
1295 dfsan_origin nptr_origin
, dfsan_origin endptr_origin
,
1296 dfsan_origin
*ret_origin
) {
1298 double ret
= dfsan_strtod(nptr
, endptr
, &tmp_endptr
);
1299 dfsan_strtod_label(nptr
, tmp_endptr
, ret_label
);
1300 if (tmp_endptr
> nptr
) {
1301 // If *tmp_endptr is '\0' include its label as well.
1302 *ret_origin
= dfsan_read_origin_of_first_taint(
1303 nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1));
1310 static long long int dfsan_strtoll(const char *nptr
, char **endptr
, int base
,
1311 char **tmp_endptr
) {
1313 long long int ret
= strtoll(nptr
, tmp_endptr
, base
);
1315 *endptr
= *tmp_endptr
;
1319 SANITIZER_INTERFACE_ATTRIBUTE
1320 long long int __dfsw_strtoll(const char *nptr
, char **endptr
, int base
,
1321 dfsan_label nptr_label
, dfsan_label endptr_label
,
1322 dfsan_label base_label
, dfsan_label
*ret_label
) {
1324 long long int ret
= dfsan_strtoll(nptr
, endptr
, base
, &tmp_endptr
);
1325 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1329 SANITIZER_INTERFACE_ATTRIBUTE
1330 long long int __dfso_strtoll(const char *nptr
, char **endptr
, int base
,
1331 dfsan_label nptr_label
, dfsan_label endptr_label
,
1332 dfsan_label base_label
, dfsan_label
*ret_label
,
1333 dfsan_origin nptr_origin
,
1334 dfsan_origin endptr_origin
,
1335 dfsan_origin base_origin
,
1336 dfsan_origin
*ret_origin
) {
1338 long long int ret
= dfsan_strtoll(nptr
, endptr
, base
, &tmp_endptr
);
1339 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1340 dfsan_strtolong_origin(nptr
, tmp_endptr
, base_label
, ret_label
, base_origin
,
1345 static unsigned long int dfsan_strtoul(const char *nptr
, char **endptr
,
1346 int base
, char **tmp_endptr
) {
1348 unsigned long int ret
= strtoul(nptr
, tmp_endptr
, base
);
1350 *endptr
= *tmp_endptr
;
1354 SANITIZER_INTERFACE_ATTRIBUTE
1355 unsigned long int __dfsw_strtoul(const char *nptr
, char **endptr
, int base
,
1356 dfsan_label nptr_label
, dfsan_label endptr_label
,
1357 dfsan_label base_label
, dfsan_label
*ret_label
) {
1359 unsigned long int ret
= dfsan_strtoul(nptr
, endptr
, base
, &tmp_endptr
);
1360 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1364 SANITIZER_INTERFACE_ATTRIBUTE
1365 unsigned long int __dfso_strtoul(
1366 const char *nptr
, char **endptr
, int base
, dfsan_label nptr_label
,
1367 dfsan_label endptr_label
, dfsan_label base_label
, dfsan_label
*ret_label
,
1368 dfsan_origin nptr_origin
, dfsan_origin endptr_origin
,
1369 dfsan_origin base_origin
, dfsan_origin
*ret_origin
) {
1371 unsigned long int ret
= dfsan_strtoul(nptr
, endptr
, base
, &tmp_endptr
);
1372 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1373 dfsan_strtolong_origin(nptr
, tmp_endptr
, base_label
, ret_label
, base_origin
,
1378 static long long unsigned int dfsan_strtoull(const char *nptr
, char **endptr
,
1379 int base
, char **tmp_endptr
) {
1381 long long unsigned int ret
= strtoull(nptr
, tmp_endptr
, base
);
1383 *endptr
= *tmp_endptr
;
1387 SANITIZER_INTERFACE_ATTRIBUTE
1388 long long unsigned int __dfsw_strtoull(const char *nptr
, char **endptr
,
1389 int base
, dfsan_label nptr_label
,
1390 dfsan_label endptr_label
,
1391 dfsan_label base_label
,
1392 dfsan_label
*ret_label
) {
1394 long long unsigned int ret
= dfsan_strtoull(nptr
, endptr
, base
, &tmp_endptr
);
1395 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1399 SANITIZER_INTERFACE_ATTRIBUTE
1400 long long unsigned int __dfso_strtoull(
1401 const char *nptr
, char **endptr
, int base
, dfsan_label nptr_label
,
1402 dfsan_label endptr_label
, dfsan_label base_label
, dfsan_label
*ret_label
,
1403 dfsan_origin nptr_origin
, dfsan_origin endptr_origin
,
1404 dfsan_origin base_origin
, dfsan_origin
*ret_origin
) {
1406 long long unsigned int ret
= dfsan_strtoull(nptr
, endptr
, base
, &tmp_endptr
);
1407 dfsan_strtolong_label(nptr
, tmp_endptr
, base_label
, ret_label
);
1408 dfsan_strtolong_origin(nptr
, tmp_endptr
, base_label
, ret_label
, base_origin
,
1413 SANITIZER_INTERFACE_ATTRIBUTE
1414 time_t __dfsw_time(time_t *t
, dfsan_label t_label
, dfsan_label
*ret_label
) {
1415 time_t ret
= time(t
);
1416 if (ret
!= (time_t) -1 && t
) {
1417 dfsan_set_label(0, t
, sizeof(time_t));
1423 SANITIZER_INTERFACE_ATTRIBUTE
1424 time_t __dfso_time(time_t *t
, dfsan_label t_label
, dfsan_label
*ret_label
,
1425 dfsan_origin t_origin
, dfsan_origin
*ret_origin
) {
1426 return __dfsw_time(t
, t_label
, ret_label
);
1429 SANITIZER_INTERFACE_ATTRIBUTE
1430 int __dfsw_inet_pton(int af
, const char *src
, void *dst
, dfsan_label af_label
,
1431 dfsan_label src_label
, dfsan_label dst_label
,
1432 dfsan_label
*ret_label
) {
1433 int ret
= inet_pton(af
, src
, dst
);
1435 dfsan_set_label(dfsan_read_label(src
, strlen(src
) + 1), dst
,
1436 af
== AF_INET
? sizeof(struct in_addr
) : sizeof(in6_addr
));
1442 SANITIZER_INTERFACE_ATTRIBUTE
1443 int __dfso_inet_pton(int af
, const char *src
, void *dst
, dfsan_label af_label
,
1444 dfsan_label src_label
, dfsan_label dst_label
,
1445 dfsan_label
*ret_label
, dfsan_origin af_origin
,
1446 dfsan_origin src_origin
, dfsan_origin dst_origin
,
1447 dfsan_origin
*ret_origin
) {
1448 int ret
= inet_pton(af
, src
, dst
);
1450 int src_len
= strlen(src
) + 1;
1451 dfsan_set_label_origin(
1452 dfsan_read_label(src
, src_len
),
1453 dfsan_read_origin_of_first_taint(src
, src_len
), dst
,
1454 af
== AF_INET
? sizeof(struct in_addr
) : sizeof(in6_addr
));
1460 SANITIZER_INTERFACE_ATTRIBUTE
1461 struct tm
*__dfsw_localtime_r(const time_t *timep
, struct tm
*result
,
1462 dfsan_label timep_label
, dfsan_label result_label
,
1463 dfsan_label
*ret_label
) {
1464 struct tm
*ret
= localtime_r(timep
, result
);
1466 dfsan_set_label(dfsan_read_label(timep
, sizeof(time_t)), result
,
1468 *ret_label
= result_label
;
1475 SANITIZER_INTERFACE_ATTRIBUTE
1476 struct tm
*__dfso_localtime_r(const time_t *timep
, struct tm
*result
,
1477 dfsan_label timep_label
, dfsan_label result_label
,
1478 dfsan_label
*ret_label
, dfsan_origin timep_origin
,
1479 dfsan_origin result_origin
,
1480 dfsan_origin
*ret_origin
) {
1481 struct tm
*ret
= localtime_r(timep
, result
);
1483 dfsan_set_label_origin(
1484 dfsan_read_label(timep
, sizeof(time_t)),
1485 dfsan_read_origin_of_first_taint(timep
, sizeof(time_t)), result
,
1487 *ret_label
= result_label
;
1488 *ret_origin
= result_origin
;
1495 SANITIZER_INTERFACE_ATTRIBUTE
1496 int __dfsw_getpwuid_r(id_t uid
, struct passwd
*pwd
,
1497 char *buf
, size_t buflen
, struct passwd
**result
,
1498 dfsan_label uid_label
, dfsan_label pwd_label
,
1499 dfsan_label buf_label
, dfsan_label buflen_label
,
1500 dfsan_label result_label
, dfsan_label
*ret_label
) {
1501 // Store the data in pwd, the strings referenced from pwd in buf, and the
1502 // address of pwd in *result. On failure, NULL is stored in *result.
1503 int ret
= getpwuid_r(uid
, pwd
, buf
, buflen
, result
);
1505 dfsan_set_label(0, pwd
, sizeof(struct passwd
));
1506 dfsan_set_label(0, buf
, strlen(buf
) + 1);
1509 dfsan_set_label(0, result
, sizeof(struct passwd
*));
1513 SANITIZER_INTERFACE_ATTRIBUTE
1514 int __dfso_getpwuid_r(id_t uid
, struct passwd
*pwd
, char *buf
, size_t buflen
,
1515 struct passwd
**result
, dfsan_label uid_label
,
1516 dfsan_label pwd_label
, dfsan_label buf_label
,
1517 dfsan_label buflen_label
, dfsan_label result_label
,
1518 dfsan_label
*ret_label
, dfsan_origin uid_origin
,
1519 dfsan_origin pwd_origin
, dfsan_origin buf_origin
,
1520 dfsan_origin buflen_origin
, dfsan_origin result_origin
,
1521 dfsan_origin
*ret_origin
) {
1522 return __dfsw_getpwuid_r(uid
, pwd
, buf
, buflen
, result
, uid_label
, pwd_label
,
1523 buf_label
, buflen_label
, result_label
, ret_label
);
1526 SANITIZER_INTERFACE_ATTRIBUTE
1527 int __dfsw_epoll_wait(int epfd
, struct epoll_event
*events
, int maxevents
,
1528 int timeout
, dfsan_label epfd_label
,
1529 dfsan_label events_label
, dfsan_label maxevents_label
,
1530 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
1531 int ret
= epoll_wait(epfd
, events
, maxevents
, timeout
);
1533 dfsan_set_label(0, events
, ret
* sizeof(*events
));
1538 SANITIZER_INTERFACE_ATTRIBUTE
1539 int __dfso_epoll_wait(int epfd
, struct epoll_event
*events
, int maxevents
,
1540 int timeout
, dfsan_label epfd_label
,
1541 dfsan_label events_label
, dfsan_label maxevents_label
,
1542 dfsan_label timeout_label
, dfsan_label
*ret_label
,
1543 dfsan_origin epfd_origin
, dfsan_origin events_origin
,
1544 dfsan_origin maxevents_origin
,
1545 dfsan_origin timeout_origin
, dfsan_origin
*ret_origin
) {
1546 return __dfsw_epoll_wait(epfd
, events
, maxevents
, timeout
, epfd_label
,
1547 events_label
, maxevents_label
, timeout_label
,
1551 SANITIZER_INTERFACE_ATTRIBUTE
1552 int __dfsw_poll(struct pollfd
*fds
, nfds_t nfds
, int timeout
,
1553 dfsan_label dfs_label
, dfsan_label nfds_label
,
1554 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
1555 int ret
= poll(fds
, nfds
, timeout
);
1557 for (; nfds
> 0; --nfds
) {
1558 dfsan_set_label(0, &fds
[nfds
- 1].revents
, sizeof(fds
[nfds
- 1].revents
));
1565 SANITIZER_INTERFACE_ATTRIBUTE
1566 int __dfso_poll(struct pollfd
*fds
, nfds_t nfds
, int timeout
,
1567 dfsan_label dfs_label
, dfsan_label nfds_label
,
1568 dfsan_label timeout_label
, dfsan_label
*ret_label
,
1569 dfsan_origin dfs_origin
, dfsan_origin nfds_origin
,
1570 dfsan_origin timeout_origin
, dfsan_origin
*ret_origin
) {
1571 return __dfsw_poll(fds
, nfds
, timeout
, dfs_label
, nfds_label
, timeout_label
,
1575 SANITIZER_INTERFACE_ATTRIBUTE
1576 int __dfsw_select(int nfds
, fd_set
*readfds
, fd_set
*writefds
,
1577 fd_set
*exceptfds
, struct timeval
*timeout
,
1578 dfsan_label nfds_label
, dfsan_label readfds_label
,
1579 dfsan_label writefds_label
, dfsan_label exceptfds_label
,
1580 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
1581 int ret
= select(nfds
, readfds
, writefds
, exceptfds
, timeout
);
1582 // Clear everything (also on error) since their content is either set or
1585 dfsan_set_label(0, readfds
, sizeof(fd_set
));
1588 dfsan_set_label(0, writefds
, sizeof(fd_set
));
1591 dfsan_set_label(0, exceptfds
, sizeof(fd_set
));
1593 dfsan_set_label(0, timeout
, sizeof(struct timeval
));
1598 SANITIZER_INTERFACE_ATTRIBUTE
1599 int __dfso_select(int nfds
, fd_set
*readfds
, fd_set
*writefds
,
1600 fd_set
*exceptfds
, struct timeval
*timeout
,
1601 dfsan_label nfds_label
, dfsan_label readfds_label
,
1602 dfsan_label writefds_label
, dfsan_label exceptfds_label
,
1603 dfsan_label timeout_label
, dfsan_label
*ret_label
,
1604 dfsan_origin nfds_origin
, dfsan_origin readfds_origin
,
1605 dfsan_origin writefds_origin
, dfsan_origin exceptfds_origin
,
1606 dfsan_origin timeout_origin
, dfsan_origin
*ret_origin
) {
1607 return __dfsw_select(nfds
, readfds
, writefds
, exceptfds
, timeout
, nfds_label
,
1608 readfds_label
, writefds_label
, exceptfds_label
,
1609 timeout_label
, ret_label
);
1612 SANITIZER_INTERFACE_ATTRIBUTE
1613 int __dfsw_sched_getaffinity(pid_t pid
, size_t cpusetsize
, cpu_set_t
*mask
,
1614 dfsan_label pid_label
,
1615 dfsan_label cpusetsize_label
,
1616 dfsan_label mask_label
, dfsan_label
*ret_label
) {
1617 int ret
= sched_getaffinity(pid
, cpusetsize
, mask
);
1619 dfsan_set_label(0, mask
, cpusetsize
);
1625 SANITIZER_INTERFACE_ATTRIBUTE
1626 int __dfso_sched_getaffinity(pid_t pid
, size_t cpusetsize
, cpu_set_t
*mask
,
1627 dfsan_label pid_label
,
1628 dfsan_label cpusetsize_label
,
1629 dfsan_label mask_label
, dfsan_label
*ret_label
,
1630 dfsan_origin pid_origin
,
1631 dfsan_origin cpusetsize_origin
,
1632 dfsan_origin mask_origin
,
1633 dfsan_origin
*ret_origin
) {
1634 return __dfsw_sched_getaffinity(pid
, cpusetsize
, mask
, pid_label
,
1635 cpusetsize_label
, mask_label
, ret_label
);
1638 SANITIZER_INTERFACE_ATTRIBUTE
1639 int __dfsw_sigemptyset(sigset_t
*set
, dfsan_label set_label
,
1640 dfsan_label
*ret_label
) {
1641 int ret
= sigemptyset(set
);
1642 dfsan_set_label(0, set
, sizeof(sigset_t
));
1647 SANITIZER_INTERFACE_ATTRIBUTE
1648 int __dfso_sigemptyset(sigset_t
*set
, dfsan_label set_label
,
1649 dfsan_label
*ret_label
, dfsan_origin set_origin
,
1650 dfsan_origin
*ret_origin
) {
1651 return __dfsw_sigemptyset(set
, set_label
, ret_label
);
1654 class SignalHandlerScope
{
1656 SignalHandlerScope() {
1657 if (DFsanThread
*t
= GetCurrentThread())
1658 t
->EnterSignalHandler();
1660 ~SignalHandlerScope() {
1661 if (DFsanThread
*t
= GetCurrentThread())
1662 t
->LeaveSignalHandler();
1666 // Clear DFSan runtime TLS state at the end of a scope.
1668 // Implementation must be async-signal-safe and use small data size, because
1669 // instances of this class may live on the signal handler stack.
1671 // DFSan uses TLS to pass metadata of arguments and return values. When an
1672 // instrumented function accesses the TLS, if a signal callback happens, and the
1673 // callback calls other instrumented functions with updating the same TLS, the
1674 // TLS is in an inconsistent state after the callback ends. This may cause
1675 // either under-tainting or over-tainting.
1677 // The current implementation simply resets TLS at restore. This prevents from
1678 // over-tainting. Although under-tainting may still happen, a taint flow can be
1679 // found eventually if we run a DFSan-instrumented program multiple times. The
1680 // alternative option is saving the entire TLS. However the TLS storage takes
1681 // 2k bytes, and signal calls could be nested. So it does not seem worth.
1682 class ScopedClearThreadLocalState
{
1684 ScopedClearThreadLocalState() {}
1685 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); }
1688 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls.
1689 const int kMaxSignals
= 1024;
1690 static atomic_uintptr_t sigactions
[kMaxSignals
];
1692 static void SignalHandler(int signo
) {
1693 SignalHandlerScope signal_handler_scope
;
1694 ScopedClearThreadLocalState scoped_clear_tls
;
1696 // Clear shadows for all inputs provided by system.
1697 dfsan_clear_arg_tls(0, sizeof(dfsan_label
));
1699 typedef void (*signal_cb
)(int x
);
1701 (signal_cb
)atomic_load(&sigactions
[signo
], memory_order_relaxed
);
1705 static void SignalAction(int signo
, siginfo_t
*si
, void *uc
) {
1706 SignalHandlerScope signal_handler_scope
;
1707 ScopedClearThreadLocalState scoped_clear_tls
;
1709 // Clear shadows for all inputs provided by system. Similar to SignalHandler.
1710 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label
));
1711 dfsan_set_label(0, si
, sizeof(*si
));
1712 dfsan_set_label(0, uc
, sizeof(ucontext_t
));
1714 typedef void (*sigaction_cb
)(int, siginfo_t
*, void *);
1716 (sigaction_cb
)atomic_load(&sigactions
[signo
], memory_order_relaxed
);
1720 SANITIZER_INTERFACE_ATTRIBUTE
1721 int __dfsw_sigaction(int signum
, const struct sigaction
*act
,
1722 struct sigaction
*oldact
, dfsan_label signum_label
,
1723 dfsan_label act_label
, dfsan_label oldact_label
,
1724 dfsan_label
*ret_label
) {
1725 CHECK_LT(signum
, kMaxSignals
);
1726 SignalSpinLocker lock
;
1727 uptr old_cb
= atomic_load(&sigactions
[signum
], memory_order_relaxed
);
1728 struct sigaction new_act
;
1729 struct sigaction
*pnew_act
= act
? &new_act
: nullptr;
1731 internal_memcpy(pnew_act
, act
, sizeof(struct sigaction
));
1732 if (pnew_act
->sa_flags
& SA_SIGINFO
) {
1733 uptr cb
= (uptr
)(pnew_act
->sa_sigaction
);
1734 if (cb
!= (uptr
)SIG_IGN
&& cb
!= (uptr
)SIG_DFL
) {
1735 atomic_store(&sigactions
[signum
], cb
, memory_order_relaxed
);
1736 pnew_act
->sa_sigaction
= SignalAction
;
1739 uptr cb
= (uptr
)(pnew_act
->sa_handler
);
1740 if (cb
!= (uptr
)SIG_IGN
&& cb
!= (uptr
)SIG_DFL
) {
1741 atomic_store(&sigactions
[signum
], cb
, memory_order_relaxed
);
1742 pnew_act
->sa_handler
= SignalHandler
;
1747 int ret
= sigaction(signum
, pnew_act
, oldact
);
1749 if (ret
== 0 && oldact
) {
1750 if (oldact
->sa_flags
& SA_SIGINFO
) {
1751 if (oldact
->sa_sigaction
== SignalAction
)
1752 oldact
->sa_sigaction
= (decltype(oldact
->sa_sigaction
))old_cb
;
1754 if (oldact
->sa_handler
== SignalHandler
)
1755 oldact
->sa_handler
= (decltype(oldact
->sa_handler
))old_cb
;
1760 dfsan_set_label(0, oldact
, sizeof(struct sigaction
));
1766 SANITIZER_INTERFACE_ATTRIBUTE
1767 int __dfso_sigaction(int signum
, const struct sigaction
*act
,
1768 struct sigaction
*oldact
, dfsan_label signum_label
,
1769 dfsan_label act_label
, dfsan_label oldact_label
,
1770 dfsan_label
*ret_label
, dfsan_origin signum_origin
,
1771 dfsan_origin act_origin
, dfsan_origin oldact_origin
,
1772 dfsan_origin
*ret_origin
) {
1773 return __dfsw_sigaction(signum
, act
, oldact
, signum_label
, act_label
,
1774 oldact_label
, ret_label
);
1777 static sighandler_t
dfsan_signal(int signum
, sighandler_t handler
,
1778 dfsan_label
*ret_label
) {
1779 CHECK_LT(signum
, kMaxSignals
);
1780 SignalSpinLocker lock
;
1781 uptr old_cb
= atomic_load(&sigactions
[signum
], memory_order_relaxed
);
1782 if (handler
!= SIG_IGN
&& handler
!= SIG_DFL
) {
1783 atomic_store(&sigactions
[signum
], (uptr
)handler
, memory_order_relaxed
);
1784 handler
= &SignalHandler
;
1787 sighandler_t ret
= signal(signum
, handler
);
1789 if (ret
== SignalHandler
)
1790 ret
= (sighandler_t
)old_cb
;
1796 SANITIZER_INTERFACE_ATTRIBUTE
1797 sighandler_t
__dfsw_signal(int signum
, sighandler_t handler
,
1798 dfsan_label signum_label
, dfsan_label handler_label
,
1799 dfsan_label
*ret_label
) {
1800 return dfsan_signal(signum
, handler
, ret_label
);
1803 SANITIZER_INTERFACE_ATTRIBUTE
1804 sighandler_t
__dfso_signal(int signum
, sighandler_t handler
,
1805 dfsan_label signum_label
, dfsan_label handler_label
,
1806 dfsan_label
*ret_label
, dfsan_origin signum_origin
,
1807 dfsan_origin handler_origin
,
1808 dfsan_origin
*ret_origin
) {
1809 return dfsan_signal(signum
, handler
, ret_label
);
1812 SANITIZER_INTERFACE_ATTRIBUTE
1813 int __dfsw_sigaltstack(const stack_t
*ss
, stack_t
*old_ss
, dfsan_label ss_label
,
1814 dfsan_label old_ss_label
, dfsan_label
*ret_label
) {
1815 int ret
= sigaltstack(ss
, old_ss
);
1816 if (ret
!= -1 && old_ss
)
1817 dfsan_set_label(0, old_ss
, sizeof(*old_ss
));
1822 SANITIZER_INTERFACE_ATTRIBUTE
1823 int __dfso_sigaltstack(const stack_t
*ss
, stack_t
*old_ss
, dfsan_label ss_label
,
1824 dfsan_label old_ss_label
, dfsan_label
*ret_label
,
1825 dfsan_origin ss_origin
, dfsan_origin old_ss_origin
,
1826 dfsan_origin
*ret_origin
) {
1827 return __dfsw_sigaltstack(ss
, old_ss
, ss_label
, old_ss_label
, ret_label
);
1830 SANITIZER_INTERFACE_ATTRIBUTE
1831 int __dfsw_gettimeofday(struct timeval
*tv
, struct timezone
*tz
,
1832 dfsan_label tv_label
, dfsan_label tz_label
,
1833 dfsan_label
*ret_label
) {
1834 int ret
= gettimeofday(tv
, tz
);
1836 dfsan_set_label(0, tv
, sizeof(struct timeval
));
1839 dfsan_set_label(0, tz
, sizeof(struct timezone
));
1845 SANITIZER_INTERFACE_ATTRIBUTE
1846 int __dfso_gettimeofday(struct timeval
*tv
, struct timezone
*tz
,
1847 dfsan_label tv_label
, dfsan_label tz_label
,
1848 dfsan_label
*ret_label
, dfsan_origin tv_origin
,
1849 dfsan_origin tz_origin
, dfsan_origin
*ret_origin
) {
1850 return __dfsw_gettimeofday(tv
, tz
, tv_label
, tz_label
, ret_label
);
1853 SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memchr(void *s
, int c
, size_t n
,
1854 dfsan_label s_label
,
1855 dfsan_label c_label
,
1856 dfsan_label n_label
,
1857 dfsan_label
*ret_label
) {
1858 void *ret
= memchr(s
, c
, n
);
1859 if (flags().strict_data_dependencies
) {
1860 *ret_label
= ret
? s_label
: 0;
1863 ret
? reinterpret_cast<char *>(ret
) - reinterpret_cast<char *>(s
) + 1
1866 dfsan_union(dfsan_read_label(s
, len
), dfsan_union(s_label
, c_label
));
1871 SANITIZER_INTERFACE_ATTRIBUTE
void *__dfso_memchr(
1872 void *s
, int c
, size_t n
, dfsan_label s_label
, dfsan_label c_label
,
1873 dfsan_label n_label
, dfsan_label
*ret_label
, dfsan_origin s_origin
,
1874 dfsan_origin c_origin
, dfsan_origin n_origin
, dfsan_origin
*ret_origin
) {
1875 void *ret
= __dfsw_memchr(s
, c
, n
, s_label
, c_label
, n_label
, ret_label
);
1876 if (flags().strict_data_dependencies
) {
1878 *ret_origin
= s_origin
;
1881 ret
? reinterpret_cast<char *>(ret
) - reinterpret_cast<char *>(s
) + 1
1883 dfsan_origin o
= dfsan_read_origin_of_first_taint(s
, len
);
1884 *ret_origin
= o
? o
: (s_label
? s_origin
: c_origin
);
1889 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strrchr(char *s
, int c
,
1890 dfsan_label s_label
,
1891 dfsan_label c_label
,
1892 dfsan_label
*ret_label
) {
1893 char *ret
= strrchr(s
, c
);
1894 if (flags().strict_data_dependencies
) {
1895 *ret_label
= ret
? s_label
: 0;
1898 dfsan_union(dfsan_read_label(s
, strlen(s
) + 1),
1899 dfsan_union(s_label
, c_label
));
1905 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strrchr(
1906 char *s
, int c
, dfsan_label s_label
, dfsan_label c_label
,
1907 dfsan_label
*ret_label
, dfsan_origin s_origin
, dfsan_origin c_origin
,
1908 dfsan_origin
*ret_origin
) {
1909 char *ret
= __dfsw_strrchr(s
, c
, s_label
, c_label
, ret_label
);
1910 if (flags().strict_data_dependencies
) {
1912 *ret_origin
= s_origin
;
1914 size_t s_len
= strlen(s
) + 1;
1915 dfsan_origin o
= dfsan_read_origin_of_first_taint(s
, s_len
);
1916 *ret_origin
= o
? o
: (s_label
? s_origin
: c_origin
);
1922 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strstr(char *haystack
, char *needle
,
1923 dfsan_label haystack_label
,
1924 dfsan_label needle_label
,
1925 dfsan_label
*ret_label
) {
1926 char *ret
= strstr(haystack
, needle
);
1927 if (flags().strict_data_dependencies
) {
1928 *ret_label
= ret
? haystack_label
: 0;
1930 size_t len
= ret
? ret
+ strlen(needle
) - haystack
: strlen(haystack
) + 1;
1932 dfsan_union(dfsan_read_label(haystack
, len
),
1933 dfsan_union(dfsan_read_label(needle
, strlen(needle
) + 1),
1934 dfsan_union(haystack_label
, needle_label
)));
1940 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfso_strstr(char *haystack
, char *needle
,
1941 dfsan_label haystack_label
,
1942 dfsan_label needle_label
,
1943 dfsan_label
*ret_label
,
1944 dfsan_origin haystack_origin
,
1945 dfsan_origin needle_origin
,
1946 dfsan_origin
*ret_origin
) {
1948 __dfsw_strstr(haystack
, needle
, haystack_label
, needle_label
, ret_label
);
1949 if (flags().strict_data_dependencies
) {
1951 *ret_origin
= haystack_origin
;
1953 size_t needle_len
= strlen(needle
);
1954 size_t len
= ret
? ret
+ needle_len
- haystack
: strlen(haystack
) + 1;
1955 dfsan_origin o
= dfsan_read_origin_of_first_taint(haystack
, len
);
1959 o
= dfsan_read_origin_of_first_taint(needle
, needle_len
+ 1);
1960 *ret_origin
= o
? o
: (haystack_label
? haystack_origin
: needle_origin
);
1967 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_nanosleep(const struct timespec
*req
,
1968 struct timespec
*rem
,
1969 dfsan_label req_label
,
1970 dfsan_label rem_label
,
1971 dfsan_label
*ret_label
) {
1972 int ret
= nanosleep(req
, rem
);
1975 // Interrupted by a signal, rem is filled with the remaining time.
1976 dfsan_set_label(0, rem
, sizeof(struct timespec
));
1981 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_nanosleep(
1982 const struct timespec
*req
, struct timespec
*rem
, dfsan_label req_label
,
1983 dfsan_label rem_label
, dfsan_label
*ret_label
, dfsan_origin req_origin
,
1984 dfsan_origin rem_origin
, dfsan_origin
*ret_origin
) {
1985 return __dfsw_nanosleep(req
, rem
, req_label
, rem_label
, ret_label
);
1988 static void clear_msghdr_labels(size_t bytes_written
, struct msghdr
*msg
) {
1989 dfsan_set_label(0, msg
, sizeof(*msg
));
1990 dfsan_set_label(0, msg
->msg_name
, msg
->msg_namelen
);
1991 dfsan_set_label(0, msg
->msg_control
, msg
->msg_controllen
);
1992 for (size_t i
= 0; bytes_written
> 0; ++i
) {
1993 assert(i
< msg
->msg_iovlen
);
1994 struct iovec
*iov
= &msg
->msg_iov
[i
];
1995 size_t iov_written
=
1996 bytes_written
< iov
->iov_len
? bytes_written
: iov
->iov_len
;
1997 dfsan_set_label(0, iov
->iov_base
, iov_written
);
1998 bytes_written
-= iov_written
;
2002 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_recvmmsg(
2003 int sockfd
, struct mmsghdr
*msgvec
, unsigned int vlen
, int flags
,
2004 struct timespec
*timeout
, dfsan_label sockfd_label
,
2005 dfsan_label msgvec_label
, dfsan_label vlen_label
, dfsan_label flags_label
,
2006 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
2007 int ret
= recvmmsg(sockfd
, msgvec
, vlen
, flags
, timeout
);
2008 for (int i
= 0; i
< ret
; ++i
) {
2009 dfsan_set_label(0, &msgvec
[i
].msg_len
, sizeof(msgvec
[i
].msg_len
));
2010 clear_msghdr_labels(msgvec
[i
].msg_len
, &msgvec
[i
].msg_hdr
);
2016 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_recvmmsg(
2017 int sockfd
, struct mmsghdr
*msgvec
, unsigned int vlen
, int flags
,
2018 struct timespec
*timeout
, dfsan_label sockfd_label
,
2019 dfsan_label msgvec_label
, dfsan_label vlen_label
, dfsan_label flags_label
,
2020 dfsan_label timeout_label
, dfsan_label
*ret_label
,
2021 dfsan_origin sockfd_origin
, dfsan_origin msgvec_origin
,
2022 dfsan_origin vlen_origin
, dfsan_origin flags_origin
,
2023 dfsan_origin timeout_origin
, dfsan_origin
*ret_origin
) {
2024 return __dfsw_recvmmsg(sockfd
, msgvec
, vlen
, flags
, timeout
, sockfd_label
,
2025 msgvec_label
, vlen_label
, flags_label
, timeout_label
,
2029 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfsw_recvmsg(
2030 int sockfd
, struct msghdr
*msg
, int flags
, dfsan_label sockfd_label
,
2031 dfsan_label msg_label
, dfsan_label flags_label
, dfsan_label
*ret_label
) {
2032 ssize_t ret
= recvmsg(sockfd
, msg
, flags
);
2034 clear_msghdr_labels(ret
, msg
);
2039 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
__dfso_recvmsg(
2040 int sockfd
, struct msghdr
*msg
, int flags
, dfsan_label sockfd_label
,
2041 dfsan_label msg_label
, dfsan_label flags_label
, dfsan_label
*ret_label
,
2042 dfsan_origin sockfd_origin
, dfsan_origin msg_origin
,
2043 dfsan_origin flags_origin
, dfsan_origin
*ret_origin
) {
2044 return __dfsw_recvmsg(sockfd
, msg
, flags
, sockfd_label
, msg_label
,
2045 flags_label
, ret_label
);
2048 SANITIZER_INTERFACE_ATTRIBUTE
int
2049 __dfsw_socketpair(int domain
, int type
, int protocol
, int sv
[2],
2050 dfsan_label domain_label
, dfsan_label type_label
,
2051 dfsan_label protocol_label
, dfsan_label sv_label
,
2052 dfsan_label
*ret_label
) {
2053 int ret
= socketpair(domain
, type
, protocol
, sv
);
2056 dfsan_set_label(0, sv
, sizeof(*sv
) * 2);
2061 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_socketpair(
2062 int domain
, int type
, int protocol
, int sv
[2], dfsan_label domain_label
,
2063 dfsan_label type_label
, dfsan_label protocol_label
, dfsan_label sv_label
,
2064 dfsan_label
*ret_label
, dfsan_origin domain_origin
,
2065 dfsan_origin type_origin
, dfsan_origin protocol_origin
,
2066 dfsan_origin sv_origin
, dfsan_origin
*ret_origin
) {
2067 return __dfsw_socketpair(domain
, type
, protocol
, sv
, domain_label
, type_label
,
2068 protocol_label
, sv_label
, ret_label
);
2071 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_getsockopt(
2072 int sockfd
, int level
, int optname
, void *optval
, socklen_t
*optlen
,
2073 dfsan_label sockfd_label
, dfsan_label level_label
,
2074 dfsan_label optname_label
, dfsan_label optval_label
,
2075 dfsan_label optlen_label
, dfsan_label
*ret_label
) {
2076 int ret
= getsockopt(sockfd
, level
, optname
, optval
, optlen
);
2077 if (ret
!= -1 && optval
&& optlen
) {
2078 dfsan_set_label(0, optlen
, sizeof(*optlen
));
2079 dfsan_set_label(0, optval
, *optlen
);
2085 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_getsockopt(
2086 int sockfd
, int level
, int optname
, void *optval
, socklen_t
*optlen
,
2087 dfsan_label sockfd_label
, dfsan_label level_label
,
2088 dfsan_label optname_label
, dfsan_label optval_label
,
2089 dfsan_label optlen_label
, dfsan_label
*ret_label
,
2090 dfsan_origin sockfd_origin
, dfsan_origin level_origin
,
2091 dfsan_origin optname_origin
, dfsan_origin optval_origin
,
2092 dfsan_origin optlen_origin
, dfsan_origin
*ret_origin
) {
2093 return __dfsw_getsockopt(sockfd
, level
, optname
, optval
, optlen
, sockfd_label
,
2094 level_label
, optname_label
, optval_label
,
2095 optlen_label
, ret_label
);
2098 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_getsockname(
2099 int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
,
2100 dfsan_label sockfd_label
, dfsan_label addr_label
, dfsan_label addrlen_label
,
2101 dfsan_label
*ret_label
) {
2102 socklen_t origlen
= addrlen
? *addrlen
: 0;
2103 int ret
= getsockname(sockfd
, addr
, addrlen
);
2104 if (ret
!= -1 && addr
&& addrlen
) {
2105 socklen_t written_bytes
= origlen
< *addrlen
? origlen
: *addrlen
;
2106 dfsan_set_label(0, addrlen
, sizeof(*addrlen
));
2107 dfsan_set_label(0, addr
, written_bytes
);
2113 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_getsockname(
2114 int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
,
2115 dfsan_label sockfd_label
, dfsan_label addr_label
, dfsan_label addrlen_label
,
2116 dfsan_label
*ret_label
, dfsan_origin sockfd_origin
,
2117 dfsan_origin addr_origin
, dfsan_origin addrlen_origin
,
2118 dfsan_origin
*ret_origin
) {
2119 return __dfsw_getsockname(sockfd
, addr
, addrlen
, sockfd_label
, addr_label
,
2120 addrlen_label
, ret_label
);
2123 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_getpeername(
2124 int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
,
2125 dfsan_label sockfd_label
, dfsan_label addr_label
, dfsan_label addrlen_label
,
2126 dfsan_label
*ret_label
) {
2127 socklen_t origlen
= addrlen
? *addrlen
: 0;
2128 int ret
= getpeername(sockfd
, addr
, addrlen
);
2129 if (ret
!= -1 && addr
&& addrlen
) {
2130 socklen_t written_bytes
= origlen
< *addrlen
? origlen
: *addrlen
;
2131 dfsan_set_label(0, addrlen
, sizeof(*addrlen
));
2132 dfsan_set_label(0, addr
, written_bytes
);
2138 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_getpeername(
2139 int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
,
2140 dfsan_label sockfd_label
, dfsan_label addr_label
, dfsan_label addrlen_label
,
2141 dfsan_label
*ret_label
, dfsan_origin sockfd_origin
,
2142 dfsan_origin addr_origin
, dfsan_origin addrlen_origin
,
2143 dfsan_origin
*ret_origin
) {
2144 return __dfsw_getpeername(sockfd
, addr
, addrlen
, sockfd_label
, addr_label
,
2145 addrlen_label
, ret_label
);
2148 // Type of the function passed to dfsan_set_write_callback.
2149 typedef void (*write_dfsan_callback_t
)(int fd
, const void *buf
, ssize_t count
);
2151 // Calls to dfsan_set_write_callback() set the values in this struct.
2152 // Calls to the custom version of write() read (and invoke) them.
2154 write_dfsan_callback_t write_callback
= nullptr;
2155 } write_callback_info
;
2157 SANITIZER_INTERFACE_ATTRIBUTE
void __dfsw_dfsan_set_write_callback(
2158 write_dfsan_callback_t write_callback
, dfsan_label write_callback_label
,
2159 dfsan_label
*ret_label
) {
2160 write_callback_info
.write_callback
= write_callback
;
2163 SANITIZER_INTERFACE_ATTRIBUTE
void __dfso_dfsan_set_write_callback(
2164 write_dfsan_callback_t write_callback
, dfsan_label write_callback_label
,
2165 dfsan_label
*ret_label
, dfsan_origin write_callback_origin
,
2166 dfsan_origin
*ret_origin
) {
2167 write_callback_info
.write_callback
= write_callback
;
2170 static inline void setup_tls_args_for_write_callback(
2171 dfsan_label fd_label
, dfsan_label buf_label
, dfsan_label count_label
,
2172 bool origins
, dfsan_origin fd_origin
, dfsan_origin buf_origin
,
2173 dfsan_origin count_origin
) {
2174 // The callback code will expect argument shadow labels in the args TLS,
2175 // and origin labels in the origin args TLS.
2176 // Previously this was done by a trampoline, but we want to remove this:
2177 // https://github.com/llvm/llvm-project/issues/54172
2179 // Instead, this code is manually setting up the args TLS data.
2181 // The offsets used need to correspond with the instrumentation code,
2182 // see llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
2183 // DFSanFunction::getShadowForTLSArgument.
2184 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L1684
2185 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L125
2187 // Here the arguments are all primitives, but it can be more complex
2188 // to compute offsets for array/aggregate type arguments.
2190 // TODO(browneee): Consider a builtin to improve maintainabliity.
2191 // With a builtin, we would provide the argument labels via builtin,
2192 // and the builtin would reuse parts of the instrumentation code to ensure
2193 // that this code and the instrumentation can never be out of sync.
2194 // Note: Currently DFSan instrumentation does not run on this code, so
2195 // the builtin may need to be handled outside DFSan instrumentation.
2196 dfsan_set_arg_tls(0, fd_label
);
2197 dfsan_set_arg_tls(1, buf_label
);
2198 dfsan_set_arg_tls(2, count_label
);
2200 dfsan_set_arg_origin_tls(0, fd_origin
);
2201 dfsan_set_arg_origin_tls(1, buf_origin
);
2202 dfsan_set_arg_origin_tls(2, count_origin
);
2206 SANITIZER_INTERFACE_ATTRIBUTE
int
2207 __dfsw_write(int fd
, const void *buf
, size_t count
,
2208 dfsan_label fd_label
, dfsan_label buf_label
,
2209 dfsan_label count_label
, dfsan_label
*ret_label
) {
2210 if (write_callback_info
.write_callback
) {
2211 setup_tls_args_for_write_callback(fd_label
, buf_label
, count_label
, false,
2213 write_callback_info
.write_callback(fd
, buf
, count
);
2217 return write(fd
, buf
, count
);
2220 SANITIZER_INTERFACE_ATTRIBUTE
int __dfso_write(
2221 int fd
, const void *buf
, size_t count
, dfsan_label fd_label
,
2222 dfsan_label buf_label
, dfsan_label count_label
, dfsan_label
*ret_label
,
2223 dfsan_origin fd_origin
, dfsan_origin buf_origin
, dfsan_origin count_origin
,
2224 dfsan_origin
*ret_origin
) {
2225 if (write_callback_info
.write_callback
) {
2226 setup_tls_args_for_write_callback(fd_label
, buf_label
, count_label
, true,
2227 fd_origin
, buf_origin
, count_origin
);
2228 write_callback_info
.write_callback(fd
, buf
, count
);
2232 return write(fd
, buf
, count
);
2234 } // namespace __dfsan
2236 // Type used to extract a dfsan_label with va_arg()
2237 typedef int dfsan_label_va
;
2239 // Formats a chunk either a constant string or a single format directive (e.g.,
2242 Formatter(char *str_
, const char *fmt_
, size_t size_
)
2253 char *tmp_fmt
= build_format_string();
2255 snprintf(str
+ str_off
, str_off
< size
? size
- str_off
: 0, tmp_fmt
,
2256 0 /* used only to avoid warnings */);
2261 template <typename T
> int format(T arg
) {
2262 char *tmp_fmt
= build_format_string();
2265 retval
= snprintf(str
+ str_off
, str_off
< size
? size
- str_off
: 0,
2266 tmp_fmt
, width
, arg
);
2268 retval
= snprintf(str
+ str_off
, str_off
< size
? size
- str_off
: 0,
2276 char *tmp_fmt
= build_format_string(true);
2278 int retval
= sscanf(str
+ str_off
, tmp_fmt
, &read_count
);
2280 if (-1 == num_scanned
)
2282 num_scanned
+= retval
;
2288 template <typename T
>
2290 char *tmp_fmt
= build_format_string(true);
2292 int retval
= sscanf(str
+ str_off
, tmp_fmt
, arg
, &read_count
);
2294 if (-1 == num_scanned
)
2296 num_scanned
+= retval
;
2302 // with_n -> toggles adding %n on/off; off by default
2303 char *build_format_string(bool with_n
= false) {
2304 size_t fmt_size
= fmt_cur
- fmt_start
+ 1;
2305 size_t add_size
= 0;
2308 char *new_fmt
= (char *)malloc(fmt_size
+ 1 + add_size
);
2310 internal_memcpy(new_fmt
, fmt_start
, fmt_size
);
2312 new_fmt
[fmt_size
] = '\0';
2314 new_fmt
[fmt_size
] = '%';
2315 new_fmt
[fmt_size
+ 1] = 'n';
2316 new_fmt
[fmt_size
+ 2] = '\0';
2322 char *str_cur() { return str
+ str_off
; }
2324 size_t num_written_bytes(int retval
) {
2329 size_t num_avail
= str_off
< size
? size
- str_off
: 0;
2330 if (num_avail
== 0) {
2334 size_t num_written
= retval
;
2335 // A return value of {v,}snprintf of size or more means that the output was
2337 if (num_written
>= num_avail
) {
2338 num_written
-= num_avail
;
2347 const char *fmt_start
;
2348 const char *fmt_cur
;
2354 // Formats the input and propagates the input labels to the output. The output
2355 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and
2356 // 'ap' are the format string and the list of arguments for formatting. Returns
2357 // the return value vsnprintf would return.
2359 // The function tokenizes the format string in chunks representing either a
2360 // constant string or a single format directive (e.g., '%.3f') and formats each
2361 // chunk independently into the output string. This approach allows to figure
2362 // out which bytes of the output string depends on which argument and thus to
2363 // propagate labels more precisely.
2365 // WARNING: This implementation does not support conversion specifiers with
2366 // positional arguments.
2367 static int format_buffer(char *str
, size_t size
, const char *fmt
,
2368 dfsan_label
*va_labels
, dfsan_label
*ret_label
,
2369 dfsan_origin
*va_origins
, dfsan_origin
*ret_origin
,
2371 Formatter
formatter(str
, fmt
, size
);
2373 while (*formatter
.fmt_cur
) {
2374 formatter
.fmt_start
= formatter
.fmt_cur
;
2375 formatter
.width
= -1;
2378 if (*formatter
.fmt_cur
!= '%') {
2379 // Ordinary character. Consume all the characters until a '%' or the end
2381 for (; *(formatter
.fmt_cur
+ 1) && *(formatter
.fmt_cur
+ 1) != '%';
2382 ++formatter
.fmt_cur
) {}
2383 retval
= formatter
.format();
2384 dfsan_set_label(0, formatter
.str_cur(),
2385 formatter
.num_written_bytes(retval
));
2387 // Conversion directive. Consume all the characters until a conversion
2388 // specifier or the end of the string.
2389 bool end_fmt
= false;
2390 for (; *formatter
.fmt_cur
&& !end_fmt
; ) {
2391 switch (*++formatter
.fmt_cur
) {
2398 switch (*(formatter
.fmt_cur
- 1)) {
2400 // Also covers the 'hh' case (since the size of the arg is still
2402 retval
= formatter
.format(va_arg(ap
, int));
2405 if (formatter
.fmt_cur
- formatter
.fmt_start
>= 2 &&
2406 *(formatter
.fmt_cur
- 2) == 'l') {
2407 retval
= formatter
.format(va_arg(ap
, long long int));
2409 retval
= formatter
.format(va_arg(ap
, long int));
2413 retval
= formatter
.format(va_arg(ap
, long long int));
2416 retval
= formatter
.format(va_arg(ap
, intmax_t));
2420 retval
= formatter
.format(va_arg(ap
, size_t));
2423 retval
= formatter
.format(va_arg(ap
, int));
2425 if (va_origins
== nullptr)
2426 dfsan_set_label(*va_labels
++, formatter
.str_cur(),
2427 formatter
.num_written_bytes(retval
));
2429 dfsan_set_label_origin(*va_labels
++, *va_origins
++,
2430 formatter
.str_cur(),
2431 formatter
.num_written_bytes(retval
));
2443 if (*(formatter
.fmt_cur
- 1) == 'L') {
2444 retval
= formatter
.format(va_arg(ap
, long double));
2446 retval
= formatter
.format(va_arg(ap
, double));
2448 if (va_origins
== nullptr)
2449 dfsan_set_label(*va_labels
++, formatter
.str_cur(),
2450 formatter
.num_written_bytes(retval
));
2452 dfsan_set_label_origin(*va_labels
++, *va_origins
++,
2453 formatter
.str_cur(),
2454 formatter
.num_written_bytes(retval
));
2459 retval
= formatter
.format(va_arg(ap
, int));
2460 if (va_origins
== nullptr)
2461 dfsan_set_label(*va_labels
++, formatter
.str_cur(),
2462 formatter
.num_written_bytes(retval
));
2464 dfsan_set_label_origin(*va_labels
++, *va_origins
++,
2465 formatter
.str_cur(),
2466 formatter
.num_written_bytes(retval
));
2471 char *arg
= va_arg(ap
, char *);
2472 retval
= formatter
.format(arg
);
2475 dfsan_mem_origin_transfer(formatter
.str_cur(), arg
,
2476 formatter
.num_written_bytes(retval
));
2479 dfsan_mem_shadow_transfer(formatter
.str_cur(), arg
,
2480 formatter
.num_written_bytes(retval
));
2486 retval
= formatter
.format(va_arg(ap
, void *));
2487 if (va_origins
== nullptr)
2488 dfsan_set_label(*va_labels
++, formatter
.str_cur(),
2489 formatter
.num_written_bytes(retval
));
2491 dfsan_set_label_origin(*va_labels
++, *va_origins
++,
2492 formatter
.str_cur(),
2493 formatter
.num_written_bytes(retval
));
2498 int *ptr
= va_arg(ap
, int *);
2499 *ptr
= (int)formatter
.str_off
;
2503 dfsan_set_label(0, ptr
, sizeof(ptr
));
2509 retval
= formatter
.format();
2510 dfsan_set_label(0, formatter
.str_cur(),
2511 formatter
.num_written_bytes(retval
));
2516 formatter
.width
= va_arg(ap
, int);
2532 formatter
.fmt_cur
++;
2533 formatter
.str_off
+= retval
;
2540 // Number of bytes written in total.
2541 return formatter
.str_off
;
2544 // This function is an inverse of format_buffer: we take the input buffer,
2545 // scan it in search for format strings and store the results in the varargs.
2546 // The labels are propagated from the input buffer to the varargs.
2547 static int scan_buffer(char *str
, size_t size
, const char *fmt
,
2548 dfsan_label
*va_labels
, dfsan_label
*ret_label
,
2549 dfsan_origin
*str_origin
, dfsan_origin
*ret_origin
,
2551 Formatter
formatter(str
, fmt
, size
);
2552 while (*formatter
.fmt_cur
) {
2553 formatter
.fmt_start
= formatter
.fmt_cur
;
2554 formatter
.width
= -1;
2555 formatter
.skip
= false;
2558 size_t write_size
= 0;
2559 if (*formatter
.fmt_cur
!= '%') {
2560 // Ordinary character. Consume all the characters until a '%' or the end
2562 for (; *(formatter
.fmt_cur
+ 1) && *(formatter
.fmt_cur
+ 1) != '%';
2563 ++formatter
.fmt_cur
) {
2565 read_count
= formatter
.scan();
2566 dfsan_set_label(0, formatter
.str_cur(),
2567 formatter
.num_written_bytes(read_count
));
2569 // Conversion directive. Consume all the characters until a conversion
2570 // specifier or the end of the string.
2571 bool end_fmt
= false;
2572 for (; *formatter
.fmt_cur
&& !end_fmt
;) {
2573 switch (*++formatter
.fmt_cur
) {
2580 if (formatter
.skip
) {
2581 read_count
= formatter
.scan();
2583 switch (*(formatter
.fmt_cur
- 1)) {
2585 // Also covers the 'hh' case (since the size of the arg is still
2587 dst_ptr
= va_arg(ap
, int *);
2588 read_count
= formatter
.scan((int *)dst_ptr
);
2589 write_size
= sizeof(int);
2592 if (formatter
.fmt_cur
- formatter
.fmt_start
>= 2 &&
2593 *(formatter
.fmt_cur
- 2) == 'l') {
2594 dst_ptr
= va_arg(ap
, long long int *);
2595 read_count
= formatter
.scan((long long int *)dst_ptr
);
2596 write_size
= sizeof(long long int);
2598 dst_ptr
= va_arg(ap
, long int *);
2599 read_count
= formatter
.scan((long int *)dst_ptr
);
2600 write_size
= sizeof(long int);
2604 dst_ptr
= va_arg(ap
, long long int *);
2605 read_count
= formatter
.scan((long long int *)dst_ptr
);
2606 write_size
= sizeof(long long int);
2609 dst_ptr
= va_arg(ap
, intmax_t *);
2610 read_count
= formatter
.scan((intmax_t *)dst_ptr
);
2611 write_size
= sizeof(intmax_t);
2615 dst_ptr
= va_arg(ap
, size_t *);
2616 read_count
= formatter
.scan((size_t *)dst_ptr
);
2617 write_size
= sizeof(size_t);
2620 dst_ptr
= va_arg(ap
, int *);
2621 read_count
= formatter
.scan((int *)dst_ptr
);
2622 write_size
= sizeof(int);
2624 // get the label associated with the string at the corresponding
2626 dfsan_label l
= dfsan_read_label(
2627 formatter
.str_cur(), formatter
.num_written_bytes(read_count
));
2628 dfsan_set_label(l
, dst_ptr
, write_size
);
2629 if (str_origin
!= nullptr) {
2630 dfsan_set_label(l
, dst_ptr
, write_size
);
2631 size_t scan_count
= formatter
.num_written_bytes(read_count
);
2632 size_t size
= scan_count
> write_size
? write_size
: scan_count
;
2633 dfsan_mem_origin_transfer(dst_ptr
, formatter
.str_cur(), size
);
2648 if (formatter
.skip
) {
2649 read_count
= formatter
.scan();
2651 if (*(formatter
.fmt_cur
- 1) == 'L') {
2652 dst_ptr
= va_arg(ap
, long double *);
2653 read_count
= formatter
.scan((long double *)dst_ptr
);
2654 write_size
= sizeof(long double);
2655 } else if (*(formatter
.fmt_cur
- 1) == 'l') {
2656 dst_ptr
= va_arg(ap
, double *);
2657 read_count
= formatter
.scan((double *)dst_ptr
);
2658 write_size
= sizeof(double);
2660 dst_ptr
= va_arg(ap
, float *);
2661 read_count
= formatter
.scan((float *)dst_ptr
);
2662 write_size
= sizeof(float);
2664 dfsan_label l
= dfsan_read_label(
2665 formatter
.str_cur(), formatter
.num_written_bytes(read_count
));
2666 dfsan_set_label(l
, dst_ptr
, write_size
);
2667 if (str_origin
!= nullptr) {
2668 dfsan_set_label(l
, dst_ptr
, write_size
);
2669 size_t scan_count
= formatter
.num_written_bytes(read_count
);
2670 size_t size
= scan_count
> write_size
? write_size
: scan_count
;
2671 dfsan_mem_origin_transfer(dst_ptr
, formatter
.str_cur(), size
);
2678 if (formatter
.skip
) {
2679 read_count
= formatter
.scan();
2681 dst_ptr
= va_arg(ap
, char *);
2682 read_count
= formatter
.scan((char *)dst_ptr
);
2683 write_size
= sizeof(char);
2684 dfsan_label l
= dfsan_read_label(
2685 formatter
.str_cur(), formatter
.num_written_bytes(read_count
));
2686 dfsan_set_label(l
, dst_ptr
, write_size
);
2687 if (str_origin
!= nullptr) {
2688 size_t scan_count
= formatter
.num_written_bytes(read_count
);
2689 size_t size
= scan_count
> write_size
? write_size
: scan_count
;
2690 dfsan_mem_origin_transfer(dst_ptr
, formatter
.str_cur(), size
);
2697 if (formatter
.skip
) {
2698 read_count
= formatter
.scan();
2700 dst_ptr
= va_arg(ap
, char *);
2701 read_count
= formatter
.scan((char *)dst_ptr
);
2702 if (1 == read_count
) {
2703 // special case: we have parsed a single string and we need to
2704 // update read_count with the string size
2705 read_count
= strlen((char *)dst_ptr
);
2708 dfsan_mem_origin_transfer(dst_ptr
, formatter
.str_cur(),
2709 formatter
.num_written_bytes(read_count
));
2711 dfsan_mem_shadow_transfer(dst_ptr
, formatter
.str_cur(),
2712 formatter
.num_written_bytes(read_count
));
2719 if (formatter
.skip
) {
2720 read_count
= formatter
.scan();
2722 dst_ptr
= va_arg(ap
, void *);
2724 formatter
.scan((int *)dst_ptr
); // note: changing void* to int*
2725 // since we need to call sizeof
2726 write_size
= sizeof(int);
2728 dfsan_label l
= dfsan_read_label(
2729 formatter
.str_cur(), formatter
.num_written_bytes(read_count
));
2730 dfsan_set_label(l
, dst_ptr
, write_size
);
2731 if (str_origin
!= nullptr) {
2732 dfsan_set_label(l
, dst_ptr
, write_size
);
2733 size_t scan_count
= formatter
.num_written_bytes(read_count
);
2734 size_t size
= scan_count
> write_size
? write_size
: scan_count
;
2735 dfsan_mem_origin_transfer(dst_ptr
, formatter
.str_cur(), size
);
2742 if (!formatter
.skip
) {
2743 int *ptr
= va_arg(ap
, int *);
2744 *ptr
= (int)formatter
.str_off
;
2746 dfsan_set_label(0, ptr
, sizeof(*ptr
));
2747 if (str_origin
!= nullptr)
2755 read_count
= formatter
.scan();
2760 formatter
.skip
= true;
2769 if (read_count
< 0) {
2770 // There was an error.
2774 formatter
.fmt_cur
++;
2775 formatter
.str_off
+= read_count
;
2778 (void)va_labels
; // Silence unused-but-set-parameter warning
2783 // Number of items scanned in total.
2784 return formatter
.num_scanned
;
2788 SANITIZER_INTERFACE_ATTRIBUTE
2789 int __dfsw_sprintf(char *str
, const char *format
, dfsan_label str_label
,
2790 dfsan_label format_label
, dfsan_label
*va_labels
,
2791 dfsan_label
*ret_label
, ...) {
2793 va_start(ap
, ret_label
);
2795 int ret
= format_buffer(str
, ~0ul, format
, va_labels
, ret_label
, nullptr,
2801 SANITIZER_INTERFACE_ATTRIBUTE
2802 int __dfso_sprintf(char *str
, const char *format
, dfsan_label str_label
,
2803 dfsan_label format_label
, dfsan_label
*va_labels
,
2804 dfsan_label
*ret_label
, dfsan_origin str_origin
,
2805 dfsan_origin format_origin
, dfsan_origin
*va_origins
,
2806 dfsan_origin
*ret_origin
, ...) {
2808 va_start(ap
, ret_origin
);
2809 int ret
= format_buffer(str
, ~0ul, format
, va_labels
, ret_label
, va_origins
,
2815 SANITIZER_INTERFACE_ATTRIBUTE
2816 int __dfsw_snprintf(char *str
, size_t size
, const char *format
,
2817 dfsan_label str_label
, dfsan_label size_label
,
2818 dfsan_label format_label
, dfsan_label
*va_labels
,
2819 dfsan_label
*ret_label
, ...) {
2821 va_start(ap
, ret_label
);
2822 int ret
= format_buffer(str
, size
, format
, va_labels
, ret_label
, nullptr,
2828 SANITIZER_INTERFACE_ATTRIBUTE
2829 int __dfso_snprintf(char *str
, size_t size
, const char *format
,
2830 dfsan_label str_label
, dfsan_label size_label
,
2831 dfsan_label format_label
, dfsan_label
*va_labels
,
2832 dfsan_label
*ret_label
, dfsan_origin str_origin
,
2833 dfsan_origin size_origin
, dfsan_origin format_origin
,
2834 dfsan_origin
*va_origins
, dfsan_origin
*ret_origin
, ...) {
2836 va_start(ap
, ret_origin
);
2837 int ret
= format_buffer(str
, size
, format
, va_labels
, ret_label
, va_origins
,
2843 SANITIZER_INTERFACE_ATTRIBUTE
2844 int __dfsw_sscanf(char *str
, const char *format
, dfsan_label str_label
,
2845 dfsan_label format_label
, dfsan_label
*va_labels
,
2846 dfsan_label
*ret_label
, ...) {
2848 va_start(ap
, ret_label
);
2849 int ret
= scan_buffer(str
, ~0ul, format
, va_labels
, ret_label
, nullptr,
2855 SANITIZER_INTERFACE_ATTRIBUTE
2856 int __dfso_sscanf(char *str
, const char *format
, dfsan_label str_label
,
2857 dfsan_label format_label
, dfsan_label
*va_labels
,
2858 dfsan_label
*ret_label
, dfsan_origin str_origin
,
2859 dfsan_origin format_origin
, dfsan_origin
*va_origins
,
2860 dfsan_origin
*ret_origin
, ...) {
2862 va_start(ap
, ret_origin
);
2863 int ret
= scan_buffer(str
, ~0ul, format
, va_labels
, ret_label
, &str_origin
,
2869 SANITIZER_INTERFACE_ATTRIBUTE
2870 int __dfsw___isoc99_sscanf(char *str
, const char *format
, dfsan_label str_label
,
2871 dfsan_label format_label
, dfsan_label
*va_labels
,
2872 dfsan_label
*ret_label
, ...) {
2874 va_start(ap
, ret_label
);
2875 int ret
= scan_buffer(str
, ~0ul, format
, va_labels
, ret_label
, nullptr,
2881 SANITIZER_INTERFACE_ATTRIBUTE
2882 int __dfso___isoc99_sscanf(char *str
, const char *format
, dfsan_label str_label
,
2883 dfsan_label format_label
, dfsan_label
*va_labels
,
2884 dfsan_label
*ret_label
, dfsan_origin str_origin
,
2885 dfsan_origin format_origin
, dfsan_origin
*va_origins
,
2886 dfsan_origin
*ret_origin
, ...) {
2888 va_start(ap
, ret_origin
);
2889 int ret
= scan_buffer(str
, ~0ul, format
, va_labels
, ret_label
, &str_origin
,
2895 static void BeforeFork() {
2896 StackDepotLockAll();
2897 GetChainedOriginDepot()->LockAll();
2900 static void AfterFork() {
2901 GetChainedOriginDepot()->UnlockAll();
2902 StackDepotUnlockAll();
2905 SANITIZER_INTERFACE_ATTRIBUTE
2906 pid_t
__dfsw_fork(dfsan_label
*ret_label
) {
2912 SANITIZER_INTERFACE_ATTRIBUTE
2913 pid_t
__dfso_fork(dfsan_label
*ret_label
, dfsan_origin
*ret_origin
) {
2915 pid_t pid
= __dfsw_fork(ret_label
);
2920 // Default empty implementations (weak). Users should redefine them.
2921 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard
, u32
*) {}
2922 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init
, u32
*,
2924 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init
, const uptr
*beg
,
2926 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir
, void) {}
2928 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp
, void) {}
2929 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1
, void) {}
2930 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2
, void) {}
2931 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4
, void) {}
2932 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8
, void) {}
2933 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1
,
2935 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2
,
2937 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4
,
2939 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8
,
2941 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch
, void) {}