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