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