xref: /freebsd/contrib/llvm-project/compiler-rt/lib/dfsan/dfsan_custom.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strsep(char **s, const char *delim,
208                                                   dfsan_label s_label,
209                                                   dfsan_label delim_label,
210                                                   dfsan_label *ret_label) {
211   dfsan_label base_label = dfsan_read_label(s, sizeof(*s));
212   char *base = *s;
213   char *res = strsep(s, delim);
214   if (res != *s) {
215     char *token_start = res;
216     int token_length = strlen(res);
217     // the delimiter byte has been set to NULL
218     dfsan_set_label(0, token_start + token_length, 1);
219   }
220 
221   if (flags().strict_data_dependencies) {
222     *ret_label = res ? base_label : 0;
223   } else {
224     size_t s_bytes_read = (res ? strlen(res) : strlen(base)) + 1;
225     *ret_label = dfsan_union(
226         dfsan_union(base_label, dfsan_read_label(base, sizeof(s_bytes_read))),
227         dfsan_union(dfsan_read_label(delim, strlen(delim) + 1),
228                     dfsan_union(s_label, delim_label)));
229   }
230 
231   return res;
232 }
233 
234 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strsep(
235     char **s, const char *delim, dfsan_label s_label, dfsan_label delim_label,
236     dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin delim_origin,
237     dfsan_origin *ret_origin) {
238   dfsan_origin base_origin = dfsan_read_origin_of_first_taint(s, sizeof(*s));
239   char *res = __dfsw_strsep(s, delim, s_label, delim_label, ret_label);
240   if (flags().strict_data_dependencies) {
241     if (res)
242       *ret_origin = base_origin;
243   } else {
244     if (*ret_label) {
245       if (base_origin) {
246         *ret_origin = base_origin;
247       } else {
248         dfsan_origin o =
249             dfsan_read_origin_of_first_taint(delim, strlen(delim) + 1);
250         *ret_origin = o ? o : (s_label ? s_origin : delim_origin);
251       }
252     }
253   }
254 
255   return res;
256 }
257 
258 static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n,
259                              size_t *bytes_read) {
260   const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
261   for (size_t i = 0; i != n; ++i) {
262     if (cs1[i] != cs2[i]) {
263       *bytes_read = i + 1;
264       return cs1[i] - cs2[i];
265     }
266   }
267   *bytes_read = n;
268   return 0;
269 }
270 
271 static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2,
272                                           size_t pos) {
273   if (flags().strict_data_dependencies)
274     return 0;
275   return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos));
276 }
277 
278 static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos,
279                                     dfsan_label *ret_label,
280                                     dfsan_origin *ret_origin) {
281   *ret_label = dfsan_get_memcmp_label(s1, s2, pos);
282   if (*ret_label == 0)
283     return;
284   dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos);
285   *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos);
286 }
287 
288 static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n,
289                                    dfsan_label *ret_label) {
290   size_t bytes_read;
291   int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
292   *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
293   return r;
294 }
295 
296 static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n,
297                                     dfsan_label *ret_label,
298                                     dfsan_origin *ret_origin) {
299   size_t bytes_read;
300   int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
301   dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
302   return r;
303 }
304 
305 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc,
306                               const void *s1, const void *s2, size_t n,
307                               dfsan_label s1_label, dfsan_label s2_label,
308                               dfsan_label n_label)
309 
310 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc,
311                               const void *s1, const void *s2, size_t n,
312                               dfsan_label s1_label, dfsan_label s2_label,
313                               dfsan_label n_label, dfsan_origin s1_origin,
314                               dfsan_origin s2_origin, dfsan_origin n_origin)
315 
316 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
317                                                 size_t n, dfsan_label s1_label,
318                                                 dfsan_label s2_label,
319                                                 dfsan_label n_label,
320                                                 dfsan_label *ret_label) {
321   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n,
322                              s1_label, s2_label, n_label);
323   return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
324 }
325 
326 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp(
327     const void *s1, const void *s2, size_t n, dfsan_label s1_label,
328     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
329     dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
330     dfsan_origin *ret_origin) {
331   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1,
332                              s2, n, s1_label, s2_label, n_label, s1_origin,
333                              s2_origin, n_origin);
334   return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
335 }
336 
337 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2,
338                                               size_t n, dfsan_label s1_label,
339                                               dfsan_label s2_label,
340                                               dfsan_label n_label,
341                                               dfsan_label *ret_label) {
342   return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
343 }
344 
345 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp(
346     const void *s1, const void *s2, size_t n, dfsan_label s1_label,
347     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
348     dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
349     dfsan_origin *ret_origin) {
350   return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
351 }
352 
353 // When n == 0, compare strings without byte limit.
354 // When n > 0, compare the first (at most) n bytes of s1 and s2.
355 static int dfsan_strncmp(const char *s1, const char *s2, size_t n,
356                          size_t *bytes_read) {
357   for (size_t i = 0;; ++i) {
358     if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) {
359       *bytes_read = i + 1;
360       return s1[i] - s2[i];
361     }
362   }
363 }
364 
365 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc,
366                               const char *s1, const char *s2,
367                               dfsan_label s1_label, dfsan_label s2_label)
368 
369 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc,
370                               const char *s1, const char *s2,
371                               dfsan_label s1_label, dfsan_label s2_label,
372                               dfsan_origin s1_origin, dfsan_origin s2_origin)
373 
374 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,
375                                                 dfsan_label s1_label,
376                                                 dfsan_label s2_label,
377                                                 dfsan_label *ret_label) {
378   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2,
379                              s1_label, s2_label);
380   size_t bytes_read;
381   int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
382   *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
383   return r;
384 }
385 
386 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp(
387     const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
388     dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
389     dfsan_origin *ret_origin) {
390   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1,
391                              s2, s1_label, s2_label, s1_origin, s2_origin);
392   size_t bytes_read;
393   int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
394   dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
395   return r;
396 }
397 
398 // When n == 0, compare strings without byte limit.
399 // When n > 0, compare the first (at most) n bytes of s1 and s2.
400 static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n,
401                              size_t *bytes_read) {
402   for (size_t i = 0;; ++i) {
403     char s1_lower = tolower(s1[i]);
404     char s2_lower = tolower(s2[i]);
405 
406     if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 ||
407         (n > 0 && i == n - 1)) {
408       *bytes_read = i + 1;
409       return s1_lower - s2_lower;
410     }
411   }
412 }
413 
414 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1,
415                                                     const char *s2,
416                                                     dfsan_label s1_label,
417                                                     dfsan_label s2_label,
418                                                     dfsan_label *ret_label) {
419   size_t bytes_read;
420   int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
421   *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
422   return r;
423 }
424 
425 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp(
426     const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
427     dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
428     dfsan_origin *ret_origin) {
429   size_t bytes_read;
430   int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
431   dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
432   return r;
433 }
434 
435 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,
436                               const char *s1, const char *s2, size_t n,
437                               dfsan_label s1_label, dfsan_label s2_label,
438                               dfsan_label n_label)
439 
440 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc,
441                               const char *s1, const char *s2, size_t n,
442                               dfsan_label s1_label, dfsan_label s2_label,
443                               dfsan_label n_label, dfsan_origin s1_origin,
444                               dfsan_origin s2_origin, dfsan_origin n_origin)
445 
446 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
447                                                  size_t n, dfsan_label s1_label,
448                                                  dfsan_label s2_label,
449                                                  dfsan_label n_label,
450                                                  dfsan_label *ret_label) {
451   if (n == 0) {
452     *ret_label = 0;
453     return 0;
454   }
455 
456   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2,
457                              n, s1_label, s2_label, n_label);
458 
459   size_t bytes_read;
460   int r = dfsan_strncmp(s1, s2, n, &bytes_read);
461   *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
462   return r;
463 }
464 
465 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp(
466     const char *s1, const char *s2, size_t n, dfsan_label s1_label,
467     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
468     dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
469     dfsan_origin *ret_origin) {
470   if (n == 0) {
471     *ret_label = 0;
472     return 0;
473   }
474 
475   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(),
476                              s1, s2, n, s1_label, s2_label, n_label, s1_origin,
477                              s2_origin, n_origin);
478 
479   size_t bytes_read;
480   int r = dfsan_strncmp(s1, s2, n, &bytes_read);
481   dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
482   return r;
483 }
484 
485 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp(
486     const char *s1, const char *s2, size_t n, dfsan_label s1_label,
487     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) {
488   if (n == 0) {
489     *ret_label = 0;
490     return 0;
491   }
492 
493   size_t bytes_read;
494   int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
495   *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
496   return r;
497 }
498 
499 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp(
500     const char *s1, const char *s2, size_t n, dfsan_label s1_label,
501     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
502     dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
503     dfsan_origin *ret_origin) {
504   if (n == 0) {
505     *ret_label = 0;
506     return 0;
507   }
508 
509   size_t bytes_read;
510   int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
511   dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
512   return r;
513 }
514 
515 
516 SANITIZER_INTERFACE_ATTRIBUTE size_t
517 __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
518   size_t ret = strlen(s);
519   if (flags().strict_data_dependencies) {
520     *ret_label = 0;
521   } else {
522     *ret_label = dfsan_read_label(s, ret + 1);
523   }
524   return ret;
525 }
526 
527 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s,
528                                                    dfsan_label s_label,
529                                                    dfsan_label *ret_label,
530                                                    dfsan_origin s_origin,
531                                                    dfsan_origin *ret_origin) {
532   size_t ret = __dfsw_strlen(s, s_label, ret_label);
533   if (!flags().strict_data_dependencies)
534     *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1);
535   return ret;
536 }
537 
538 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfsw_strnlen(const char *s,
539                                                     size_t maxlen,
540                                                     dfsan_label s_label,
541                                                     dfsan_label maxlen_label,
542                                                     dfsan_label *ret_label) {
543   size_t ret = strnlen(s, maxlen);
544   if (flags().strict_data_dependencies) {
545     *ret_label = 0;
546   } else {
547     size_t full_len = strlen(s);
548     size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen;
549     *ret_label = dfsan_union(maxlen_label, dfsan_read_label(s, covered_len));
550   }
551   return ret;
552 }
553 
554 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strnlen(
555     const char *s, size_t maxlen, dfsan_label s_label, dfsan_label maxlen_label,
556     dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin maxlen_origin,
557     dfsan_origin *ret_origin) {
558   size_t ret = __dfsw_strnlen(s, maxlen, s_label, maxlen_label, ret_label);
559   if (!flags().strict_data_dependencies) {
560     size_t full_len = strlen(s);
561     size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen;
562     dfsan_origin o = dfsan_read_origin_of_first_taint(s, covered_len);
563     *ret_origin = o ? o : maxlen_origin;
564   }
565   return ret;
566 }
567 
568 static void *dfsan_memmove(void *dest, const void *src, size_t n) {
569   dfsan_label *sdest = shadow_for(dest);
570   const dfsan_label *ssrc = shadow_for(src);
571   internal_memmove((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label));
572   return internal_memmove(dest, src, n);
573 }
574 
575 static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) {
576   dfsan_mem_origin_transfer(dest, src, n);
577   return dfsan_memmove(dest, src, n);
578 }
579 
580 static void *dfsan_memcpy(void *dest, const void *src, size_t n) {
581   dfsan_mem_shadow_transfer(dest, src, n);
582   return internal_memcpy(dest, src, n);
583 }
584 
585 static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) {
586   dfsan_mem_origin_transfer(dest, src, n);
587   return dfsan_memcpy(dest, src, n);
588 }
589 
590 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {
591   internal_memset(s, c, n);
592   dfsan_set_label(c_label, s, n);
593 }
594 
595 static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label,
596                                      dfsan_origin c_origin, size_t n) {
597   internal_memset(s, c, n);
598   dfsan_set_label_origin(c_label, c_origin, s, n);
599 }
600 
601 SANITIZER_INTERFACE_ATTRIBUTE
602 void *__dfsw_memcpy(void *dest, const void *src, size_t n,
603                     dfsan_label dest_label, dfsan_label src_label,
604                     dfsan_label n_label, dfsan_label *ret_label) {
605   *ret_label = dest_label;
606   return dfsan_memcpy(dest, src, n);
607 }
608 
609 SANITIZER_INTERFACE_ATTRIBUTE
610 void *__dfso_memcpy(void *dest, const void *src, size_t n,
611                     dfsan_label dest_label, dfsan_label src_label,
612                     dfsan_label n_label, dfsan_label *ret_label,
613                     dfsan_origin dest_origin, dfsan_origin src_origin,
614                     dfsan_origin n_origin, dfsan_origin *ret_origin) {
615   *ret_label = dest_label;
616   *ret_origin = dest_origin;
617   return dfsan_memcpy_with_origin(dest, src, n);
618 }
619 
620 SANITIZER_INTERFACE_ATTRIBUTE
621 void *__dfsw_memmove(void *dest, const void *src, size_t n,
622                      dfsan_label dest_label, dfsan_label src_label,
623                      dfsan_label n_label, dfsan_label *ret_label) {
624   *ret_label = dest_label;
625   return dfsan_memmove(dest, src, n);
626 }
627 
628 SANITIZER_INTERFACE_ATTRIBUTE
629 void *__dfso_memmove(void *dest, const void *src, size_t n,
630                      dfsan_label dest_label, dfsan_label src_label,
631                      dfsan_label n_label, dfsan_label *ret_label,
632                      dfsan_origin dest_origin, dfsan_origin src_origin,
633                      dfsan_origin n_origin, dfsan_origin *ret_origin) {
634   *ret_label = dest_label;
635   *ret_origin = dest_origin;
636   return dfsan_memmove_with_origin(dest, src, n);
637 }
638 
639 SANITIZER_INTERFACE_ATTRIBUTE
640 void *__dfsw_memset(void *s, int c, size_t n,
641                     dfsan_label s_label, dfsan_label c_label,
642                     dfsan_label n_label, dfsan_label *ret_label) {
643   dfsan_memset(s, c, c_label, n);
644   *ret_label = s_label;
645   return s;
646 }
647 
648 SANITIZER_INTERFACE_ATTRIBUTE
649 void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label,
650                     dfsan_label c_label, dfsan_label n_label,
651                     dfsan_label *ret_label, dfsan_origin s_origin,
652                     dfsan_origin c_origin, dfsan_origin n_origin,
653                     dfsan_origin *ret_origin) {
654   dfsan_memset_with_origin(s, c, c_label, c_origin, n);
655   *ret_label = s_label;
656   *ret_origin = s_origin;
657   return s;
658 }
659 
660 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
661                                                   dfsan_label dest_label,
662                                                   dfsan_label src_label,
663                                                   dfsan_label *ret_label) {
664   size_t dest_len = strlen(dest);
665   char *ret = strcat(dest, src);
666   dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src));
667   *ret_label = dest_label;
668   return ret;
669 }
670 
671 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
672     char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label,
673     dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin,
674     dfsan_origin *ret_origin) {
675   size_t dest_len = strlen(dest);
676   char *ret = strcat(dest, src);
677   size_t src_len = strlen(src);
678   dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
679   dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
680   *ret_label = dest_label;
681   *ret_origin = dest_origin;
682   return ret;
683 }
684 
685 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strncat(
686     char *dest, const char *src, size_t num, dfsan_label dest_label,
687     dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label) {
688   size_t src_len = strlen(src);
689   src_len = src_len < num ? src_len : num;
690   size_t dest_len = strlen(dest);
691 
692   char *ret = strncat(dest, src, num);
693   dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
694   *ret_label = dest_label;
695   return ret;
696 }
697 
698 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncat(
699     char *dest, const char *src, size_t num, dfsan_label dest_label,
700     dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label,
701     dfsan_origin dest_origin, dfsan_origin src_origin, dfsan_origin num_origin,
702     dfsan_origin *ret_origin) {
703   size_t src_len = strlen(src);
704   src_len = src_len < num ? src_len : num;
705   size_t dest_len = strlen(dest);
706 
707   char *ret = strncat(dest, src, num);
708 
709   dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
710   dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
711   *ret_label = dest_label;
712   *ret_origin = dest_origin;
713   return ret;
714 }
715 
716 SANITIZER_INTERFACE_ATTRIBUTE char *
717 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
718   size_t len = strlen(s);
719   void *p = malloc(len+1);
720   dfsan_memcpy(p, s, len+1);
721   *ret_label = 0;
722   return static_cast<char *>(p);
723 }
724 
725 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s,
726                                                   dfsan_label s_label,
727                                                   dfsan_label *ret_label,
728                                                   dfsan_origin s_origin,
729                                                   dfsan_origin *ret_origin) {
730   size_t len = strlen(s);
731   void *p = malloc(len + 1);
732   dfsan_memcpy_with_origin(p, s, len + 1);
733   *ret_label = 0;
734   return static_cast<char *>(p);
735 }
736 
737 SANITIZER_INTERFACE_ATTRIBUTE char *
738 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
739                dfsan_label s2_label, dfsan_label n_label,
740                dfsan_label *ret_label) {
741   size_t len = strlen(s2);
742   if (len < n) {
743     dfsan_memcpy(s1, s2, len+1);
744     dfsan_memset(s1+len+1, 0, 0, n-len-1);
745   } else {
746     dfsan_memcpy(s1, s2, n);
747   }
748 
749   *ret_label = s1_label;
750   return s1;
751 }
752 
753 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy(
754     char *s1, const char *s2, size_t n, dfsan_label s1_label,
755     dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
756     dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
757     dfsan_origin *ret_origin) {
758   size_t len = strlen(s2);
759   if (len < n) {
760     dfsan_memcpy_with_origin(s1, s2, len + 1);
761     dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1);
762   } else {
763     dfsan_memcpy_with_origin(s1, s2, n);
764   }
765 
766   *ret_label = s1_label;
767   *ret_origin = s1_origin;
768   return s1;
769 }
770 
771 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
772 __dfsw_pread(int fd, void *buf, size_t count, off_t offset,
773              dfsan_label fd_label, dfsan_label buf_label,
774              dfsan_label count_label, dfsan_label offset_label,
775              dfsan_label *ret_label) {
776   ssize_t ret = pread(fd, buf, count, offset);
777   if (ret > 0)
778     dfsan_set_label(0, buf, ret);
779   *ret_label = 0;
780   return ret;
781 }
782 
783 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread(
784     int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label,
785     dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label,
786     dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
787     dfsan_origin count_origin, dfsan_label offset_origin,
788     dfsan_origin *ret_origin) {
789   return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label,
790                       offset_label, ret_label);
791 }
792 
793 SANITIZER_INTERFACE_ATTRIBUTE ssize_t
794 __dfsw_read(int fd, void *buf, size_t count,
795              dfsan_label fd_label, dfsan_label buf_label,
796              dfsan_label count_label,
797              dfsan_label *ret_label) {
798   ssize_t ret = read(fd, buf, count);
799   if (ret > 0)
800     dfsan_set_label(0, buf, ret);
801   *ret_label = 0;
802   return ret;
803 }
804 
805 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read(
806     int fd, void *buf, size_t count, dfsan_label fd_label,
807     dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
808     dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
809     dfsan_origin *ret_origin) {
810   return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label,
811                      ret_label);
812 }
813 
814 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
815                                                        struct timespec *tp,
816                                                        dfsan_label clk_id_label,
817                                                        dfsan_label tp_label,
818                                                        dfsan_label *ret_label) {
819   int ret = clock_gettime(clk_id, tp);
820   if (ret == 0)
821     dfsan_set_label(0, tp, sizeof(struct timespec));
822   *ret_label = 0;
823   return ret;
824 }
825 
826 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime(
827     clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label,
828     dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin,
829     dfsan_origin tp_origin, dfsan_origin *ret_origin) {
830   return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label);
831 }
832 
833 static void dfsan_set_zero_label(const void *ptr, uptr size) {
834   dfsan_set_label(0, const_cast<void *>(ptr), size);
835 }
836 
837 // dlopen() ultimately calls mmap() down inside the loader, which generally
838 // doesn't participate in dynamic symbol resolution.  Therefore we won't
839 // intercept its calls to mmap, and we have to hook it here.
840 SANITIZER_INTERFACE_ATTRIBUTE void *
841 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
842               dfsan_label flag_label, dfsan_label *ret_label) {
843   void *handle = dlopen(filename, flag);
844   link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
845   if (map)
846     ForEachMappedRegion(map, dfsan_set_zero_label);
847   *ret_label = 0;
848   return handle;
849 }
850 
851 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen(
852     const char *filename, int flag, dfsan_label filename_label,
853     dfsan_label flag_label, dfsan_label *ret_label,
854     dfsan_origin filename_origin, dfsan_origin flag_origin,
855     dfsan_origin *ret_origin) {
856   return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label);
857 }
858 
859 static void *DFsanThreadStartFunc(void *arg) {
860   DFsanThread *t = (DFsanThread *)arg;
861   SetCurrentThread(t);
862   t->Init();
863   SetSigProcMask(&t->starting_sigset_, nullptr);
864   return t->ThreadStart();
865 }
866 
867 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
868                                 void *start_routine, void *arg,
869                                 dfsan_label *ret_label,
870                                 bool track_origins = false) {
871   pthread_attr_t myattr;
872   if (!attr) {
873     pthread_attr_init(&myattr);
874     attr = &myattr;
875   }
876 
877   // Ensure that the thread stack is large enough to hold all TLS data.
878   AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr)));
879 
880   DFsanThread *t =
881       DFsanThread::Create((thread_callback_t)start_routine, arg, track_origins);
882   ScopedBlockSignals block(&t->starting_sigset_);
883   int res = pthread_create(thread, attr, DFsanThreadStartFunc, t);
884 
885   if (attr == &myattr)
886     pthread_attr_destroy(&myattr);
887   *ret_label = 0;
888   return res;
889 }
890 
891 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create(
892     pthread_t *thread, const pthread_attr_t *attr, void *start_routine,
893     void *arg, dfsan_label thread_label, dfsan_label attr_label,
894     dfsan_label start_routine_label, dfsan_label arg_label,
895     dfsan_label *ret_label) {
896   return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label);
897 }
898 
899 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create(
900     pthread_t *thread, const pthread_attr_t *attr, void *start_routine,
901     void *arg, dfsan_label thread_label, dfsan_label attr_label,
902     dfsan_label start_routine_label, dfsan_label arg_label,
903     dfsan_label *ret_label, dfsan_origin thread_origin,
904     dfsan_origin attr_origin, dfsan_origin start_routine_origin,
905     dfsan_origin arg_origin, dfsan_origin *ret_origin) {
906   return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label,
907                               true);
908 }
909 
910 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread,
911                                                       void **retval,
912                                                       dfsan_label thread_label,
913                                                       dfsan_label retval_label,
914                                                       dfsan_label *ret_label) {
915   int ret = pthread_join(thread, retval);
916   if (ret == 0 && retval)
917     dfsan_set_label(0, retval, sizeof(*retval));
918   *ret_label = 0;
919   return ret;
920 }
921 
922 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join(
923     pthread_t thread, void **retval, dfsan_label thread_label,
924     dfsan_label retval_label, dfsan_label *ret_label,
925     dfsan_origin thread_origin, dfsan_origin retval_origin,
926     dfsan_origin *ret_origin) {
927   return __dfsw_pthread_join(thread, retval, thread_label, retval_label,
928                              ret_label);
929 }
930 
931 struct dl_iterate_phdr_info {
932   int (*callback)(struct dl_phdr_info *info, size_t size, void *data);
933   void *data;
934 };
935 
936 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
937   dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;
938   dfsan_set_label(0, *info);
939   dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
940                   strlen(info->dlpi_name) + 1);
941   dfsan_set_label(
942       0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
943       sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
944 
945   dfsan_clear_thread_local_state();
946   return dipi->callback(info, size, dipi->data);
947 }
948 
949 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
950     int (*callback)(struct dl_phdr_info *info, size_t size, void *data),
951     void *data, dfsan_label callback_label, dfsan_label data_label,
952     dfsan_label *ret_label) {
953   dl_iterate_phdr_info dipi = {callback, data};
954   *ret_label = 0;
955   return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
956 }
957 
958 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr(
959     int (*callback)(struct dl_phdr_info *info, size_t size, void *data),
960     void *data, dfsan_label callback_label, dfsan_label data_label,
961     dfsan_label *ret_label, dfsan_origin callback_origin,
962     dfsan_origin data_origin, dfsan_origin *ret_origin) {
963   dl_iterate_phdr_info dipi = {callback, data};
964   *ret_label = 0;
965   return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
966 }
967 
968 // This function is only available for glibc 2.27 or newer.  Mark it weak so
969 // linking succeeds with older glibcs.
970 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep,
971                                                       size_t *alignp);
972 
973 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info(
974     size_t *sizep, size_t *alignp, dfsan_label sizep_label,
975     dfsan_label alignp_label) {
976   assert(_dl_get_tls_static_info);
977   _dl_get_tls_static_info(sizep, alignp);
978   dfsan_set_label(0, sizep, sizeof(*sizep));
979   dfsan_set_label(0, alignp, sizeof(*alignp));
980 }
981 
982 SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info(
983     size_t *sizep, size_t *alignp, dfsan_label sizep_label,
984     dfsan_label alignp_label, dfsan_origin sizep_origin,
985     dfsan_origin alignp_origin) {
986   __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label);
987 }
988 
989 SANITIZER_INTERFACE_ATTRIBUTE
990 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
991                      dfsan_label buf_label, dfsan_label *ret_label) {
992   char *ret = ctime_r(timep, buf);
993   if (ret) {
994     dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf,
995                     strlen(buf) + 1);
996     *ret_label = buf_label;
997   } else {
998     *ret_label = 0;
999   }
1000   return ret;
1001 }
1002 
1003 SANITIZER_INTERFACE_ATTRIBUTE
1004 char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
1005                      dfsan_label buf_label, dfsan_label *ret_label,
1006                      dfsan_origin timep_origin, dfsan_origin buf_origin,
1007                      dfsan_origin *ret_origin) {
1008   char *ret = ctime_r(timep, buf);
1009   if (ret) {
1010     dfsan_set_label_origin(
1011         dfsan_read_label(timep, sizeof(time_t)),
1012         dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf,
1013         strlen(buf) + 1);
1014     *ret_label = buf_label;
1015     *ret_origin = buf_origin;
1016   } else {
1017     *ret_label = 0;
1018   }
1019   return ret;
1020 }
1021 
1022 SANITIZER_INTERFACE_ATTRIBUTE
1023 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
1024                    dfsan_label size_label, dfsan_label stream_label,
1025                    dfsan_label *ret_label) {
1026   char *ret = fgets(s, size, stream);
1027   if (ret) {
1028     dfsan_set_label(0, ret, strlen(ret) + 1);
1029     *ret_label = s_label;
1030   } else {
1031     *ret_label = 0;
1032   }
1033   return ret;
1034 }
1035 
1036 SANITIZER_INTERFACE_ATTRIBUTE
1037 char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
1038                    dfsan_label size_label, dfsan_label stream_label,
1039                    dfsan_label *ret_label, dfsan_origin s_origin,
1040                    dfsan_origin size_origin, dfsan_origin stream_origin,
1041                    dfsan_origin *ret_origin) {
1042   char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label,
1043                            ret_label);
1044   if (ret)
1045     *ret_origin = s_origin;
1046   return ret;
1047 }
1048 
1049 SANITIZER_INTERFACE_ATTRIBUTE
1050 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label,
1051                     dfsan_label size_label, dfsan_label *ret_label) {
1052   char *ret = getcwd(buf, size);
1053   if (ret) {
1054     dfsan_set_label(0, ret, strlen(ret) + 1);
1055     *ret_label = buf_label;
1056   } else {
1057     *ret_label = 0;
1058   }
1059   return ret;
1060 }
1061 
1062 SANITIZER_INTERFACE_ATTRIBUTE
1063 char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label,
1064                     dfsan_label size_label, dfsan_label *ret_label,
1065                     dfsan_origin buf_origin, dfsan_origin size_origin,
1066                     dfsan_origin *ret_origin) {
1067   char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label);
1068   if (ret)
1069     *ret_origin = buf_origin;
1070   return ret;
1071 }
1072 
1073 SANITIZER_INTERFACE_ATTRIBUTE
1074 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) {
1075   char *ret = get_current_dir_name();
1076   if (ret)
1077     dfsan_set_label(0, ret, strlen(ret) + 1);
1078   *ret_label = 0;
1079   return ret;
1080 }
1081 
1082 SANITIZER_INTERFACE_ATTRIBUTE
1083 char *__dfso_get_current_dir_name(dfsan_label *ret_label,
1084                                   dfsan_origin *ret_origin) {
1085   return __dfsw_get_current_dir_name(ret_label);
1086 }
1087 
1088 // This function is only available for glibc 2.25 or newer.  Mark it weak so
1089 // linking succeeds with older glibcs.
1090 SANITIZER_WEAK_ATTRIBUTE int getentropy(void *buffer, size_t length);
1091 
1092 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getentropy(void *buffer, size_t length,
1093                                                     dfsan_label buffer_label,
1094                                                     dfsan_label length_label,
1095                                                     dfsan_label *ret_label) {
1096   int ret = getentropy(buffer, length);
1097   if (ret == 0) {
1098     dfsan_set_label(0, buffer, length);
1099   }
1100   *ret_label = 0;
1101   return ret;
1102 }
1103 
1104 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getentropy(void *buffer, size_t length,
1105                                                     dfsan_label buffer_label,
1106                                                     dfsan_label length_label,
1107                                                     dfsan_label *ret_label,
1108                                                     dfsan_origin buffer_origin,
1109                                                     dfsan_origin length_origin,
1110                                                     dfsan_origin *ret_origin) {
1111   return __dfsw_getentropy(buffer, length, buffer_label, length_label,
1112                            ret_label);
1113 }
1114 
1115 SANITIZER_INTERFACE_ATTRIBUTE
1116 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label,
1117                        dfsan_label len_label, dfsan_label *ret_label) {
1118   int ret = gethostname(name, len);
1119   if (ret == 0) {
1120     dfsan_set_label(0, name, strlen(name) + 1);
1121   }
1122   *ret_label = 0;
1123   return ret;
1124 }
1125 
1126 SANITIZER_INTERFACE_ATTRIBUTE
1127 int __dfso_gethostname(char *name, size_t len, dfsan_label name_label,
1128                        dfsan_label len_label, dfsan_label *ret_label,
1129                        dfsan_origin name_origin, dfsan_origin len_origin,
1130                        dfsan_label *ret_origin) {
1131   return __dfsw_gethostname(name, len, name_label, len_label, ret_label);
1132 }
1133 
1134 SANITIZER_INTERFACE_ATTRIBUTE
1135 int __dfsw_getrlimit(int resource, struct rlimit *rlim,
1136                      dfsan_label resource_label, dfsan_label rlim_label,
1137                      dfsan_label *ret_label) {
1138   int ret = getrlimit(resource, rlim);
1139   if (ret == 0) {
1140     dfsan_set_label(0, rlim, sizeof(struct rlimit));
1141   }
1142   *ret_label = 0;
1143   return ret;
1144 }
1145 
1146 SANITIZER_INTERFACE_ATTRIBUTE
1147 int __dfso_getrlimit(int resource, struct rlimit *rlim,
1148                      dfsan_label resource_label, dfsan_label rlim_label,
1149                      dfsan_label *ret_label, dfsan_origin resource_origin,
1150                      dfsan_origin rlim_origin, dfsan_origin *ret_origin) {
1151   return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label,
1152                           ret_label);
1153 }
1154 
1155 SANITIZER_INTERFACE_ATTRIBUTE
1156 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1157                      dfsan_label usage_label, dfsan_label *ret_label) {
1158   int ret = getrusage(who, usage);
1159   if (ret == 0) {
1160     dfsan_set_label(0, usage, sizeof(struct rusage));
1161   }
1162   *ret_label = 0;
1163   return ret;
1164 }
1165 
1166 SANITIZER_INTERFACE_ATTRIBUTE
1167 int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label,
1168                      dfsan_label usage_label, dfsan_label *ret_label,
1169                      dfsan_origin who_origin, dfsan_origin usage_origin,
1170                      dfsan_label *ret_origin) {
1171   return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label);
1172 }
1173 
1174 SANITIZER_INTERFACE_ATTRIBUTE
1175 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label,
1176                     dfsan_label src_label, dfsan_label *ret_label) {
1177   char *ret = strcpy(dest, src);
1178   if (ret) {
1179     dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1);
1180   }
1181   *ret_label = dst_label;
1182   return ret;
1183 }
1184 
1185 SANITIZER_INTERFACE_ATTRIBUTE
1186 char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label,
1187                     dfsan_label src_label, dfsan_label *ret_label,
1188                     dfsan_origin dst_origin, dfsan_origin src_origin,
1189                     dfsan_origin *ret_origin) {
1190   char *ret = strcpy(dest, src);
1191   if (ret) {
1192     size_t str_len = strlen(src) + 1;
1193     dfsan_mem_origin_transfer(dest, src, str_len);
1194     dfsan_mem_shadow_transfer(dest, src, str_len);
1195   }
1196   *ret_label = dst_label;
1197   *ret_origin = dst_origin;
1198   return ret;
1199 }
1200 
1201 static long int dfsan_strtol(const char *nptr, char **endptr, int base,
1202                              char **tmp_endptr) {
1203   assert(tmp_endptr);
1204   long int ret = strtol(nptr, tmp_endptr, base);
1205   if (endptr)
1206     *endptr = *tmp_endptr;
1207   return ret;
1208 }
1209 
1210 static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr,
1211                                   dfsan_label base_label,
1212                                   dfsan_label *ret_label) {
1213   if (tmp_endptr > nptr) {
1214     // If *tmp_endptr is '\0' include its label as well.
1215     *ret_label = dfsan_union(
1216         base_label,
1217         dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));
1218   } else {
1219     *ret_label = 0;
1220   }
1221 }
1222 
1223 static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr,
1224                                    dfsan_label base_label,
1225                                    dfsan_label *ret_label,
1226                                    dfsan_origin base_origin,
1227                                    dfsan_origin *ret_origin) {
1228   if (tmp_endptr > nptr) {
1229     // When multiple inputs are tainted, we propagate one of its origins.
1230     // Because checking if base_label is tainted does not need additional
1231     // computation, we prefer to propagating base_origin.
1232     *ret_origin = base_label
1233                       ? base_origin
1234                       : dfsan_read_origin_of_first_taint(
1235                             nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1236   }
1237 }
1238 
1239 SANITIZER_INTERFACE_ATTRIBUTE
1240 long int __dfsw_strtol(const char *nptr, char **endptr, int base,
1241                        dfsan_label nptr_label, dfsan_label endptr_label,
1242                        dfsan_label base_label, dfsan_label *ret_label) {
1243   char *tmp_endptr;
1244   long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1245   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1246   return ret;
1247 }
1248 
1249 SANITIZER_INTERFACE_ATTRIBUTE
1250 long int __dfso_strtol(const char *nptr, char **endptr, int base,
1251                        dfsan_label nptr_label, dfsan_label endptr_label,
1252                        dfsan_label base_label, dfsan_label *ret_label,
1253                        dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1254                        dfsan_origin base_origin, dfsan_origin *ret_origin) {
1255   char *tmp_endptr;
1256   long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
1257   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1258   dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1259                          ret_origin);
1260   return ret;
1261 }
1262 
1263 static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) {
1264   assert(tmp_endptr);
1265   double ret = strtod(nptr, tmp_endptr);
1266   if (endptr)
1267     *endptr = *tmp_endptr;
1268   return ret;
1269 }
1270 
1271 static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr,
1272                                dfsan_label *ret_label) {
1273   if (tmp_endptr > nptr) {
1274     // If *tmp_endptr is '\0' include its label as well.
1275     *ret_label = dfsan_read_label(
1276         nptr,
1277         tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1278   } else {
1279     *ret_label = 0;
1280   }
1281 }
1282 
1283 SANITIZER_INTERFACE_ATTRIBUTE
1284 double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1285                      dfsan_label endptr_label, dfsan_label *ret_label) {
1286   char *tmp_endptr;
1287   double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1288   dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1289   return ret;
1290 }
1291 
1292 SANITIZER_INTERFACE_ATTRIBUTE
1293 double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
1294                      dfsan_label endptr_label, dfsan_label *ret_label,
1295                      dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1296                      dfsan_origin *ret_origin) {
1297   char *tmp_endptr;
1298   double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
1299   dfsan_strtod_label(nptr, tmp_endptr, ret_label);
1300   if (tmp_endptr > nptr) {
1301     // If *tmp_endptr is '\0' include its label as well.
1302     *ret_origin = dfsan_read_origin_of_first_taint(
1303         nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
1304   } else {
1305     *ret_origin = 0;
1306   }
1307   return ret;
1308 }
1309 
1310 static long long int dfsan_strtoll(const char *nptr, char **endptr, int base,
1311                                    char **tmp_endptr) {
1312   assert(tmp_endptr);
1313   long long int ret = strtoll(nptr, tmp_endptr, base);
1314   if (endptr)
1315     *endptr = *tmp_endptr;
1316   return ret;
1317 }
1318 
1319 SANITIZER_INTERFACE_ATTRIBUTE
1320 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base,
1321                              dfsan_label nptr_label, dfsan_label endptr_label,
1322                              dfsan_label base_label, dfsan_label *ret_label) {
1323   char *tmp_endptr;
1324   long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1325   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1326   return ret;
1327 }
1328 
1329 SANITIZER_INTERFACE_ATTRIBUTE
1330 long long int __dfso_strtoll(const char *nptr, char **endptr, int base,
1331                              dfsan_label nptr_label, dfsan_label endptr_label,
1332                              dfsan_label base_label, dfsan_label *ret_label,
1333                              dfsan_origin nptr_origin,
1334                              dfsan_origin endptr_origin,
1335                              dfsan_origin base_origin,
1336                              dfsan_origin *ret_origin) {
1337   char *tmp_endptr;
1338   long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
1339   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1340   dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1341                          ret_origin);
1342   return ret;
1343 }
1344 
1345 static unsigned long int dfsan_strtoul(const char *nptr, char **endptr,
1346                                        int base, char **tmp_endptr) {
1347   assert(tmp_endptr);
1348   unsigned long int ret = strtoul(nptr, tmp_endptr, base);
1349   if (endptr)
1350     *endptr = *tmp_endptr;
1351   return ret;
1352 }
1353 
1354 SANITIZER_INTERFACE_ATTRIBUTE
1355 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base,
1356                        dfsan_label nptr_label, dfsan_label endptr_label,
1357                        dfsan_label base_label, dfsan_label *ret_label) {
1358   char *tmp_endptr;
1359   unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1360   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1361   return ret;
1362 }
1363 
1364 SANITIZER_INTERFACE_ATTRIBUTE
1365 unsigned long int __dfso_strtoul(
1366     const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1367     dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1368     dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1369     dfsan_origin base_origin, dfsan_origin *ret_origin) {
1370   char *tmp_endptr;
1371   unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
1372   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1373   dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1374                          ret_origin);
1375   return ret;
1376 }
1377 
1378 static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr,
1379                                              int base, char **tmp_endptr) {
1380   assert(tmp_endptr);
1381   long long unsigned int ret = strtoull(nptr, tmp_endptr, base);
1382   if (endptr)
1383     *endptr = *tmp_endptr;
1384   return ret;
1385 }
1386 
1387 SANITIZER_INTERFACE_ATTRIBUTE
1388 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr,
1389                                        int base, dfsan_label nptr_label,
1390                                        dfsan_label endptr_label,
1391                                        dfsan_label base_label,
1392                                        dfsan_label *ret_label) {
1393   char *tmp_endptr;
1394   long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1395   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1396   return ret;
1397 }
1398 
1399 SANITIZER_INTERFACE_ATTRIBUTE
1400 long long unsigned int __dfso_strtoull(
1401     const char *nptr, char **endptr, int base, dfsan_label nptr_label,
1402     dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
1403     dfsan_origin nptr_origin, dfsan_origin endptr_origin,
1404     dfsan_origin base_origin, dfsan_origin *ret_origin) {
1405   char *tmp_endptr;
1406   long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
1407   dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
1408   dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
1409                          ret_origin);
1410   return ret;
1411 }
1412 
1413 SANITIZER_INTERFACE_ATTRIBUTE
1414 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) {
1415   time_t ret = time(t);
1416   if (ret != (time_t) -1 && t) {
1417     dfsan_set_label(0, t, sizeof(time_t));
1418   }
1419   *ret_label = 0;
1420   return ret;
1421 }
1422 
1423 SANITIZER_INTERFACE_ATTRIBUTE
1424 time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label,
1425                    dfsan_origin t_origin, dfsan_origin *ret_origin) {
1426   return __dfsw_time(t, t_label, ret_label);
1427 }
1428 
1429 SANITIZER_INTERFACE_ATTRIBUTE
1430 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1431                      dfsan_label src_label, dfsan_label dst_label,
1432                      dfsan_label *ret_label) {
1433   int ret = inet_pton(af, src, dst);
1434   if (ret == 1) {
1435     dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst,
1436                     af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1437   }
1438   *ret_label = 0;
1439   return ret;
1440 }
1441 
1442 SANITIZER_INTERFACE_ATTRIBUTE
1443 int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
1444                      dfsan_label src_label, dfsan_label dst_label,
1445                      dfsan_label *ret_label, dfsan_origin af_origin,
1446                      dfsan_origin src_origin, dfsan_origin dst_origin,
1447                      dfsan_origin *ret_origin) {
1448   int ret = inet_pton(af, src, dst);
1449   if (ret == 1) {
1450     int src_len = strlen(src) + 1;
1451     dfsan_set_label_origin(
1452         dfsan_read_label(src, src_len),
1453         dfsan_read_origin_of_first_taint(src, src_len), dst,
1454         af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
1455   }
1456   *ret_label = 0;
1457   return ret;
1458 }
1459 
1460 SANITIZER_INTERFACE_ATTRIBUTE
1461 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result,
1462                               dfsan_label timep_label, dfsan_label result_label,
1463                               dfsan_label *ret_label) {
1464   struct tm *ret = localtime_r(timep, result);
1465   if (ret) {
1466     dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result,
1467                     sizeof(struct tm));
1468     *ret_label = result_label;
1469   } else {
1470     *ret_label = 0;
1471   }
1472   return ret;
1473 }
1474 
1475 SANITIZER_INTERFACE_ATTRIBUTE
1476 struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result,
1477                               dfsan_label timep_label, dfsan_label result_label,
1478                               dfsan_label *ret_label, dfsan_origin timep_origin,
1479                               dfsan_origin result_origin,
1480                               dfsan_origin *ret_origin) {
1481   struct tm *ret = localtime_r(timep, result);
1482   if (ret) {
1483     dfsan_set_label_origin(
1484         dfsan_read_label(timep, sizeof(time_t)),
1485         dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result,
1486         sizeof(struct tm));
1487     *ret_label = result_label;
1488     *ret_origin = result_origin;
1489   } else {
1490     *ret_label = 0;
1491   }
1492   return ret;
1493 }
1494 
1495 SANITIZER_INTERFACE_ATTRIBUTE
1496 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,
1497                       char *buf, size_t buflen, struct passwd **result,
1498                       dfsan_label uid_label, dfsan_label pwd_label,
1499                       dfsan_label buf_label, dfsan_label buflen_label,
1500                       dfsan_label result_label, dfsan_label *ret_label) {
1501   // Store the data in pwd, the strings referenced from pwd in buf, and the
1502   // address of pwd in *result.  On failure, NULL is stored in *result.
1503   int ret = getpwuid_r(uid, pwd, buf, buflen, result);
1504   if (ret == 0) {
1505     dfsan_set_label(0, pwd, sizeof(struct passwd));
1506     dfsan_set_label(0, buf, strlen(buf) + 1);
1507   }
1508   *ret_label = 0;
1509   dfsan_set_label(0, result, sizeof(struct passwd*));
1510   return ret;
1511 }
1512 
1513 SANITIZER_INTERFACE_ATTRIBUTE
1514 int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen,
1515                       struct passwd **result, dfsan_label uid_label,
1516                       dfsan_label pwd_label, dfsan_label buf_label,
1517                       dfsan_label buflen_label, dfsan_label result_label,
1518                       dfsan_label *ret_label, dfsan_origin uid_origin,
1519                       dfsan_origin pwd_origin, dfsan_origin buf_origin,
1520                       dfsan_origin buflen_origin, dfsan_origin result_origin,
1521                       dfsan_origin *ret_origin) {
1522   return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label,
1523                            buf_label, buflen_label, result_label, ret_label);
1524 }
1525 
1526 SANITIZER_INTERFACE_ATTRIBUTE
1527 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1528                       int timeout, dfsan_label epfd_label,
1529                       dfsan_label events_label, dfsan_label maxevents_label,
1530                       dfsan_label timeout_label, dfsan_label *ret_label) {
1531   int ret = epoll_wait(epfd, events, maxevents, timeout);
1532   if (ret > 0)
1533     dfsan_set_label(0, events, ret * sizeof(*events));
1534   *ret_label = 0;
1535   return ret;
1536 }
1537 
1538 SANITIZER_INTERFACE_ATTRIBUTE
1539 int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
1540                       int timeout, dfsan_label epfd_label,
1541                       dfsan_label events_label, dfsan_label maxevents_label,
1542                       dfsan_label timeout_label, dfsan_label *ret_label,
1543                       dfsan_origin epfd_origin, dfsan_origin events_origin,
1544                       dfsan_origin maxevents_origin,
1545                       dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1546   return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label,
1547                            events_label, maxevents_label, timeout_label,
1548                            ret_label);
1549 }
1550 
1551 SANITIZER_INTERFACE_ATTRIBUTE
1552 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1553                 dfsan_label dfs_label, dfsan_label nfds_label,
1554                 dfsan_label timeout_label, dfsan_label *ret_label) {
1555   int ret = poll(fds, nfds, timeout);
1556   if (ret >= 0) {
1557     for (; nfds > 0; --nfds) {
1558       dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents));
1559     }
1560   }
1561   *ret_label = 0;
1562   return ret;
1563 }
1564 
1565 SANITIZER_INTERFACE_ATTRIBUTE
1566 int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout,
1567                 dfsan_label dfs_label, dfsan_label nfds_label,
1568                 dfsan_label timeout_label, dfsan_label *ret_label,
1569                 dfsan_origin dfs_origin, dfsan_origin nfds_origin,
1570                 dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1571   return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label,
1572                      ret_label);
1573 }
1574 
1575 SANITIZER_INTERFACE_ATTRIBUTE
1576 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds,
1577                   fd_set *exceptfds, struct timeval *timeout,
1578                   dfsan_label nfds_label, dfsan_label readfds_label,
1579                   dfsan_label writefds_label, dfsan_label exceptfds_label,
1580                   dfsan_label timeout_label, dfsan_label *ret_label) {
1581   int ret = select(nfds, readfds, writefds, exceptfds, timeout);
1582   // Clear everything (also on error) since their content is either set or
1583   // undefined.
1584   if (readfds) {
1585     dfsan_set_label(0, readfds, sizeof(fd_set));
1586   }
1587   if (writefds) {
1588     dfsan_set_label(0, writefds, sizeof(fd_set));
1589   }
1590   if (exceptfds) {
1591     dfsan_set_label(0, exceptfds, sizeof(fd_set));
1592   }
1593   dfsan_set_label(0, timeout, sizeof(struct timeval));
1594   *ret_label = 0;
1595   return ret;
1596 }
1597 
1598 SANITIZER_INTERFACE_ATTRIBUTE
1599 int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds,
1600                   fd_set *exceptfds, struct timeval *timeout,
1601                   dfsan_label nfds_label, dfsan_label readfds_label,
1602                   dfsan_label writefds_label, dfsan_label exceptfds_label,
1603                   dfsan_label timeout_label, dfsan_label *ret_label,
1604                   dfsan_origin nfds_origin, dfsan_origin readfds_origin,
1605                   dfsan_origin writefds_origin, dfsan_origin exceptfds_origin,
1606                   dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
1607   return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label,
1608                        readfds_label, writefds_label, exceptfds_label,
1609                        timeout_label, ret_label);
1610 }
1611 
1612 SANITIZER_INTERFACE_ATTRIBUTE
1613 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1614                              dfsan_label pid_label,
1615                              dfsan_label cpusetsize_label,
1616                              dfsan_label mask_label, dfsan_label *ret_label) {
1617   int ret = sched_getaffinity(pid, cpusetsize, mask);
1618   if (ret == 0) {
1619     dfsan_set_label(0, mask, cpusetsize);
1620   }
1621   *ret_label = 0;
1622   return ret;
1623 }
1624 
1625 SANITIZER_INTERFACE_ATTRIBUTE
1626 int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
1627                              dfsan_label pid_label,
1628                              dfsan_label cpusetsize_label,
1629                              dfsan_label mask_label, dfsan_label *ret_label,
1630                              dfsan_origin pid_origin,
1631                              dfsan_origin cpusetsize_origin,
1632                              dfsan_origin mask_origin,
1633                              dfsan_origin *ret_origin) {
1634   return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label,
1635                                   cpusetsize_label, mask_label, ret_label);
1636 }
1637 
1638 SANITIZER_INTERFACE_ATTRIBUTE
1639 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label,
1640                        dfsan_label *ret_label) {
1641   int ret = sigemptyset(set);
1642   dfsan_set_label(0, set, sizeof(sigset_t));
1643   *ret_label = 0;
1644   return ret;
1645 }
1646 
1647 SANITIZER_INTERFACE_ATTRIBUTE
1648 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label,
1649                        dfsan_label *ret_label, dfsan_origin set_origin,
1650                        dfsan_origin *ret_origin) {
1651   return __dfsw_sigemptyset(set, set_label, ret_label);
1652 }
1653 
1654 class SignalHandlerScope {
1655  public:
1656   SignalHandlerScope() {
1657     if (DFsanThread *t = GetCurrentThread())
1658       t->EnterSignalHandler();
1659   }
1660   ~SignalHandlerScope() {
1661     if (DFsanThread *t = GetCurrentThread())
1662       t->LeaveSignalHandler();
1663   }
1664 };
1665 
1666 // Clear DFSan runtime TLS state at the end of a scope.
1667 //
1668 // Implementation must be async-signal-safe and use small data size, because
1669 // instances of this class may live on the signal handler stack.
1670 //
1671 // DFSan uses TLS to pass metadata of arguments and return values. When an
1672 // instrumented function accesses the TLS, if a signal callback happens, and the
1673 // callback calls other instrumented functions with updating the same TLS, the
1674 // TLS is in an inconsistent state after the callback ends. This may cause
1675 // either under-tainting or over-tainting.
1676 //
1677 // The current implementation simply resets TLS at restore. This prevents from
1678 // over-tainting. Although under-tainting may still happen, a taint flow can be
1679 // found eventually if we run a DFSan-instrumented program multiple times. The
1680 // alternative option is saving the entire TLS. However the TLS storage takes
1681 // 2k bytes, and signal calls could be nested. So it does not seem worth.
1682 class ScopedClearThreadLocalState {
1683  public:
1684   ScopedClearThreadLocalState() {}
1685   ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); }
1686 };
1687 
1688 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls.
1689 const int kMaxSignals = 1024;
1690 static atomic_uintptr_t sigactions[kMaxSignals];
1691 
1692 static void SignalHandler(int signo) {
1693   SignalHandlerScope signal_handler_scope;
1694   ScopedClearThreadLocalState scoped_clear_tls;
1695 
1696   // Clear shadows for all inputs provided by system.
1697   dfsan_clear_arg_tls(0, sizeof(dfsan_label));
1698 
1699   typedef void (*signal_cb)(int x);
1700   signal_cb cb =
1701       (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1702   cb(signo);
1703 }
1704 
1705 static void SignalAction(int signo, siginfo_t *si, void *uc) {
1706   SignalHandlerScope signal_handler_scope;
1707   ScopedClearThreadLocalState scoped_clear_tls;
1708 
1709   // Clear shadows for all inputs provided by system. Similar to SignalHandler.
1710   dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label));
1711   dfsan_set_label(0, si, sizeof(*si));
1712   dfsan_set_label(0, uc, sizeof(ucontext_t));
1713 
1714   typedef void (*sigaction_cb)(int, siginfo_t *, void *);
1715   sigaction_cb cb =
1716       (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
1717   cb(signo, si, uc);
1718 }
1719 
1720 SANITIZER_INTERFACE_ATTRIBUTE
1721 int __dfsw_sigaction(int signum, const struct sigaction *act,
1722                      struct sigaction *oldact, dfsan_label signum_label,
1723                      dfsan_label act_label, dfsan_label oldact_label,
1724                      dfsan_label *ret_label) {
1725   CHECK_LT(signum, kMaxSignals);
1726   SignalSpinLocker lock;
1727   uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1728   struct sigaction new_act;
1729   struct sigaction *pnew_act = act ? &new_act : nullptr;
1730   if (act) {
1731     internal_memcpy(pnew_act, act, sizeof(struct sigaction));
1732     if (pnew_act->sa_flags & SA_SIGINFO) {
1733       uptr cb = (uptr)(pnew_act->sa_sigaction);
1734       if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1735         atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1736         pnew_act->sa_sigaction = SignalAction;
1737       }
1738     } else {
1739       uptr cb = (uptr)(pnew_act->sa_handler);
1740       if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
1741         atomic_store(&sigactions[signum], cb, memory_order_relaxed);
1742         pnew_act->sa_handler = SignalHandler;
1743       }
1744     }
1745   }
1746 
1747   int ret = sigaction(signum, pnew_act, oldact);
1748 
1749   if (ret == 0 && oldact) {
1750     if (oldact->sa_flags & SA_SIGINFO) {
1751       if (oldact->sa_sigaction == SignalAction)
1752         oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb;
1753     } else {
1754       if (oldact->sa_handler == SignalHandler)
1755         oldact->sa_handler = (decltype(oldact->sa_handler))old_cb;
1756     }
1757   }
1758 
1759   if (oldact) {
1760     dfsan_set_label(0, oldact, sizeof(struct sigaction));
1761   }
1762   *ret_label = 0;
1763   return ret;
1764 }
1765 
1766 SANITIZER_INTERFACE_ATTRIBUTE
1767 int __dfso_sigaction(int signum, const struct sigaction *act,
1768                      struct sigaction *oldact, dfsan_label signum_label,
1769                      dfsan_label act_label, dfsan_label oldact_label,
1770                      dfsan_label *ret_label, dfsan_origin signum_origin,
1771                      dfsan_origin act_origin, dfsan_origin oldact_origin,
1772                      dfsan_origin *ret_origin) {
1773   return __dfsw_sigaction(signum, act, oldact, signum_label, act_label,
1774                           oldact_label, ret_label);
1775 }
1776 
1777 static sighandler_t dfsan_signal(int signum, sighandler_t handler,
1778                                  dfsan_label *ret_label) {
1779   CHECK_LT(signum, kMaxSignals);
1780   SignalSpinLocker lock;
1781   uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
1782   if (handler != SIG_IGN && handler != SIG_DFL) {
1783     atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed);
1784     handler = &SignalHandler;
1785   }
1786 
1787   sighandler_t ret = signal(signum, handler);
1788 
1789   if (ret == SignalHandler)
1790     ret = (sighandler_t)old_cb;
1791 
1792   *ret_label = 0;
1793   return ret;
1794 }
1795 
1796 SANITIZER_INTERFACE_ATTRIBUTE
1797 sighandler_t __dfsw_signal(int signum, sighandler_t handler,
1798                            dfsan_label signum_label, dfsan_label handler_label,
1799                            dfsan_label *ret_label) {
1800   return dfsan_signal(signum, handler, ret_label);
1801 }
1802 
1803 SANITIZER_INTERFACE_ATTRIBUTE
1804 sighandler_t __dfso_signal(int signum, sighandler_t handler,
1805                            dfsan_label signum_label, dfsan_label handler_label,
1806                            dfsan_label *ret_label, dfsan_origin signum_origin,
1807                            dfsan_origin handler_origin,
1808                            dfsan_origin *ret_origin) {
1809   return dfsan_signal(signum, handler, ret_label);
1810 }
1811 
1812 SANITIZER_INTERFACE_ATTRIBUTE
1813 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1814                        dfsan_label old_ss_label, dfsan_label *ret_label) {
1815   int ret = sigaltstack(ss, old_ss);
1816   if (ret != -1 && old_ss)
1817     dfsan_set_label(0, old_ss, sizeof(*old_ss));
1818   *ret_label = 0;
1819   return ret;
1820 }
1821 
1822 SANITIZER_INTERFACE_ATTRIBUTE
1823 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
1824                        dfsan_label old_ss_label, dfsan_label *ret_label,
1825                        dfsan_origin ss_origin, dfsan_origin old_ss_origin,
1826                        dfsan_origin *ret_origin) {
1827   return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label);
1828 }
1829 
1830 SANITIZER_INTERFACE_ATTRIBUTE
1831 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz,
1832                         dfsan_label tv_label, dfsan_label tz_label,
1833                         dfsan_label *ret_label) {
1834   int ret = gettimeofday(tv, tz);
1835   if (tv) {
1836     dfsan_set_label(0, tv, sizeof(struct timeval));
1837   }
1838   if (tz) {
1839     dfsan_set_label(0, tz, sizeof(struct timezone));
1840   }
1841   *ret_label = 0;
1842   return ret;
1843 }
1844 
1845 SANITIZER_INTERFACE_ATTRIBUTE
1846 int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz,
1847                         dfsan_label tv_label, dfsan_label tz_label,
1848                         dfsan_label *ret_label, dfsan_origin tv_origin,
1849                         dfsan_origin tz_origin, dfsan_origin *ret_origin) {
1850   return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label);
1851 }
1852 
1853 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n,
1854                                                   dfsan_label s_label,
1855                                                   dfsan_label c_label,
1856                                                   dfsan_label n_label,
1857                                                   dfsan_label *ret_label) {
1858   void *ret = memchr(s, c, n);
1859   if (flags().strict_data_dependencies) {
1860     *ret_label = ret ? s_label : 0;
1861   } else {
1862     size_t len =
1863         ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1864             : n;
1865     *ret_label =
1866         dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label));
1867   }
1868   return ret;
1869 }
1870 
1871 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr(
1872     void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label,
1873     dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin,
1874     dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) {
1875   void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label);
1876   if (flags().strict_data_dependencies) {
1877     if (ret)
1878       *ret_origin = s_origin;
1879   } else {
1880     size_t len =
1881         ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
1882             : n;
1883     dfsan_origin o = dfsan_read_origin_of_first_taint(s, len);
1884     *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1885   }
1886   return ret;
1887 }
1888 
1889 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c,
1890                                                    dfsan_label s_label,
1891                                                    dfsan_label c_label,
1892                                                    dfsan_label *ret_label) {
1893   char *ret = strrchr(s, c);
1894   if (flags().strict_data_dependencies) {
1895     *ret_label = ret ? s_label : 0;
1896   } else {
1897     *ret_label =
1898         dfsan_union(dfsan_read_label(s, strlen(s) + 1),
1899                     dfsan_union(s_label, c_label));
1900   }
1901 
1902   return ret;
1903 }
1904 
1905 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr(
1906     char *s, int c, dfsan_label s_label, dfsan_label c_label,
1907     dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
1908     dfsan_origin *ret_origin) {
1909   char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label);
1910   if (flags().strict_data_dependencies) {
1911     if (ret)
1912       *ret_origin = s_origin;
1913   } else {
1914     size_t s_len = strlen(s) + 1;
1915     dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len);
1916     *ret_origin = o ? o : (s_label ? s_origin : c_origin);
1917   }
1918 
1919   return ret;
1920 }
1921 
1922 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle,
1923                                                   dfsan_label haystack_label,
1924                                                   dfsan_label needle_label,
1925                                                   dfsan_label *ret_label) {
1926   char *ret = strstr(haystack, needle);
1927   if (flags().strict_data_dependencies) {
1928     *ret_label = ret ? haystack_label : 0;
1929   } else {
1930     size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1;
1931     *ret_label =
1932         dfsan_union(dfsan_read_label(haystack, len),
1933                     dfsan_union(dfsan_read_label(needle, strlen(needle) + 1),
1934                                 dfsan_union(haystack_label, needle_label)));
1935   }
1936 
1937   return ret;
1938 }
1939 
1940 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle,
1941                                                   dfsan_label haystack_label,
1942                                                   dfsan_label needle_label,
1943                                                   dfsan_label *ret_label,
1944                                                   dfsan_origin haystack_origin,
1945                                                   dfsan_origin needle_origin,
1946                                                   dfsan_origin *ret_origin) {
1947   char *ret =
1948       __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label);
1949   if (flags().strict_data_dependencies) {
1950     if (ret)
1951       *ret_origin = haystack_origin;
1952   } else {
1953     size_t needle_len = strlen(needle);
1954     size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1;
1955     dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len);
1956     if (o) {
1957       *ret_origin = o;
1958     } else {
1959       o = dfsan_read_origin_of_first_taint(needle, needle_len + 1);
1960       *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin);
1961     }
1962   }
1963 
1964   return ret;
1965 }
1966 
1967 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req,
1968                                                    struct timespec *rem,
1969                                                    dfsan_label req_label,
1970                                                    dfsan_label rem_label,
1971                                                    dfsan_label *ret_label) {
1972   int ret = nanosleep(req, rem);
1973   *ret_label = 0;
1974   if (ret == -1) {
1975     // Interrupted by a signal, rem is filled with the remaining time.
1976     dfsan_set_label(0, rem, sizeof(struct timespec));
1977   }
1978   return ret;
1979 }
1980 
1981 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep(
1982     const struct timespec *req, struct timespec *rem, dfsan_label req_label,
1983     dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin,
1984     dfsan_origin rem_origin, dfsan_origin *ret_origin) {
1985   return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label);
1986 }
1987 
1988 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) {
1989   dfsan_set_label(0, msg, sizeof(*msg));
1990   dfsan_set_label(0, msg->msg_name, msg->msg_namelen);
1991   dfsan_set_label(0, msg->msg_control, msg->msg_controllen);
1992   for (size_t i = 0; bytes_written > 0; ++i) {
1993     assert(i < msg->msg_iovlen);
1994     struct iovec *iov = &msg->msg_iov[i];
1995     size_t iov_written =
1996         bytes_written < iov->iov_len ? bytes_written : iov->iov_len;
1997     dfsan_set_label(0, iov->iov_base, iov_written);
1998     bytes_written -= iov_written;
1999   }
2000 }
2001 
2002 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg(
2003     int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
2004     struct timespec *timeout, dfsan_label sockfd_label,
2005     dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
2006     dfsan_label timeout_label, dfsan_label *ret_label) {
2007   int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout);
2008   for (int i = 0; i < ret; ++i) {
2009     dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len));
2010     clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr);
2011   }
2012   *ret_label = 0;
2013   return ret;
2014 }
2015 
2016 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg(
2017     int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
2018     struct timespec *timeout, dfsan_label sockfd_label,
2019     dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
2020     dfsan_label timeout_label, dfsan_label *ret_label,
2021     dfsan_origin sockfd_origin, dfsan_origin msgvec_origin,
2022     dfsan_origin vlen_origin, dfsan_origin flags_origin,
2023     dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
2024   return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label,
2025                          msgvec_label, vlen_label, flags_label, timeout_label,
2026                          ret_label);
2027 }
2028 
2029 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg(
2030     int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
2031     dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) {
2032   ssize_t ret = recvmsg(sockfd, msg, flags);
2033   if (ret >= 0)
2034     clear_msghdr_labels(ret, msg);
2035   *ret_label = 0;
2036   return ret;
2037 }
2038 
2039 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg(
2040     int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
2041     dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label,
2042     dfsan_origin sockfd_origin, dfsan_origin msg_origin,
2043     dfsan_origin flags_origin, dfsan_origin *ret_origin) {
2044   return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label,
2045                         flags_label, ret_label);
2046 }
2047 
2048 SANITIZER_INTERFACE_ATTRIBUTE int
2049 __dfsw_socketpair(int domain, int type, int protocol, int sv[2],
2050                   dfsan_label domain_label, dfsan_label type_label,
2051                   dfsan_label protocol_label, dfsan_label sv_label,
2052                   dfsan_label *ret_label) {
2053   int ret = socketpair(domain, type, protocol, sv);
2054   *ret_label = 0;
2055   if (ret == 0) {
2056     dfsan_set_label(0, sv, sizeof(*sv) * 2);
2057   }
2058   return ret;
2059 }
2060 
2061 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair(
2062     int domain, int type, int protocol, int sv[2], dfsan_label domain_label,
2063     dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label,
2064     dfsan_label *ret_label, dfsan_origin domain_origin,
2065     dfsan_origin type_origin, dfsan_origin protocol_origin,
2066     dfsan_origin sv_origin, dfsan_origin *ret_origin) {
2067   return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label,
2068                            protocol_label, sv_label, ret_label);
2069 }
2070 
2071 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt(
2072     int sockfd, int level, int optname, void *optval, socklen_t *optlen,
2073     dfsan_label sockfd_label, dfsan_label level_label,
2074     dfsan_label optname_label, dfsan_label optval_label,
2075     dfsan_label optlen_label, dfsan_label *ret_label) {
2076   int ret = getsockopt(sockfd, level, optname, optval, optlen);
2077   if (ret != -1 && optval && optlen) {
2078     dfsan_set_label(0, optlen, sizeof(*optlen));
2079     dfsan_set_label(0, optval, *optlen);
2080   }
2081   *ret_label = 0;
2082   return ret;
2083 }
2084 
2085 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt(
2086     int sockfd, int level, int optname, void *optval, socklen_t *optlen,
2087     dfsan_label sockfd_label, dfsan_label level_label,
2088     dfsan_label optname_label, dfsan_label optval_label,
2089     dfsan_label optlen_label, dfsan_label *ret_label,
2090     dfsan_origin sockfd_origin, dfsan_origin level_origin,
2091     dfsan_origin optname_origin, dfsan_origin optval_origin,
2092     dfsan_origin optlen_origin, dfsan_origin *ret_origin) {
2093   return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label,
2094                            level_label, optname_label, optval_label,
2095                            optlen_label, ret_label);
2096 }
2097 
2098 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname(
2099     int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2100     dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2101     dfsan_label *ret_label) {
2102   socklen_t origlen = addrlen ? *addrlen : 0;
2103   int ret = getsockname(sockfd, addr, addrlen);
2104   if (ret != -1 && addr && addrlen) {
2105     socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
2106     dfsan_set_label(0, addrlen, sizeof(*addrlen));
2107     dfsan_set_label(0, addr, written_bytes);
2108   }
2109   *ret_label = 0;
2110   return ret;
2111 }
2112 
2113 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname(
2114     int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2115     dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2116     dfsan_label *ret_label, dfsan_origin sockfd_origin,
2117     dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2118     dfsan_origin *ret_origin) {
2119   return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label,
2120                             addrlen_label, ret_label);
2121 }
2122 
2123 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername(
2124     int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2125     dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2126     dfsan_label *ret_label) {
2127   socklen_t origlen = addrlen ? *addrlen : 0;
2128   int ret = getpeername(sockfd, addr, addrlen);
2129   if (ret != -1 && addr && addrlen) {
2130     socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
2131     dfsan_set_label(0, addrlen, sizeof(*addrlen));
2132     dfsan_set_label(0, addr, written_bytes);
2133   }
2134   *ret_label = 0;
2135   return ret;
2136 }
2137 
2138 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername(
2139     int sockfd, struct sockaddr *addr, socklen_t *addrlen,
2140     dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
2141     dfsan_label *ret_label, dfsan_origin sockfd_origin,
2142     dfsan_origin addr_origin, dfsan_origin addrlen_origin,
2143     dfsan_origin *ret_origin) {
2144   return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label,
2145                             addrlen_label, ret_label);
2146 }
2147 
2148 // Type of the function passed to dfsan_set_write_callback.
2149 typedef void (*write_dfsan_callback_t)(int fd, const void *buf, ssize_t count);
2150 
2151 // Calls to dfsan_set_write_callback() set the values in this struct.
2152 // Calls to the custom version of write() read (and invoke) them.
2153 static struct {
2154   write_dfsan_callback_t write_callback = nullptr;
2155 } write_callback_info;
2156 
2157 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw_dfsan_set_write_callback(
2158     write_dfsan_callback_t write_callback, dfsan_label write_callback_label,
2159     dfsan_label *ret_label) {
2160   write_callback_info.write_callback = write_callback;
2161 }
2162 
2163 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback(
2164     write_dfsan_callback_t write_callback, dfsan_label write_callback_label,
2165     dfsan_label *ret_label, dfsan_origin write_callback_origin,
2166     dfsan_origin *ret_origin) {
2167   write_callback_info.write_callback = write_callback;
2168 }
2169 
2170 static inline void setup_tls_args_for_write_callback(
2171     dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label,
2172     bool origins, dfsan_origin fd_origin, dfsan_origin buf_origin,
2173     dfsan_origin count_origin) {
2174   // The callback code will expect argument shadow labels in the args TLS,
2175   // and origin labels in the origin args TLS.
2176   // Previously this was done by a trampoline, but we want to remove this:
2177   // https://github.com/llvm/llvm-project/issues/54172
2178   //
2179   // Instead, this code is manually setting up the args TLS data.
2180   //
2181   // The offsets used need to correspond with the instrumentation code,
2182   // see llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
2183   // DFSanFunction::getShadowForTLSArgument.
2184   // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L1684
2185   // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L125
2186   //
2187   // Here the arguments are all primitives, but it can be more complex
2188   // to compute offsets for array/aggregate type arguments.
2189   //
2190   // TODO(browneee): Consider a builtin to improve maintainabliity.
2191   // With a builtin, we would provide the argument labels via builtin,
2192   // and the builtin would reuse parts of the instrumentation code to ensure
2193   // that this code and the instrumentation can never be out of sync.
2194   // Note: Currently DFSan instrumentation does not run on this code, so
2195   // the builtin may need to be handled outside DFSan instrumentation.
2196   dfsan_set_arg_tls(0, fd_label);
2197   dfsan_set_arg_tls(1, buf_label);
2198   dfsan_set_arg_tls(2, count_label);
2199   if (origins) {
2200     dfsan_set_arg_origin_tls(0, fd_origin);
2201     dfsan_set_arg_origin_tls(1, buf_origin);
2202     dfsan_set_arg_origin_tls(2, count_origin);
2203   }
2204 }
2205 
2206 SANITIZER_INTERFACE_ATTRIBUTE int
2207 __dfsw_write(int fd, const void *buf, size_t count,
2208              dfsan_label fd_label, dfsan_label buf_label,
2209              dfsan_label count_label, dfsan_label *ret_label) {
2210   if (write_callback_info.write_callback) {
2211     setup_tls_args_for_write_callback(fd_label, buf_label, count_label, false,
2212                                       0, 0, 0);
2213     write_callback_info.write_callback(fd, buf, count);
2214   }
2215 
2216   *ret_label = 0;
2217   return write(fd, buf, count);
2218 }
2219 
2220 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write(
2221     int fd, const void *buf, size_t count, dfsan_label fd_label,
2222     dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
2223     dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
2224     dfsan_origin *ret_origin) {
2225   if (write_callback_info.write_callback) {
2226     setup_tls_args_for_write_callback(fd_label, buf_label, count_label, true,
2227                                       fd_origin, buf_origin, count_origin);
2228     write_callback_info.write_callback(fd, buf, count);
2229   }
2230 
2231   *ret_label = 0;
2232   return write(fd, buf, count);
2233 }
2234 } // namespace __dfsan
2235 
2236 // Type used to extract a dfsan_label with va_arg()
2237 typedef int dfsan_label_va;
2238 
2239 // Formats a chunk either a constant string or a single format directive (e.g.,
2240 // '%.3f').
2241 struct Formatter {
2242   Formatter(char *str_, const char *fmt_, size_t size_)
2243       : str(str_),
2244         str_off(0),
2245         size(size_),
2246         fmt_start(fmt_),
2247         fmt_cur(fmt_),
2248         width(-1),
2249         num_scanned(-1),
2250         skip(false) {}
2251 
2252   int format() {
2253     char *tmp_fmt = build_format_string();
2254     int retval =
2255         snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt,
2256                  0 /* used only to avoid warnings */);
2257     free(tmp_fmt);
2258     return retval;
2259   }
2260 
2261   template <typename T> int format(T arg) {
2262     char *tmp_fmt = build_format_string();
2263     int retval;
2264     if (width >= 0) {
2265       retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2266                         tmp_fmt, width, arg);
2267     } else {
2268       retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
2269                         tmp_fmt, arg);
2270     }
2271     free(tmp_fmt);
2272     return retval;
2273   }
2274 
2275   int scan() {
2276     char *tmp_fmt = build_format_string(true);
2277     int read_count = 0;
2278     int retval = sscanf(str + str_off, tmp_fmt, &read_count);
2279     if (retval > 0) {
2280       if (-1 == num_scanned)
2281         num_scanned = 0;
2282       num_scanned += retval;
2283     }
2284     free(tmp_fmt);
2285     return read_count;
2286   }
2287 
2288   template <typename T>
2289   int scan(T arg) {
2290     char *tmp_fmt = build_format_string(true);
2291     int read_count = 0;
2292     int retval = sscanf(str + str_off, tmp_fmt, arg, &read_count);
2293     if (retval > 0) {
2294       if (-1 == num_scanned)
2295         num_scanned = 0;
2296       num_scanned += retval;
2297     }
2298     free(tmp_fmt);
2299     return read_count;
2300   }
2301 
2302   // with_n -> toggles adding %n on/off; off by default
2303   char *build_format_string(bool with_n = false) {
2304     size_t fmt_size = fmt_cur - fmt_start + 1;
2305     size_t add_size = 0;
2306     if (with_n)
2307       add_size = 2;
2308     char *new_fmt = (char *)malloc(fmt_size + 1 + add_size);
2309     assert(new_fmt);
2310     internal_memcpy(new_fmt, fmt_start, fmt_size);
2311     if (!with_n) {
2312       new_fmt[fmt_size] = '\0';
2313     } else {
2314       new_fmt[fmt_size] = '%';
2315       new_fmt[fmt_size + 1] = 'n';
2316       new_fmt[fmt_size + 2] = '\0';
2317     }
2318 
2319     return new_fmt;
2320   }
2321 
2322   char *str_cur() { return str + str_off; }
2323 
2324   size_t num_written_bytes(int retval) {
2325     if (retval < 0) {
2326       return 0;
2327     }
2328 
2329     size_t num_avail = str_off < size ? size - str_off : 0;
2330     if (num_avail == 0) {
2331       return 0;
2332     }
2333 
2334     size_t num_written = retval;
2335     // A return value of {v,}snprintf of size or more means that the output was
2336     // truncated.
2337     if (num_written >= num_avail) {
2338       num_written -= num_avail;
2339     }
2340 
2341     return num_written;
2342   }
2343 
2344   char *str;
2345   size_t str_off;
2346   size_t size;
2347   const char *fmt_start;
2348   const char *fmt_cur;
2349   int width;
2350   int num_scanned;
2351   bool skip;
2352 };
2353 
2354 // Formats the input and propagates the input labels to the output. The output
2355 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and
2356 // 'ap' are the format string and the list of arguments for formatting. Returns
2357 // the return value vsnprintf would return.
2358 //
2359 // The function tokenizes the format string in chunks representing either a
2360 // constant string or a single format directive (e.g., '%.3f') and formats each
2361 // chunk independently into the output string. This approach allows to figure
2362 // out which bytes of the output string depends on which argument and thus to
2363 // propagate labels more precisely.
2364 //
2365 // WARNING: This implementation does not support conversion specifiers with
2366 // positional arguments.
2367 static int format_buffer(char *str, size_t size, const char *fmt,
2368                          dfsan_label *va_labels, dfsan_label *ret_label,
2369                          dfsan_origin *va_origins, dfsan_origin *ret_origin,
2370                          va_list ap) {
2371   Formatter formatter(str, fmt, size);
2372 
2373   while (*formatter.fmt_cur) {
2374     formatter.fmt_start = formatter.fmt_cur;
2375     formatter.width = -1;
2376     int retval = 0;
2377 
2378     if (*formatter.fmt_cur != '%') {
2379       // Ordinary character. Consume all the characters until a '%' or the end
2380       // of the string.
2381       for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';
2382            ++formatter.fmt_cur) {}
2383       retval = formatter.format();
2384       dfsan_set_label(0, formatter.str_cur(),
2385                       formatter.num_written_bytes(retval));
2386     } else {
2387       // Conversion directive. Consume all the characters until a conversion
2388       // specifier or the end of the string.
2389       bool end_fmt = false;
2390       for (; *formatter.fmt_cur && !end_fmt; ) {
2391         switch (*++formatter.fmt_cur) {
2392         case 'd':
2393         case 'i':
2394         case 'o':
2395         case 'u':
2396         case 'x':
2397         case 'X':
2398           switch (*(formatter.fmt_cur - 1)) {
2399           case 'h':
2400             // Also covers the 'hh' case (since the size of the arg is still
2401             // an int).
2402             retval = formatter.format(va_arg(ap, int));
2403             break;
2404           case 'l':
2405             if (formatter.fmt_cur - formatter.fmt_start >= 2 &&
2406                 *(formatter.fmt_cur - 2) == 'l') {
2407               retval = formatter.format(va_arg(ap, long long int));
2408             } else {
2409               retval = formatter.format(va_arg(ap, long int));
2410             }
2411             break;
2412           case 'q':
2413             retval = formatter.format(va_arg(ap, long long int));
2414             break;
2415           case 'j':
2416             retval = formatter.format(va_arg(ap, intmax_t));
2417             break;
2418           case 'z':
2419           case 't':
2420             retval = formatter.format(va_arg(ap, size_t));
2421             break;
2422           default:
2423             retval = formatter.format(va_arg(ap, int));
2424           }
2425           if (va_origins == nullptr)
2426             dfsan_set_label(*va_labels++, formatter.str_cur(),
2427                             formatter.num_written_bytes(retval));
2428           else
2429             dfsan_set_label_origin(*va_labels++, *va_origins++,
2430                                    formatter.str_cur(),
2431                                    formatter.num_written_bytes(retval));
2432           end_fmt = true;
2433           break;
2434 
2435         case 'a':
2436         case 'A':
2437         case 'e':
2438         case 'E':
2439         case 'f':
2440         case 'F':
2441         case 'g':
2442         case 'G':
2443           if (*(formatter.fmt_cur - 1) == 'L') {
2444             retval = formatter.format(va_arg(ap, long double));
2445           } else {
2446             retval = formatter.format(va_arg(ap, double));
2447           }
2448           if (va_origins == nullptr)
2449             dfsan_set_label(*va_labels++, formatter.str_cur(),
2450                             formatter.num_written_bytes(retval));
2451           else
2452             dfsan_set_label_origin(*va_labels++, *va_origins++,
2453                                    formatter.str_cur(),
2454                                    formatter.num_written_bytes(retval));
2455           end_fmt = true;
2456           break;
2457 
2458         case 'c':
2459           retval = formatter.format(va_arg(ap, int));
2460           if (va_origins == nullptr)
2461             dfsan_set_label(*va_labels++, formatter.str_cur(),
2462                             formatter.num_written_bytes(retval));
2463           else
2464             dfsan_set_label_origin(*va_labels++, *va_origins++,
2465                                    formatter.str_cur(),
2466                                    formatter.num_written_bytes(retval));
2467           end_fmt = true;
2468           break;
2469 
2470         case 's': {
2471           char *arg = va_arg(ap, char *);
2472           retval = formatter.format(arg);
2473           if (va_origins) {
2474             va_origins++;
2475             dfsan_mem_origin_transfer(formatter.str_cur(), arg,
2476                                       formatter.num_written_bytes(retval));
2477           }
2478           va_labels++;
2479           dfsan_mem_shadow_transfer(formatter.str_cur(), arg,
2480                                     formatter.num_written_bytes(retval));
2481           end_fmt = true;
2482           break;
2483         }
2484 
2485         case 'p':
2486           retval = formatter.format(va_arg(ap, void *));
2487           if (va_origins == nullptr)
2488             dfsan_set_label(*va_labels++, formatter.str_cur(),
2489                             formatter.num_written_bytes(retval));
2490           else
2491             dfsan_set_label_origin(*va_labels++, *va_origins++,
2492                                    formatter.str_cur(),
2493                                    formatter.num_written_bytes(retval));
2494           end_fmt = true;
2495           break;
2496 
2497         case 'n': {
2498           int *ptr = va_arg(ap, int *);
2499           *ptr = (int)formatter.str_off;
2500           va_labels++;
2501           if (va_origins)
2502             va_origins++;
2503           dfsan_set_label(0, ptr, sizeof(ptr));
2504           end_fmt = true;
2505           break;
2506         }
2507 
2508         case '%':
2509           retval = formatter.format();
2510           dfsan_set_label(0, formatter.str_cur(),
2511                           formatter.num_written_bytes(retval));
2512           end_fmt = true;
2513           break;
2514 
2515         case '*':
2516           formatter.width = va_arg(ap, int);
2517           va_labels++;
2518           if (va_origins)
2519             va_origins++;
2520           break;
2521 
2522         default:
2523           break;
2524         }
2525       }
2526     }
2527 
2528     if (retval < 0) {
2529       return retval;
2530     }
2531 
2532     formatter.fmt_cur++;
2533     formatter.str_off += retval;
2534   }
2535 
2536   *ret_label = 0;
2537   if (ret_origin)
2538     *ret_origin = 0;
2539 
2540   // Number of bytes written in total.
2541   return formatter.str_off;
2542 }
2543 
2544 // This function is an inverse of format_buffer: we take the input buffer,
2545 // scan it in search for format strings and store the results in the varargs.
2546 // The labels are propagated from the input buffer to the varargs.
2547 static int scan_buffer(char *str, size_t size, const char *fmt,
2548                        dfsan_label *va_labels, dfsan_label *ret_label,
2549                        dfsan_origin *str_origin, dfsan_origin *ret_origin,
2550                        va_list ap) {
2551   Formatter formatter(str, fmt, size);
2552   while (*formatter.fmt_cur) {
2553     formatter.fmt_start = formatter.fmt_cur;
2554     formatter.width = -1;
2555     formatter.skip = false;
2556     int read_count = 0;
2557     void *dst_ptr = 0;
2558     size_t write_size = 0;
2559     if (*formatter.fmt_cur != '%') {
2560       // Ordinary character. Consume all the characters until a '%' or the end
2561       // of the string.
2562       for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';
2563            ++formatter.fmt_cur) {
2564       }
2565       read_count = formatter.scan();
2566       dfsan_set_label(0, formatter.str_cur(),
2567                       formatter.num_written_bytes(read_count));
2568     } else {
2569       // Conversion directive. Consume all the characters until a conversion
2570       // specifier or the end of the string.
2571       bool end_fmt = false;
2572       for (; *formatter.fmt_cur && !end_fmt;) {
2573         switch (*++formatter.fmt_cur) {
2574         case 'd':
2575         case 'i':
2576         case 'o':
2577         case 'u':
2578         case 'x':
2579         case 'X':
2580           if (formatter.skip) {
2581             read_count = formatter.scan();
2582           } else {
2583             switch (*(formatter.fmt_cur - 1)) {
2584             case 'h':
2585               // Also covers the 'hh' case (since the size of the arg is still
2586               // an int).
2587               dst_ptr = va_arg(ap, int *);
2588               read_count = formatter.scan((int *)dst_ptr);
2589               write_size = sizeof(int);
2590               break;
2591             case 'l':
2592               if (formatter.fmt_cur - formatter.fmt_start >= 2 &&
2593                   *(formatter.fmt_cur - 2) == 'l') {
2594                 dst_ptr = va_arg(ap, long long int *);
2595                 read_count = formatter.scan((long long int *)dst_ptr);
2596                 write_size = sizeof(long long int);
2597               } else {
2598                 dst_ptr = va_arg(ap, long int *);
2599                 read_count = formatter.scan((long int *)dst_ptr);
2600                 write_size = sizeof(long int);
2601               }
2602               break;
2603             case 'q':
2604               dst_ptr = va_arg(ap, long long int *);
2605               read_count = formatter.scan((long long int *)dst_ptr);
2606               write_size = sizeof(long long int);
2607               break;
2608             case 'j':
2609               dst_ptr = va_arg(ap, intmax_t *);
2610               read_count = formatter.scan((intmax_t *)dst_ptr);
2611               write_size = sizeof(intmax_t);
2612               break;
2613             case 'z':
2614             case 't':
2615               dst_ptr = va_arg(ap, size_t *);
2616               read_count = formatter.scan((size_t *)dst_ptr);
2617               write_size = sizeof(size_t);
2618               break;
2619             default:
2620               dst_ptr = va_arg(ap, int *);
2621               read_count = formatter.scan((int *)dst_ptr);
2622               write_size = sizeof(int);
2623             }
2624             // get the label associated with the string at the corresponding
2625             // place
2626             dfsan_label l = dfsan_read_label(
2627                 formatter.str_cur(), formatter.num_written_bytes(read_count));
2628             dfsan_set_label(l, dst_ptr, write_size);
2629             if (str_origin != nullptr) {
2630             dfsan_set_label(l, dst_ptr, write_size);
2631             size_t scan_count = formatter.num_written_bytes(read_count);
2632             size_t size = scan_count > write_size ? write_size : scan_count;
2633             dfsan_mem_origin_transfer(dst_ptr, formatter.str_cur(), size);
2634             }
2635           }
2636           end_fmt = true;
2637 
2638           break;
2639 
2640         case 'a':
2641         case 'A':
2642         case 'e':
2643         case 'E':
2644         case 'f':
2645         case 'F':
2646         case 'g':
2647         case 'G':
2648           if (formatter.skip) {
2649             read_count = formatter.scan();
2650           } else {
2651             if (*(formatter.fmt_cur - 1) == 'L') {
2652             dst_ptr = va_arg(ap, long double *);
2653             read_count = formatter.scan((long double *)dst_ptr);
2654             write_size = sizeof(long double);
2655             } else if (*(formatter.fmt_cur - 1) == 'l') {
2656             dst_ptr = va_arg(ap, double *);
2657             read_count = formatter.scan((double *)dst_ptr);
2658             write_size = sizeof(double);
2659             } else {
2660             dst_ptr = va_arg(ap, float *);
2661             read_count = formatter.scan((float *)dst_ptr);
2662             write_size = sizeof(float);
2663             }
2664             dfsan_label l = dfsan_read_label(
2665                 formatter.str_cur(), formatter.num_written_bytes(read_count));
2666             dfsan_set_label(l, dst_ptr, write_size);
2667             if (str_origin != nullptr) {
2668             dfsan_set_label(l, dst_ptr, write_size);
2669             size_t scan_count = formatter.num_written_bytes(read_count);
2670             size_t size = scan_count > write_size ? write_size : scan_count;
2671             dfsan_mem_origin_transfer(dst_ptr, formatter.str_cur(), size);
2672             }
2673           }
2674           end_fmt = true;
2675           break;
2676 
2677         case 'c':
2678           if (formatter.skip) {
2679             read_count = formatter.scan();
2680           } else {
2681             dst_ptr = va_arg(ap, char *);
2682             read_count = formatter.scan((char *)dst_ptr);
2683             write_size = sizeof(char);
2684             dfsan_label l = dfsan_read_label(
2685                 formatter.str_cur(), formatter.num_written_bytes(read_count));
2686             dfsan_set_label(l, dst_ptr, write_size);
2687             if (str_origin != nullptr) {
2688             size_t scan_count = formatter.num_written_bytes(read_count);
2689             size_t size = scan_count > write_size ? write_size : scan_count;
2690             dfsan_mem_origin_transfer(dst_ptr, formatter.str_cur(), size);
2691             }
2692           }
2693           end_fmt = true;
2694           break;
2695 
2696         case 's': {
2697           if (formatter.skip) {
2698             read_count = formatter.scan();
2699           } else {
2700             dst_ptr = va_arg(ap, char *);
2701             read_count = formatter.scan((char *)dst_ptr);
2702             if (1 == read_count) {
2703             // special case: we have parsed a single string and we need to
2704             // update read_count with the string size
2705             read_count = strlen((char *)dst_ptr);
2706             }
2707             if (str_origin)
2708             dfsan_mem_origin_transfer(dst_ptr, formatter.str_cur(),
2709                                       formatter.num_written_bytes(read_count));
2710             va_labels++;
2711             dfsan_mem_shadow_transfer(dst_ptr, formatter.str_cur(),
2712                                       formatter.num_written_bytes(read_count));
2713           }
2714           end_fmt = true;
2715           break;
2716         }
2717 
2718         case 'p':
2719           if (formatter.skip) {
2720             read_count = formatter.scan();
2721           } else {
2722             dst_ptr = va_arg(ap, void *);
2723             read_count =
2724                 formatter.scan((int *)dst_ptr);  // note: changing void* to int*
2725                                                  // since we need to call sizeof
2726             write_size = sizeof(int);
2727 
2728             dfsan_label l = dfsan_read_label(
2729                 formatter.str_cur(), formatter.num_written_bytes(read_count));
2730             dfsan_set_label(l, dst_ptr, write_size);
2731             if (str_origin != nullptr) {
2732             dfsan_set_label(l, dst_ptr, write_size);
2733             size_t scan_count = formatter.num_written_bytes(read_count);
2734             size_t size = scan_count > write_size ? write_size : scan_count;
2735             dfsan_mem_origin_transfer(dst_ptr, formatter.str_cur(), size);
2736             }
2737           }
2738           end_fmt = true;
2739           break;
2740 
2741         case 'n': {
2742           if (!formatter.skip) {
2743             int *ptr = va_arg(ap, int *);
2744             *ptr = (int)formatter.str_off;
2745             *va_labels++ = 0;
2746             dfsan_set_label(0, ptr, sizeof(*ptr));
2747             if (str_origin != nullptr)
2748             *str_origin++ = 0;
2749           }
2750           end_fmt = true;
2751           break;
2752         }
2753 
2754         case '%':
2755           read_count = formatter.scan();
2756           end_fmt = true;
2757           break;
2758 
2759         case '*':
2760           formatter.skip = true;
2761           break;
2762 
2763         default:
2764           break;
2765         }
2766       }
2767     }
2768 
2769     if (read_count < 0) {
2770       // There was an error.
2771       return read_count;
2772     }
2773 
2774     formatter.fmt_cur++;
2775     formatter.str_off += read_count;
2776   }
2777 
2778   (void)va_labels; // Silence unused-but-set-parameter warning
2779   *ret_label = 0;
2780   if (ret_origin)
2781     *ret_origin = 0;
2782 
2783   // Number of items scanned in total.
2784   return formatter.num_scanned;
2785 }
2786 
2787 extern "C" {
2788 SANITIZER_INTERFACE_ATTRIBUTE
2789 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,
2790                    dfsan_label format_label, dfsan_label *va_labels,
2791                    dfsan_label *ret_label, ...) {
2792   va_list ap;
2793   va_start(ap, ret_label);
2794 
2795   int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
2796                           nullptr, ap);
2797   va_end(ap);
2798   return ret;
2799 }
2800 
2801 SANITIZER_INTERFACE_ATTRIBUTE
2802 int __dfso_sprintf(char *str, const char *format, dfsan_label str_label,
2803                    dfsan_label format_label, dfsan_label *va_labels,
2804                    dfsan_label *ret_label, dfsan_origin str_origin,
2805                    dfsan_origin format_origin, dfsan_origin *va_origins,
2806                    dfsan_origin *ret_origin, ...) {
2807   va_list ap;
2808   va_start(ap, ret_origin);
2809   int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins,
2810                           ret_origin, ap);
2811   va_end(ap);
2812   return ret;
2813 }
2814 
2815 SANITIZER_INTERFACE_ATTRIBUTE
2816 int __dfsw_snprintf(char *str, size_t size, const char *format,
2817                     dfsan_label str_label, dfsan_label size_label,
2818                     dfsan_label format_label, dfsan_label *va_labels,
2819                     dfsan_label *ret_label, ...) {
2820   va_list ap;
2821   va_start(ap, ret_label);
2822   int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr,
2823                           nullptr, ap);
2824   va_end(ap);
2825   return ret;
2826 }
2827 
2828 SANITIZER_INTERFACE_ATTRIBUTE
2829 int __dfso_snprintf(char *str, size_t size, const char *format,
2830                     dfsan_label str_label, dfsan_label size_label,
2831                     dfsan_label format_label, dfsan_label *va_labels,
2832                     dfsan_label *ret_label, dfsan_origin str_origin,
2833                     dfsan_origin size_origin, dfsan_origin format_origin,
2834                     dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) {
2835   va_list ap;
2836   va_start(ap, ret_origin);
2837   int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins,
2838                           ret_origin, ap);
2839   va_end(ap);
2840   return ret;
2841 }
2842 
2843 SANITIZER_INTERFACE_ATTRIBUTE
2844 int __dfsw_sscanf(char *str, const char *format, dfsan_label str_label,
2845                   dfsan_label format_label, dfsan_label *va_labels,
2846                   dfsan_label *ret_label, ...) {
2847   va_list ap;
2848   va_start(ap, ret_label);
2849   int ret = scan_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
2850                         nullptr, ap);
2851   va_end(ap);
2852   return ret;
2853 }
2854 
2855 SANITIZER_INTERFACE_ATTRIBUTE
2856 int __dfso_sscanf(char *str, const char *format, dfsan_label str_label,
2857                   dfsan_label format_label, dfsan_label *va_labels,
2858                   dfsan_label *ret_label, dfsan_origin str_origin,
2859                   dfsan_origin format_origin, dfsan_origin *va_origins,
2860                   dfsan_origin *ret_origin, ...) {
2861   va_list ap;
2862   va_start(ap, ret_origin);
2863   int ret = scan_buffer(str, ~0ul, format, va_labels, ret_label, &str_origin,
2864                         ret_origin, ap);
2865   va_end(ap);
2866   return ret;
2867 }
2868 
2869 SANITIZER_INTERFACE_ATTRIBUTE
2870 int __dfsw___isoc99_sscanf(char *str, const char *format, dfsan_label str_label,
2871                            dfsan_label format_label, dfsan_label *va_labels,
2872                            dfsan_label *ret_label, ...) {
2873   va_list ap;
2874   va_start(ap, ret_label);
2875   int ret = scan_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
2876                         nullptr, ap);
2877   va_end(ap);
2878   return ret;
2879 }
2880 
2881 SANITIZER_INTERFACE_ATTRIBUTE
2882 int __dfso___isoc99_sscanf(char *str, const char *format, dfsan_label str_label,
2883                            dfsan_label format_label, dfsan_label *va_labels,
2884                            dfsan_label *ret_label, dfsan_origin str_origin,
2885                            dfsan_origin format_origin, dfsan_origin *va_origins,
2886                            dfsan_origin *ret_origin, ...) {
2887   va_list ap;
2888   va_start(ap, ret_origin);
2889   int ret = scan_buffer(str, ~0ul, format, va_labels, ret_label, &str_origin,
2890                         ret_origin, ap);
2891   va_end(ap);
2892   return ret;
2893 }
2894 
2895 static void BeforeFork() {
2896   StackDepotLockBeforeFork();
2897   ChainedOriginDepotLockBeforeFork();
2898 }
2899 
2900 static void AfterFork(bool fork_child) {
2901   ChainedOriginDepotUnlockAfterFork(fork_child);
2902   StackDepotUnlockAfterFork(fork_child);
2903 }
2904 
2905 SANITIZER_INTERFACE_ATTRIBUTE
2906 pid_t __dfsw_fork(dfsan_label *ret_label) {
2907   pid_t pid = fork();
2908   *ret_label = 0;
2909   return pid;
2910 }
2911 
2912 SANITIZER_INTERFACE_ATTRIBUTE
2913 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) {
2914   BeforeFork();
2915   pid_t pid = __dfsw_fork(ret_label);
2916   AfterFork(/* fork_child= */ pid == 0);
2917   return pid;
2918 }
2919 
2920 // Default empty implementations (weak). Users should redefine them.
2921 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {}
2922 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *,
2923                              u32 *) {}
2924 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg,
2925                              const uptr *end) {}
2926 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
2927 
2928 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {}
2929 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {}
2930 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {}
2931 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {}
2932 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {}
2933 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1,
2934                              void) {}
2935 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2,
2936                              void) {}
2937 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4,
2938                              void) {}
2939 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8,
2940                              void) {}
2941 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {}
2942 }  // extern "C"
2943