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