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