1 //===-- dfsan.cc ----------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of DataFlowSanitizer.
12 // This file defines the custom functions listed in done_abilist.txt.
13 //===----------------------------------------------------------------------===//
15 #include "sanitizer_common/sanitizer_internal_defs.h"
16 #include "sanitizer_common/sanitizer_linux.h"
18 #include "dfsan/dfsan.h"
20 #include <arpa/inet.h>
32 #include <sys/resource.h>
33 #include <sys/select.h>
36 #include <sys/types.h>
40 using namespace __dfsan
;
43 SANITIZER_INTERFACE_ATTRIBUTE
int
44 __dfsw_stat(const char *path
, struct stat
*buf
, dfsan_label path_label
,
45 dfsan_label buf_label
, dfsan_label
*ret_label
) {
46 int ret
= stat(path
, buf
);
48 dfsan_set_label(0, buf
, sizeof(struct stat
));
53 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_fstat(int fd
, struct stat
*buf
,
55 dfsan_label buf_label
,
56 dfsan_label
*ret_label
) {
57 int ret
= fstat(fd
, buf
);
59 dfsan_set_label(0, buf
, sizeof(struct stat
));
64 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strchr(const char *s
, int c
,
67 dfsan_label
*ret_label
) {
68 for (size_t i
= 0;; ++i
) {
69 if (s
[i
] == c
|| s
[i
] == 0) {
70 if (flags().strict_data_dependencies
) {
73 *ret_label
= dfsan_union(dfsan_read_label(s
, i
+ 1),
74 dfsan_union(s_label
, c_label
));
76 return s
[i
] == 0 ? 0 : const_cast<char *>(s
+i
);
81 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_memcmp(const void *s1
, const void *s2
,
82 size_t n
, dfsan_label s1_label
,
85 dfsan_label
*ret_label
) {
86 const char *cs1
= (const char *) s1
, *cs2
= (const char *) s2
;
87 for (size_t i
= 0; i
!= n
; ++i
) {
88 if (cs1
[i
] != cs2
[i
]) {
89 if (flags().strict_data_dependencies
) {
92 *ret_label
= dfsan_union(dfsan_read_label(cs1
, i
+ 1),
93 dfsan_read_label(cs2
, i
+ 1));
95 return cs1
[i
] - cs2
[i
];
99 if (flags().strict_data_dependencies
) {
102 *ret_label
= dfsan_union(dfsan_read_label(cs1
, n
),
103 dfsan_read_label(cs2
, n
));
108 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strcmp(const char *s1
, const char *s2
,
109 dfsan_label s1_label
,
110 dfsan_label s2_label
,
111 dfsan_label
*ret_label
) {
112 for (size_t i
= 0;; ++i
) {
113 if (s1
[i
] != s2
[i
] || s1
[i
] == 0 || s2
[i
] == 0) {
114 if (flags().strict_data_dependencies
) {
117 *ret_label
= dfsan_union(dfsan_read_label(s1
, i
+ 1),
118 dfsan_read_label(s2
, i
+ 1));
120 return s1
[i
] - s2
[i
];
126 SANITIZER_INTERFACE_ATTRIBUTE
int
127 __dfsw_strcasecmp(const char *s1
, const char *s2
, dfsan_label s1_label
,
128 dfsan_label s2_label
, dfsan_label
*ret_label
) {
129 for (size_t i
= 0;; ++i
) {
130 if (tolower(s1
[i
]) != tolower(s2
[i
]) || s1
[i
] == 0 || s2
[i
] == 0) {
131 if (flags().strict_data_dependencies
) {
134 *ret_label
= dfsan_union(dfsan_read_label(s1
, i
+ 1),
135 dfsan_read_label(s2
, i
+ 1));
137 return s1
[i
] - s2
[i
];
143 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_strncmp(const char *s1
, const char *s2
,
144 size_t n
, dfsan_label s1_label
,
145 dfsan_label s2_label
,
147 dfsan_label
*ret_label
) {
153 for (size_t i
= 0;; ++i
) {
154 if (s1
[i
] != s2
[i
] || s1
[i
] == 0 || s2
[i
] == 0 || i
== n
- 1) {
155 if (flags().strict_data_dependencies
) {
158 *ret_label
= dfsan_union(dfsan_read_label(s1
, i
+ 1),
159 dfsan_read_label(s2
, i
+ 1));
161 return s1
[i
] - s2
[i
];
167 SANITIZER_INTERFACE_ATTRIBUTE
int
168 __dfsw_strncasecmp(const char *s1
, const char *s2
, size_t n
,
169 dfsan_label s1_label
, dfsan_label s2_label
,
170 dfsan_label n_label
, dfsan_label
*ret_label
) {
176 for (size_t i
= 0;; ++i
) {
177 if (tolower(s1
[i
]) != tolower(s2
[i
]) || s1
[i
] == 0 || s2
[i
] == 0 ||
179 if (flags().strict_data_dependencies
) {
182 *ret_label
= dfsan_union(dfsan_read_label(s1
, i
+ 1),
183 dfsan_read_label(s2
, i
+ 1));
185 return s1
[i
] - s2
[i
];
191 SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_calloc(size_t nmemb
, size_t size
,
192 dfsan_label nmemb_label
,
193 dfsan_label size_label
,
194 dfsan_label
*ret_label
) {
195 void *p
= calloc(nmemb
, size
);
196 dfsan_set_label(0, p
, nmemb
* size
);
201 SANITIZER_INTERFACE_ATTRIBUTE
size_t
202 __dfsw_strlen(const char *s
, dfsan_label s_label
, dfsan_label
*ret_label
) {
203 size_t ret
= strlen(s
);
204 if (flags().strict_data_dependencies
) {
207 *ret_label
= dfsan_read_label(s
, ret
+ 1);
213 static void *dfsan_memcpy(void *dest
, const void *src
, size_t n
) {
214 dfsan_label
*sdest
= shadow_for(dest
), *ssrc
= shadow_for((void *)src
);
215 internal_memcpy((void *)sdest
, (void *)ssrc
, n
* sizeof(dfsan_label
));
216 return internal_memcpy(dest
, src
, n
);
219 static void dfsan_memset(void *s
, int c
, dfsan_label c_label
, size_t n
) {
220 internal_memset(s
, c
, n
);
221 dfsan_set_label(c_label
, s
, n
);
224 SANITIZER_INTERFACE_ATTRIBUTE
225 void *__dfsw_memcpy(void *dest
, const void *src
, size_t n
,
226 dfsan_label dest_label
, dfsan_label src_label
,
227 dfsan_label n_label
, dfsan_label
*ret_label
) {
228 *ret_label
= dest_label
;
229 return dfsan_memcpy(dest
, src
, n
);
232 SANITIZER_INTERFACE_ATTRIBUTE
233 void *__dfsw_memset(void *s
, int c
, size_t n
,
234 dfsan_label s_label
, dfsan_label c_label
,
235 dfsan_label n_label
, dfsan_label
*ret_label
) {
236 dfsan_memset(s
, c
, c_label
, n
);
237 *ret_label
= s_label
;
241 SANITIZER_INTERFACE_ATTRIBUTE
char *
242 __dfsw_strdup(const char *s
, dfsan_label s_label
, dfsan_label
*ret_label
) {
243 size_t len
= strlen(s
);
244 void *p
= malloc(len
+1);
245 dfsan_memcpy(p
, s
, len
+1);
247 return static_cast<char *>(p
);
250 SANITIZER_INTERFACE_ATTRIBUTE
char *
251 __dfsw_strncpy(char *s1
, const char *s2
, size_t n
, dfsan_label s1_label
,
252 dfsan_label s2_label
, dfsan_label n_label
,
253 dfsan_label
*ret_label
) {
254 size_t len
= strlen(s2
);
256 dfsan_memcpy(s1
, s2
, len
+1);
257 dfsan_memset(s1
+len
+1, 0, 0, n
-len
-1);
259 dfsan_memcpy(s1
, s2
, n
);
262 *ret_label
= s1_label
;
266 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
267 __dfsw_pread(int fd
, void *buf
, size_t count
, off_t offset
,
268 dfsan_label fd_label
, dfsan_label buf_label
,
269 dfsan_label count_label
, dfsan_label offset_label
,
270 dfsan_label
*ret_label
) {
271 ssize_t ret
= pread(fd
, buf
, count
, offset
);
273 dfsan_set_label(0, buf
, ret
);
278 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
279 __dfsw_read(int fd
, void *buf
, size_t count
,
280 dfsan_label fd_label
, dfsan_label buf_label
,
281 dfsan_label count_label
,
282 dfsan_label
*ret_label
) {
283 ssize_t ret
= read(fd
, buf
, count
);
285 dfsan_set_label(0, buf
, ret
);
290 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_clock_gettime(clockid_t clk_id
,
292 dfsan_label clk_id_label
,
293 dfsan_label tp_label
,
294 dfsan_label
*ret_label
) {
295 int ret
= clock_gettime(clk_id
, tp
);
297 dfsan_set_label(0, tp
, sizeof(struct timespec
));
302 static void unpoison(const void *ptr
, uptr size
) {
303 dfsan_set_label(0, const_cast<void *>(ptr
), size
);
306 // dlopen() ultimately calls mmap() down inside the loader, which generally
307 // doesn't participate in dynamic symbol resolution. Therefore we won't
308 // intercept its calls to mmap, and we have to hook it here.
309 SANITIZER_INTERFACE_ATTRIBUTE
void *
310 __dfsw_dlopen(const char *filename
, int flag
, dfsan_label filename_label
,
311 dfsan_label flag_label
, dfsan_label
*ret_label
) {
312 link_map
*map
= (link_map
*)dlopen(filename
, flag
);
314 ForEachMappedRegion(map
, unpoison
);
319 struct pthread_create_info
{
320 void *(*start_routine_trampoline
)(void *, void *, dfsan_label
, dfsan_label
*);
325 static void *pthread_create_cb(void *p
) {
326 pthread_create_info
pci(*(pthread_create_info
*)p
);
328 dfsan_label ret_label
;
329 return pci
.start_routine_trampoline(pci
.start_routine
, pci
.arg
, 0,
333 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_pthread_create(
334 pthread_t
*thread
, const pthread_attr_t
*attr
,
335 void *(*start_routine_trampoline
)(void *, void *, dfsan_label
,
337 void *start_routine
, void *arg
, dfsan_label thread_label
,
338 dfsan_label attr_label
, dfsan_label start_routine_label
,
339 dfsan_label arg_label
, dfsan_label
*ret_label
) {
340 pthread_create_info
*pci
=
341 (pthread_create_info
*)malloc(sizeof(pthread_create_info
));
342 pci
->start_routine_trampoline
= start_routine_trampoline
;
343 pci
->start_routine
= start_routine
;
345 int rv
= pthread_create(thread
, attr
, pthread_create_cb
, (void *)pci
);
352 struct dl_iterate_phdr_info
{
353 int (*callback_trampoline
)(void *callback
, struct dl_phdr_info
*info
,
354 size_t size
, void *data
, dfsan_label info_label
,
355 dfsan_label size_label
, dfsan_label data_label
,
356 dfsan_label
*ret_label
);
361 int dl_iterate_phdr_cb(struct dl_phdr_info
*info
, size_t size
, void *data
) {
362 dl_iterate_phdr_info
*dipi
= (dl_iterate_phdr_info
*)data
;
363 dfsan_set_label(0, *info
);
364 dfsan_set_label(0, (void *)info
->dlpi_name
, strlen(info
->dlpi_name
) + 1);
365 dfsan_set_label(0, (void *)info
->dlpi_phdr
,
366 sizeof(*info
->dlpi_phdr
) * info
->dlpi_phnum
);
367 dfsan_label ret_label
;
368 return dipi
->callback_trampoline(dipi
->callback
, info
, size
, dipi
->data
, 0, 0,
372 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_dl_iterate_phdr(
373 int (*callback_trampoline
)(void *callback
, struct dl_phdr_info
*info
,
374 size_t size
, void *data
, dfsan_label info_label
,
375 dfsan_label size_label
, dfsan_label data_label
,
376 dfsan_label
*ret_label
),
377 void *callback
, void *data
, dfsan_label callback_label
,
378 dfsan_label data_label
, dfsan_label
*ret_label
) {
379 dl_iterate_phdr_info dipi
= { callback_trampoline
, callback
, data
};
381 return dl_iterate_phdr(dl_iterate_phdr_cb
, &dipi
);
384 SANITIZER_INTERFACE_ATTRIBUTE
385 char *__dfsw_ctime_r(const time_t *timep
, char *buf
, dfsan_label timep_label
,
386 dfsan_label buf_label
, dfsan_label
*ret_label
) {
387 char *ret
= ctime_r(timep
, buf
);
389 dfsan_set_label(dfsan_read_label(timep
, sizeof(time_t)), buf
,
391 *ret_label
= buf_label
;
398 SANITIZER_INTERFACE_ATTRIBUTE
399 char *__dfsw_fgets(char *s
, int size
, FILE *stream
, dfsan_label s_label
,
400 dfsan_label size_label
, dfsan_label stream_label
,
401 dfsan_label
*ret_label
) {
402 char *ret
= fgets(s
, size
, stream
);
404 dfsan_set_label(0, ret
, strlen(ret
) + 1);
405 *ret_label
= s_label
;
412 SANITIZER_INTERFACE_ATTRIBUTE
413 char *__dfsw_getcwd(char *buf
, size_t size
, dfsan_label buf_label
,
414 dfsan_label size_label
, dfsan_label
*ret_label
) {
415 char *ret
= getcwd(buf
, size
);
417 dfsan_set_label(0, ret
, strlen(ret
) + 1);
418 *ret_label
= buf_label
;
425 SANITIZER_INTERFACE_ATTRIBUTE
426 char *__dfsw_get_current_dir_name(dfsan_label
*ret_label
) {
427 char *ret
= get_current_dir_name();
429 dfsan_set_label(0, ret
, strlen(ret
) + 1);
435 SANITIZER_INTERFACE_ATTRIBUTE
436 int __dfsw_gethostname(char *name
, size_t len
, dfsan_label name_label
,
437 dfsan_label len_label
, dfsan_label
*ret_label
) {
438 int ret
= gethostname(name
, len
);
440 dfsan_set_label(0, name
, strlen(name
) + 1);
446 SANITIZER_INTERFACE_ATTRIBUTE
447 int __dfsw_getrlimit(int resource
, struct rlimit
*rlim
,
448 dfsan_label resource_label
, dfsan_label rlim_label
,
449 dfsan_label
*ret_label
) {
450 int ret
= getrlimit(resource
, rlim
);
452 dfsan_set_label(0, rlim
, sizeof(struct rlimit
));
458 SANITIZER_INTERFACE_ATTRIBUTE
459 int __dfsw_getrusage(int who
, struct rusage
*usage
, dfsan_label who_label
,
460 dfsan_label usage_label
, dfsan_label
*ret_label
) {
461 int ret
= getrusage(who
, usage
);
463 dfsan_set_label(0, usage
, sizeof(struct rusage
));
469 SANITIZER_INTERFACE_ATTRIBUTE
470 char *__dfsw_strcpy(char *dest
, const char *src
, dfsan_label dst_label
,
471 dfsan_label src_label
, dfsan_label
*ret_label
) {
472 char *ret
= strcpy(dest
, src
);
474 internal_memcpy(shadow_for(dest
), shadow_for(src
),
475 sizeof(dfsan_label
) * (strlen(src
) + 1));
477 *ret_label
= dst_label
;
481 SANITIZER_INTERFACE_ATTRIBUTE
482 long int __dfsw_strtol(const char *nptr
, char **endptr
, int base
,
483 dfsan_label nptr_label
, dfsan_label endptr_label
,
484 dfsan_label base_label
, dfsan_label
*ret_label
) {
486 long int ret
= strtol(nptr
, &tmp_endptr
, base
);
488 *endptr
= tmp_endptr
;
490 if (tmp_endptr
> nptr
) {
491 // If *tmp_endptr is '\0' include its label as well.
492 *ret_label
= dfsan_union(
494 dfsan_read_label(nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1)));
501 SANITIZER_INTERFACE_ATTRIBUTE
502 double __dfsw_strtod(const char *nptr
, char **endptr
,
503 dfsan_label nptr_label
, dfsan_label endptr_label
,
504 dfsan_label
*ret_label
) {
506 double ret
= strtod(nptr
, &tmp_endptr
);
508 *endptr
= tmp_endptr
;
510 if (tmp_endptr
> nptr
) {
511 // If *tmp_endptr is '\0' include its label as well.
512 *ret_label
= dfsan_read_label(
514 tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1));
521 SANITIZER_INTERFACE_ATTRIBUTE
522 long long int __dfsw_strtoll(const char *nptr
, char **endptr
, int base
,
523 dfsan_label nptr_label
, dfsan_label endptr_label
,
524 dfsan_label base_label
, dfsan_label
*ret_label
) {
526 long long int ret
= strtoll(nptr
, &tmp_endptr
, base
);
528 *endptr
= tmp_endptr
;
530 if (tmp_endptr
> nptr
) {
531 // If *tmp_endptr is '\0' include its label as well.
532 *ret_label
= dfsan_union(
534 dfsan_read_label(nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1)));
541 SANITIZER_INTERFACE_ATTRIBUTE
542 unsigned long int __dfsw_strtoul(const char *nptr
, char **endptr
, int base
,
543 dfsan_label nptr_label
, dfsan_label endptr_label
,
544 dfsan_label base_label
, dfsan_label
*ret_label
) {
546 unsigned long int ret
= strtoul(nptr
, &tmp_endptr
, base
);
548 *endptr
= tmp_endptr
;
550 if (tmp_endptr
> nptr
) {
551 // If *tmp_endptr is '\0' include its label as well.
552 *ret_label
= dfsan_union(
554 dfsan_read_label(nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1)));
561 SANITIZER_INTERFACE_ATTRIBUTE
562 long long unsigned int __dfsw_strtoull(const char *nptr
, char **endptr
,
563 dfsan_label nptr_label
,
564 int base
, dfsan_label endptr_label
,
565 dfsan_label base_label
,
566 dfsan_label
*ret_label
) {
568 long long unsigned int ret
= strtoull(nptr
, &tmp_endptr
, base
);
570 *endptr
= tmp_endptr
;
572 if (tmp_endptr
> nptr
) {
573 // If *tmp_endptr is '\0' include its label as well.
574 *ret_label
= dfsan_union(
576 dfsan_read_label(nptr
, tmp_endptr
- nptr
+ (*tmp_endptr
? 0 : 1)));
583 SANITIZER_INTERFACE_ATTRIBUTE
584 time_t __dfsw_time(time_t *t
, dfsan_label t_label
, dfsan_label
*ret_label
) {
585 time_t ret
= time(t
);
586 if (ret
!= (time_t) -1 && t
) {
587 dfsan_set_label(0, t
, sizeof(time_t));
593 SANITIZER_INTERFACE_ATTRIBUTE
594 int __dfsw_inet_pton(int af
, const char *src
, void *dst
, dfsan_label af_label
,
595 dfsan_label src_label
, dfsan_label dst_label
,
596 dfsan_label
*ret_label
) {
597 int ret
= inet_pton(af
, src
, dst
);
599 dfsan_set_label(dfsan_read_label(src
, strlen(src
) + 1), dst
,
600 af
== AF_INET
? sizeof(struct in_addr
) : sizeof(in6_addr
));
606 SANITIZER_INTERFACE_ATTRIBUTE
607 struct tm
*__dfsw_localtime_r(const time_t *timep
, struct tm
*result
,
608 dfsan_label timep_label
, dfsan_label result_label
,
609 dfsan_label
*ret_label
) {
610 struct tm
*ret
= localtime_r(timep
, result
);
612 dfsan_set_label(dfsan_read_label(timep
, sizeof(time_t)), result
,
614 *ret_label
= result_label
;
621 SANITIZER_INTERFACE_ATTRIBUTE
622 int __dfsw_getpwuid_r(id_t uid
, struct passwd
*pwd
,
623 char *buf
, size_t buflen
, struct passwd
**result
,
624 dfsan_label uid_label
, dfsan_label pwd_label
,
625 dfsan_label buf_label
, dfsan_label buflen_label
,
626 dfsan_label result_label
, dfsan_label
*ret_label
) {
627 // Store the data in pwd, the strings referenced from pwd in buf, and the
628 // address of pwd in *result. On failure, NULL is stored in *result.
629 int ret
= getpwuid_r(uid
, pwd
, buf
, buflen
, result
);
631 dfsan_set_label(0, pwd
, sizeof(struct passwd
));
632 dfsan_set_label(0, buf
, strlen(buf
) + 1);
635 dfsan_set_label(0, result
, sizeof(struct passwd
*));
639 SANITIZER_INTERFACE_ATTRIBUTE
640 int __dfsw_poll(struct pollfd
*fds
, nfds_t nfds
, int timeout
,
641 dfsan_label dfs_label
, dfsan_label nfds_label
,
642 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
643 int ret
= poll(fds
, nfds
, timeout
);
645 for (; nfds
> 0; --nfds
) {
646 dfsan_set_label(0, &fds
[nfds
- 1].revents
, sizeof(fds
[nfds
- 1].revents
));
653 SANITIZER_INTERFACE_ATTRIBUTE
654 int __dfsw_select(int nfds
, fd_set
*readfds
, fd_set
*writefds
,
655 fd_set
*exceptfds
, struct timeval
*timeout
,
656 dfsan_label nfds_label
, dfsan_label readfds_label
,
657 dfsan_label writefds_label
, dfsan_label exceptfds_label
,
658 dfsan_label timeout_label
, dfsan_label
*ret_label
) {
659 int ret
= select(nfds
, readfds
, writefds
, exceptfds
, timeout
);
660 // Clear everything (also on error) since their content is either set or
663 dfsan_set_label(0, readfds
, sizeof(fd_set
));
666 dfsan_set_label(0, writefds
, sizeof(fd_set
));
669 dfsan_set_label(0, exceptfds
, sizeof(fd_set
));
671 dfsan_set_label(0, timeout
, sizeof(struct timeval
));
676 SANITIZER_INTERFACE_ATTRIBUTE
677 int __dfsw_sched_getaffinity(pid_t pid
, size_t cpusetsize
, cpu_set_t
*mask
,
678 dfsan_label pid_label
,
679 dfsan_label cpusetsize_label
,
680 dfsan_label mask_label
, dfsan_label
*ret_label
) {
681 int ret
= sched_getaffinity(pid
, cpusetsize
, mask
);
683 dfsan_set_label(0, mask
, cpusetsize
);
689 SANITIZER_INTERFACE_ATTRIBUTE
690 int __dfsw_sigemptyset(sigset_t
*set
, dfsan_label set_label
,
691 dfsan_label
*ret_label
) {
692 int ret
= sigemptyset(set
);
693 dfsan_set_label(0, set
, sizeof(sigset_t
));
697 SANITIZER_INTERFACE_ATTRIBUTE
698 int __dfsw_sigaction(int signum
, const struct sigaction
*act
,
699 struct sigaction
*oldact
, dfsan_label signum_label
,
700 dfsan_label act_label
, dfsan_label oldact_label
,
701 dfsan_label
*ret_label
) {
702 int ret
= sigaction(signum
, act
, oldact
);
704 dfsan_set_label(0, oldact
, sizeof(struct sigaction
));
710 SANITIZER_INTERFACE_ATTRIBUTE
711 int __dfsw_gettimeofday(struct timeval
*tv
, struct timezone
*tz
,
712 dfsan_label tv_label
, dfsan_label tz_label
,
713 dfsan_label
*ret_label
) {
714 int ret
= gettimeofday(tv
, tz
);
716 dfsan_set_label(0, tv
, sizeof(struct timeval
));
719 dfsan_set_label(0, tz
, sizeof(struct timezone
));
725 SANITIZER_INTERFACE_ATTRIBUTE
void *__dfsw_memchr(void *s
, int c
, size_t n
,
729 dfsan_label
*ret_label
) {
730 void *ret
= memchr(s
, c
, n
);
731 if (flags().strict_data_dependencies
) {
732 *ret_label
= ret
? s_label
: 0;
735 ret
? reinterpret_cast<char *>(ret
) - reinterpret_cast<char *>(s
) + 1
738 dfsan_union(dfsan_read_label(s
, len
), dfsan_union(s_label
, c_label
));
743 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strrchr(char *s
, int c
,
746 dfsan_label
*ret_label
) {
747 char *ret
= strrchr(s
, c
);
748 if (flags().strict_data_dependencies
) {
749 *ret_label
= ret
? s_label
: 0;
752 dfsan_union(dfsan_read_label(s
, strlen(s
) + 1),
753 dfsan_union(s_label
, c_label
));
759 SANITIZER_INTERFACE_ATTRIBUTE
char *__dfsw_strstr(char *haystack
, char *needle
,
760 dfsan_label haystack_label
,
761 dfsan_label needle_label
,
762 dfsan_label
*ret_label
) {
763 char *ret
= strstr(haystack
, needle
);
764 if (flags().strict_data_dependencies
) {
765 *ret_label
= ret
? haystack_label
: 0;
767 size_t len
= ret
? ret
+ strlen(needle
) - haystack
: strlen(haystack
) + 1;
769 dfsan_union(dfsan_read_label(haystack
, len
),
770 dfsan_union(dfsan_read_label(needle
, strlen(needle
) + 1),
771 dfsan_union(haystack_label
, needle_label
)));
777 SANITIZER_INTERFACE_ATTRIBUTE
int __dfsw_nanosleep(const struct timespec
*req
,
778 struct timespec
*rem
,
779 dfsan_label req_label
,
780 dfsan_label rem_label
,
781 dfsan_label
*ret_label
) {
782 int ret
= nanosleep(req
, rem
);
785 // Interrupted by a signal, rem is filled with the remaining time.
786 dfsan_set_label(0, rem
, sizeof(struct timespec
));
791 SANITIZER_INTERFACE_ATTRIBUTE
int
792 __dfsw_socketpair(int domain
, int type
, int protocol
, int sv
[2],
793 dfsan_label domain_label
, dfsan_label type_label
,
794 dfsan_label protocol_label
, dfsan_label sv_label
,
795 dfsan_label
*ret_label
) {
796 int ret
= socketpair(domain
, type
, protocol
, sv
);
799 dfsan_set_label(0, sv
, sizeof(*sv
) * 2);
804 // Type of the trampoline function passed to the custom version of
805 // dfsan_set_write_callback.
806 typedef void (*write_trampoline_t
)(
808 int fd
, const void *buf
, ssize_t count
,
809 dfsan_label fd_label
, dfsan_label buf_label
, dfsan_label count_label
);
811 // Calls to dfsan_set_write_callback() set the values in this struct.
812 // Calls to the custom version of write() read (and invoke) them.
814 write_trampoline_t write_callback_trampoline
= NULL
;
815 void *write_callback
= NULL
;
816 } write_callback_info
;
818 SANITIZER_INTERFACE_ATTRIBUTE
void
819 __dfsw_dfsan_set_write_callback(
820 write_trampoline_t write_callback_trampoline
,
821 void *write_callback
,
822 dfsan_label write_callback_label
,
823 dfsan_label
*ret_label
) {
824 write_callback_info
.write_callback_trampoline
= write_callback_trampoline
;
825 write_callback_info
.write_callback
= write_callback
;
828 SANITIZER_INTERFACE_ATTRIBUTE
int
829 __dfsw_write(int fd
, const void *buf
, size_t count
,
830 dfsan_label fd_label
, dfsan_label buf_label
,
831 dfsan_label count_label
, dfsan_label
*ret_label
) {
832 if (write_callback_info
.write_callback
!= NULL
) {
833 write_callback_info
.write_callback_trampoline(
834 write_callback_info
.write_callback
,
836 fd_label
, buf_label
, count_label
);
840 return write(fd
, buf
, count
);