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