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