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