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