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