1 // RUN: %clang_dfsan %s -o %t && env DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
2 // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
3 // RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
4 // RUN: %clang_dfsan -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -mllvm -dfsan-combine-pointer-labels-on-load=false -no-pie %s -o %t && env DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
6 // Tests custom implementations of various glibc functions.
8 #pragma clang diagnostic ignored "-Wformat-extra-args"
10 #include <sanitizer/dfsan_interface.h>
12 #include <arpa/inet.h>
26 #include <sys/epoll.h>
27 #include <sys/resource.h>
28 #include <sys/select.h>
29 #include <sys/socket.h>
32 #include <sys/types.h>
36 dfsan_label i_label
= 0;
37 dfsan_label j_label
= 0;
38 dfsan_label k_label
= 0;
39 dfsan_label m_label
= 0;
40 dfsan_label n_label
= 0;
41 dfsan_label i_j_label
= 0;
43 #define ASSERT_ZERO_LABEL(data) \
44 assert(0 == dfsan_get_label((long) (data)))
46 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
47 assert(0 == dfsan_read_label(ptr, size))
49 #define ASSERT_LABEL(data, label) \
50 assert(label == dfsan_get_label((long) (data)))
52 #define ASSERT_READ_LABEL(ptr, size, label) \
53 assert(label == dfsan_read_label(ptr, size))
55 #ifdef ORIGIN_TRACKING
56 #define ASSERT_ZERO_ORIGIN(data) \
57 assert(0 == dfsan_get_origin((long)(data)))
59 #define ASSERT_ZERO_ORIGIN(data)
62 #ifdef ORIGIN_TRACKING
63 #define ASSERT_ZERO_ORIGINS(ptr, size) \
64 for (int i = 0; i < size; ++i) { \
65 assert(0 == dfsan_get_origin((long)(((char *)ptr)[i]))); \
68 #define ASSERT_ZERO_ORIGINS(ptr, size)
71 #ifdef ORIGIN_TRACKING
72 #define ASSERT_ORIGIN(data, origin) \
73 assert(origin == dfsan_get_origin((long)(data)))
75 #define ASSERT_ORIGIN(data, origin)
78 #ifdef ORIGIN_TRACKING
79 #define ASSERT_ORIGINS(ptr, size, origin) \
80 for (int i = 0; i < size; ++i) { \
81 assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \
84 #define ASSERT_ORIGINS(ptr, size, origin)
87 #ifdef ORIGIN_TRACKING
88 #define ASSERT_INIT_ORIGIN(ptr, origin) \
89 assert(origin == dfsan_get_init_origin(ptr))
91 #define ASSERT_INIT_ORIGIN(ptr, origin)
94 #ifdef ORIGIN_TRACKING
95 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) \
96 assert(dfsan_get_origin((long)(data)) == dfsan_get_init_origin(ptr))
98 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data)
101 #ifdef ORIGIN_TRACKING
102 #define ASSERT_INIT_ORIGINS(ptr, size, origin) \
103 for (int i = 0; i < size; ++i) { \
104 assert(origin == dfsan_get_init_origin(&((char *)ptr)[i])); \
107 #define ASSERT_INIT_ORIGINS(ptr, size, origin)
110 #ifdef ORIGIN_TRACKING
111 #define ASSERT_EQ_ORIGIN(data1, data2) \
112 assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2)))
114 #define ASSERT_EQ_ORIGIN(data1, data2)
117 #ifdef ORIGIN_TRACKING
118 #define DEFINE_AND_SAVE_ORIGINS(val) \
119 dfsan_origin val##_o[sizeof(val)]; \
120 for (int i = 0; i < sizeof(val); ++i) \
121 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
123 #define DEFINE_AND_SAVE_ORIGINS(val)
126 #ifdef ORIGIN_TRACKING
127 #define SAVE_ORIGINS(val) \
128 for (int i = 0; i < sizeof(val); ++i) \
129 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
131 #define SAVE_ORIGINS(val)
134 #ifdef ORIGIN_TRACKING
135 #define ASSERT_SAVED_ORIGINS(val) \
136 for (int i = 0; i < sizeof(val); ++i) \
137 ASSERT_ORIGIN(((char *)(&val))[i], val##_o[i]);
139 #define ASSERT_SAVED_ORIGINS(val)
142 #ifdef ORIGIN_TRACKING
143 #define DEFINE_AND_SAVE_N_ORIGINS(val, n) \
144 dfsan_origin val##_o[n]; \
145 for (int i = 0; i < n; ++i) \
146 val##_o[i] = dfsan_get_origin((long)(val[i]));
148 #define DEFINE_AND_SAVE_N_ORIGINS(val, n)
151 #ifdef ORIGIN_TRACKING
152 #define ASSERT_SAVED_N_ORIGINS(val, n) \
153 for (int i = 0; i < n; ++i) \
154 ASSERT_ORIGIN(val[i], val##_o[i]);
156 #define ASSERT_SAVED_N_ORIGINS(val, n)
159 #if !defined(__GLIBC_PREREQ)
160 # define __GLIBC_PREREQ(a, b) 0
165 dfsan_set_label(i_label
, &i
, sizeof(i
));
169 DEFINE_AND_SAVE_ORIGINS(s
)
170 int ret
= stat("/", &s
);
172 ASSERT_ZERO_LABEL(ret
);
173 ASSERT_ZERO_LABEL(s
.st_dev
);
174 ASSERT_SAVED_ORIGINS(s
)
178 ret
= stat("/nonexistent_581cb021aba7", &s
);
180 ASSERT_ZERO_LABEL(ret
);
181 ASSERT_LABEL(s
.st_dev
, i_label
);
182 ASSERT_SAVED_ORIGINS(s
)
187 dfsan_set_label(i_label
, &i
, sizeof(i
));
190 int fd
= open("/dev/zero", O_RDONLY
);
192 DEFINE_AND_SAVE_ORIGINS(s
)
193 int rv
= fstat(fd
, &s
);
195 ASSERT_ZERO_LABEL(rv
);
196 ASSERT_ZERO_LABEL(s
.st_dev
);
197 ASSERT_SAVED_ORIGINS(s
)
201 char str1
[] = "str1", str2
[] = "str2";
202 dfsan_set_label(i_label
, &str1
[3], 1);
203 dfsan_set_label(j_label
, &str2
[3], 1);
205 int rv
= memcmp(str1
, str2
, sizeof(str1
));
207 #ifdef STRICT_DATA_DEPENDENCIES
208 ASSERT_ZERO_LABEL(rv
);
210 ASSERT_LABEL(rv
, i_j_label
);
211 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
214 rv
= memcmp(str1
, str2
, sizeof(str1
) - 2);
216 ASSERT_ZERO_LABEL(rv
);
220 char str1
[] = "str1", str2
[] = "str2";
221 dfsan_set_label(i_label
, &str1
[3], 1);
222 dfsan_set_label(j_label
, &str2
[3], 1);
224 int rv
= bcmp(str1
, str2
, sizeof(str1
));
226 #ifdef STRICT_DATA_DEPENDENCIES
227 ASSERT_ZERO_LABEL(rv
);
229 ASSERT_LABEL(rv
, i_j_label
);
230 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
233 rv
= bcmp(str1
, str2
, sizeof(str1
) - 2);
235 ASSERT_ZERO_LABEL(rv
);
239 char str1
[] = "str1";
240 char str2
[sizeof(str1
)];
241 dfsan_set_label(i_label
, &str1
[3], 1);
243 DEFINE_AND_SAVE_ORIGINS(str1
)
246 dfsan_set_label(j_label
, &ptr2
, sizeof(ptr2
));
248 void *r
= memcpy(ptr2
, str1
, sizeof(str1
));
249 ASSERT_LABEL(r
, j_label
);
250 ASSERT_EQ_ORIGIN(r
, ptr2
);
251 assert(0 == memcmp(str2
, str1
, sizeof(str1
)));
252 ASSERT_ZERO_LABEL(str2
[0]);
253 ASSERT_LABEL(str2
[3], i_label
);
255 for (int i
= 0; i
< sizeof(str2
); ++i
) {
256 if (!dfsan_get_label(str2
[i
]))
258 ASSERT_INIT_ORIGIN(&(str2
[i
]), str1_o
[i
]);
262 void test_memmove() {
263 char str
[] = "str1xx";
264 dfsan_set_label(i_label
, &str
[3], 1);
266 DEFINE_AND_SAVE_ORIGINS(str
)
269 dfsan_set_label(j_label
, &ptr
, sizeof(ptr
));
271 void *r
= memmove(ptr
, str
, 4);
272 ASSERT_LABEL(r
, j_label
);
273 ASSERT_EQ_ORIGIN(r
, ptr
);
274 assert(0 == memcmp(str
+ 2, "str1", 4));
275 ASSERT_ZERO_LABEL(str
[4]);
276 ASSERT_LABEL(str
[5], i_label
);
278 for (int i
= 0; i
< 4; ++i
) {
279 if (!dfsan_get_label(ptr
[i
]))
281 ASSERT_INIT_ORIGIN(&(ptr
[i
]), str_o
[i
]);
289 dfsan_set_label(j_label
, &j
, sizeof(j
));
290 dfsan_set_label(k_label
, &ptr
, sizeof(ptr
));
291 void *ret
= memset(ptr
, j
, sizeof(buf
));
292 ASSERT_LABEL(ret
, k_label
);
293 ASSERT_EQ_ORIGIN(ret
, ptr
);
294 for (int i
= 0; i
< 8; ++i
) {
295 ASSERT_LABEL(buf
[i
], j_label
);
296 ASSERT_EQ_ORIGIN(buf
[i
], j
);
297 assert(buf
[i
] == 'a');
302 char str1
[] = "str1", str2
[] = "str2";
303 dfsan_set_label(i_label
, &str1
[3], 1);
304 dfsan_set_label(j_label
, &str2
[3], 1);
306 int rv
= strcmp(str1
, str2
);
308 #ifdef STRICT_DATA_DEPENDENCIES
309 ASSERT_ZERO_LABEL(rv
);
311 ASSERT_LABEL(rv
, i_j_label
);
312 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
315 rv
= strcmp(str1
, str1
);
317 #ifdef STRICT_DATA_DEPENDENCIES
318 ASSERT_ZERO_LABEL(rv
);
319 ASSERT_ZERO_ORIGIN(rv
);
321 ASSERT_LABEL(rv
, i_label
);
322 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
327 char src
[] = "world";
328 int volatile x
= 0; // buffer to ensure src and dst do not share origins
330 char dst
[] = "hello \0 ";
331 int volatile y
= 0; // buffer to ensure dst and p do not share origins
334 dfsan_set_label(k_label
, &p
, sizeof(p
));
335 dfsan_set_label(i_label
, src
, sizeof(src
));
336 dfsan_set_label(j_label
, dst
, sizeof(dst
));
337 dfsan_origin dst_o
= dfsan_get_origin((long)dst
[0]);
339 char *ret
= strcat(p
, src
);
341 ASSERT_LABEL(ret
, k_label
);
342 ASSERT_EQ_ORIGIN(ret
, p
);
344 assert(strcmp(src
, dst
+ 6) == 0);
345 // Origins are assigned for every 4 contiguous 4-aligned bytes. After
346 // appending src to dst, origins of src can overwrite origins of dst if their
347 // application adddresses are within [start_aligned_down, end_aligned_up).
348 // Other origins are not changed.
349 char *start_aligned_down
= (char *)(((size_t)(dst
+ 6)) & ~3UL);
350 char *end_aligned_up
= (char *)(((size_t)(dst
+ 11 + 4)) & ~3UL);
351 for (int i
= 0; i
< 12; ++i
) {
352 if (dst
+ i
< start_aligned_down
|| dst
+ i
>= end_aligned_up
) {
353 ASSERT_INIT_ORIGIN(&dst
[i
], dst_o
);
355 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst
[i
], src
[0]);
358 for (int i
= 0; i
< 6; ++i
) {
359 ASSERT_LABEL(dst
[i
], j_label
);
361 for (int i
= 6; i
< strlen(dst
); ++i
) {
362 ASSERT_LABEL(dst
[i
], i_label
);
363 assert(dfsan_get_label(dst
[i
]) == dfsan_get_label(src
[i
- 6]));
365 ASSERT_LABEL(dst
[11], j_label
);
368 void test_strncat(int n
) {
369 char src
[] = "world";
370 int volatile x
= 0; // buffer to ensure src and dst do not share origins
372 char dst
[] = "hello \0 ";
373 int volatile y
= 0; // buffer to ensure dst and p do not share origins
376 dfsan_set_label(k_label
, &p
, sizeof(p
));
377 dfsan_set_label(i_label
, src
, sizeof(src
));
378 dfsan_set_label(j_label
, dst
, sizeof(dst
));
379 dfsan_origin dst_o
= dfsan_get_origin((long)dst
[0]);
381 char *ret
= strncat(p
, src
, n
);
383 ASSERT_LABEL(ret
, k_label
);
384 ASSERT_EQ_ORIGIN(ret
, p
);
386 assert(strncmp(src
, dst
+ 6, n
) == 0);
387 // Origins are assigned for every 4 contiguous 4-aligned bytes. After
388 // appending src to dst, origins of src can overwrite origins of dst if their
389 // application adddresses are within [start_aligned_down, end_aligned_up).
390 // Other origins are not changed.
395 char *start_aligned_down
= (char *)(((size_t)(dst
+ 6)) & ~3UL);
396 char *end_aligned_up
= (char *)(((size_t)(dst
+ 6 + n
+ pad
)) & ~3UL);
398 for (int i
= 0; i
< 12; ++i
) {
399 if (dst
+ i
< start_aligned_down
|| dst
+ i
>= end_aligned_up
) {
400 ASSERT_INIT_ORIGIN(&dst
[i
], dst_o
);
402 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst
[i
], src
[0]);
405 for (int i
= 0; i
< 6; ++i
) {
406 ASSERT_LABEL(dst
[i
], j_label
);
408 for (int i
= 6; i
< 6 + n
; ++i
) {
409 ASSERT_LABEL(dst
[i
], i_label
);
410 assert(dfsan_get_label(dst
[i
]) == dfsan_get_label(src
[i
- 6]));
412 for (int i
= 6 + n
; i
< strlen(dst
); ++i
) {
413 ASSERT_LABEL(dst
[i
], j_label
);
415 ASSERT_LABEL(dst
[11], j_label
);
419 char str1
[] = "str1";
420 dfsan_set_label(i_label
, &str1
[3], 1);
422 int rv
= strlen(str1
);
424 #ifdef STRICT_DATA_DEPENDENCIES
425 ASSERT_ZERO_LABEL(rv
);
427 ASSERT_LABEL(rv
, i_label
);
428 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
432 void test_strnlen() {
433 char str1
[] = "str1";
434 dfsan_set_label(i_label
, &str1
[3], 1);
437 dfsan_set_label(j_label
, &maxlen
, sizeof(maxlen
));
439 int rv
= strnlen(str1
, maxlen
);
441 #ifdef STRICT_DATA_DEPENDENCIES
442 ASSERT_ZERO_LABEL(rv
);
444 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
445 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
449 dfsan_set_label(j_label
, &maxlen
, sizeof(maxlen
));
450 rv
= strnlen(str1
, maxlen
);
452 #ifdef STRICT_DATA_DEPENDENCIES
453 ASSERT_ZERO_LABEL(rv
);
455 ASSERT_LABEL(rv
, j_label
);
456 ASSERT_EQ_ORIGIN(rv
, maxlen
);
461 char str1
[] = "str1";
462 dfsan_set_label(i_label
, &str1
[3], 1);
463 DEFINE_AND_SAVE_ORIGINS(str1
)
465 char *strd
= strdup(str1
);
466 ASSERT_ZERO_LABEL(strd
);
467 ASSERT_ZERO_LABEL(strd
[0]);
468 ASSERT_LABEL(strd
[3], i_label
);
470 for (int i
= 0; i
< strlen(strd
); ++i
) {
471 if (!dfsan_get_label(strd
[i
]))
473 ASSERT_INIT_ORIGIN(&(strd
[i
]), str1_o
[i
]);
479 void test_strncpy() {
480 char str1
[] = "str1";
481 char str2
[sizeof(str1
)];
482 dfsan_set_label(i_label
, &str1
[3], 1);
484 char *strd
= strncpy(str2
, str1
, 5);
485 assert(strd
== str2
);
486 assert(strcmp(str1
, str2
) == 0);
487 ASSERT_ZERO_LABEL(strd
);
488 ASSERT_ZERO_LABEL(strd
[0]);
489 ASSERT_ZERO_LABEL(strd
[1]);
490 ASSERT_ZERO_LABEL(strd
[2]);
491 ASSERT_LABEL(strd
[3], i_label
);
492 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd
[3]), str1
[3]);
495 dfsan_set_label(j_label
, &p2
, sizeof(p2
));
496 strd
= strncpy(p2
, str1
, 3);
497 assert(strd
== str2
);
498 assert(strncmp(str1
, str2
, 3) == 0);
499 ASSERT_LABEL(strd
, j_label
);
500 ASSERT_EQ_ORIGIN(strd
, p2
);
501 // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates
502 // to strd[i]'s label. When ORIGIN_TRACKING is defined,
503 // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag
505 #if defined(ORIGIN_TRACKING)
506 ASSERT_ZERO_LABEL(strd
[0]);
507 ASSERT_ZERO_LABEL(strd
[1]);
508 ASSERT_ZERO_LABEL(strd
[2]);
510 ASSERT_LABEL(strd
[0], j_label
);
511 ASSERT_LABEL(strd
[1], j_label
);
512 ASSERT_LABEL(strd
[2], j_label
);
516 void test_strncmp() {
517 char str1
[] = "str1", str2
[] = "str2";
518 dfsan_set_label(i_label
, &str1
[3], 1);
519 dfsan_set_label(j_label
, &str2
[3], 1);
521 int rv
= strncmp(str1
, str2
, sizeof(str1
));
523 #ifdef STRICT_DATA_DEPENDENCIES
524 ASSERT_ZERO_LABEL(rv
);
526 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
527 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
530 rv
= strncmp(str1
, str2
, 0);
532 ASSERT_ZERO_LABEL(rv
);
534 rv
= strncmp(str1
, str2
, 3);
536 ASSERT_ZERO_LABEL(rv
);
538 rv
= strncmp(str1
, str1
, 4);
540 #ifdef STRICT_DATA_DEPENDENCIES
541 ASSERT_ZERO_LABEL(rv
);
543 ASSERT_LABEL(rv
, i_label
);
544 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
548 void test_strcasecmp() {
549 char str1
[] = "str1", str2
[] = "str2", str3
[] = "Str1";
550 dfsan_set_label(i_label
, &str1
[3], 1);
551 dfsan_set_label(j_label
, &str2
[3], 1);
552 dfsan_set_label(j_label
, &str3
[2], 1);
554 int rv
= strcasecmp(str1
, str2
);
556 #ifdef STRICT_DATA_DEPENDENCIES
557 ASSERT_ZERO_LABEL(rv
);
559 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
560 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
563 rv
= strcasecmp(str1
, str3
);
565 #ifdef STRICT_DATA_DEPENDENCIES
566 ASSERT_ZERO_LABEL(rv
);
568 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
569 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
574 dfsan_set_label(i_label
, &s1
[2], 1);
575 dfsan_set_label(j_label
, &s2
[2], 1);
577 rv
= strcasecmp(s1
, s2
);
578 assert(rv
> 0); // 'Z' > 'y'
579 #ifdef STRICT_DATA_DEPENDENCIES
580 ASSERT_ZERO_LABEL(rv
);
582 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
583 ASSERT_EQ_ORIGIN(rv
, s1
[2]);
587 void test_strncasecmp() {
588 char str1
[] = "Str1", str2
[] = "str2";
589 dfsan_set_label(i_label
, &str1
[3], 1);
590 dfsan_set_label(j_label
, &str2
[3], 1);
592 int rv
= strncasecmp(str1
, str2
, sizeof(str1
));
594 #ifdef STRICT_DATA_DEPENDENCIES
595 ASSERT_ZERO_LABEL(rv
);
597 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
598 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
601 rv
= strncasecmp(str1
, str2
, 3);
603 ASSERT_ZERO_LABEL(rv
);
607 dfsan_set_label(i_label
, &s1
[2], 1);
608 dfsan_set_label(j_label
, &s2
[2], 1);
610 rv
= strncasecmp(s1
, s2
, 0);
611 assert(rv
== 0); // Compare zero chars.
612 ASSERT_ZERO_LABEL(rv
);
614 rv
= strncasecmp(s1
, s2
, 1);
615 assert(rv
== 0); // 'A' == 'a'
616 ASSERT_ZERO_LABEL(rv
);
618 rv
= strncasecmp(s1
, s2
, 2);
619 assert(rv
== 0); // 'b' == 'B'
620 ASSERT_ZERO_LABEL(rv
);
622 rv
= strncasecmp(s1
, s2
, 3);
623 assert(rv
> 0); // 'Z' > 'y'
624 #ifdef STRICT_DATA_DEPENDENCIES
625 ASSERT_ZERO_LABEL(rv
);
627 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
628 ASSERT_EQ_ORIGIN(rv
, s1
[2]);
633 char str1
[] = "str1";
634 dfsan_set_label(i_label
, &str1
[3], 1);
638 dfsan_set_label(k_label
, &c
, sizeof(c
));
640 char *crv
= strchr(p1
, c
);
641 assert(crv
== &str1
[2]);
642 #ifdef STRICT_DATA_DEPENDENCIES
643 ASSERT_ZERO_LABEL(crv
);
645 ASSERT_LABEL(crv
, k_label
);
646 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, c
);
649 dfsan_set_label(j_label
, &p1
, sizeof(p1
));
650 crv
= strchr(p1
, 'r');
651 assert(crv
== &str1
[2]);
652 ASSERT_LABEL(crv
, j_label
);
653 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
655 crv
= strchr(p1
, '1');
656 assert(crv
== &str1
[3]);
657 #ifdef STRICT_DATA_DEPENDENCIES
658 ASSERT_LABEL(crv
, j_label
);
659 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
661 ASSERT_LABEL(crv
, i_j_label
);
662 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
665 crv
= strchr(p1
, 'x');
667 #ifdef STRICT_DATA_DEPENDENCIES
668 ASSERT_LABEL(crv
, j_label
);
669 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
671 ASSERT_LABEL(crv
, i_j_label
);
672 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
675 // `man strchr` says:
676 // The terminating null byte is considered part of the string, so that if c
677 // is specified as '\0', these functions return a pointer to the terminator.
678 crv
= strchr(p1
, '\0');
679 assert(crv
== &str1
[4]);
680 #ifdef STRICT_DATA_DEPENDENCIES
681 ASSERT_LABEL(crv
, j_label
);
682 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
684 ASSERT_LABEL(crv
, i_j_label
);
685 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
689 void test_recvmmsg() {
691 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
694 // Setup messages to send.
695 struct mmsghdr smmsg
[2] = {};
696 char sbuf0
[] = "abcdefghijkl";
697 struct iovec siov0
[2] = {{&sbuf0
[0], 4}, {&sbuf0
[4], 4}};
698 smmsg
[0].msg_hdr
.msg_iov
= siov0
;
699 smmsg
[0].msg_hdr
.msg_iovlen
= 2;
700 char sbuf1
[] = "1234567890";
701 struct iovec siov1
[1] = {{&sbuf1
[0], 7}};
702 smmsg
[1].msg_hdr
.msg_iov
= siov1
;
703 smmsg
[1].msg_hdr
.msg_iovlen
= 1;
706 int sent_msgs
= sendmmsg(sockfds
[0], smmsg
, 2, 0);
707 assert(sent_msgs
== 2);
709 // Setup receive buffers.
710 struct mmsghdr rmmsg
[2] = {};
712 struct iovec riov0
[2] = {{&rbuf0
[0], 4}, {&rbuf0
[4], 4}};
713 rmmsg
[0].msg_hdr
.msg_iov
= riov0
;
714 rmmsg
[0].msg_hdr
.msg_iovlen
= 2;
716 struct iovec riov1
[1] = {{&rbuf1
[0], 16}};
717 rmmsg
[1].msg_hdr
.msg_iov
= riov1
;
718 rmmsg
[1].msg_hdr
.msg_iovlen
= 1;
719 struct timespec timeout
= {1, 1};
720 dfsan_set_label(i_label
, rbuf0
, sizeof(rbuf0
));
721 dfsan_set_label(i_label
, rbuf1
, sizeof(rbuf1
));
722 dfsan_set_label(i_label
, &rmmsg
[0].msg_len
, sizeof(rmmsg
[0].msg_len
));
723 dfsan_set_label(i_label
, &rmmsg
[1].msg_len
, sizeof(rmmsg
[1].msg_len
));
724 dfsan_set_label(i_label
, &timeout
, sizeof(timeout
));
726 dfsan_origin msg_len0_o
= dfsan_get_origin((long)(rmmsg
[0].msg_len
));
727 dfsan_origin msg_len1_o
= dfsan_get_origin((long)(rmmsg
[1].msg_len
));
728 #ifndef ORIGIN_TRACKING
733 // Receive messages and check labels.
734 int received_msgs
= recvmmsg(sockfds
[1], rmmsg
, 2, 0, &timeout
);
735 assert(received_msgs
== sent_msgs
);
736 assert(rmmsg
[0].msg_len
== smmsg
[0].msg_len
);
737 assert(rmmsg
[1].msg_len
== smmsg
[1].msg_len
);
738 assert(memcmp(sbuf0
, rbuf0
, 8) == 0);
739 assert(memcmp(sbuf1
, rbuf1
, 7) == 0);
740 ASSERT_ZERO_LABEL(received_msgs
);
741 ASSERT_ZERO_LABEL(rmmsg
[0].msg_len
);
742 ASSERT_ZERO_LABEL(rmmsg
[1].msg_len
);
743 ASSERT_READ_ZERO_LABEL(&rbuf0
[0], 8);
744 ASSERT_READ_LABEL(&rbuf0
[8], 1, i_label
);
745 ASSERT_READ_ZERO_LABEL(&rbuf1
[0], 7);
746 ASSERT_READ_LABEL(&rbuf1
[7], 1, i_label
);
747 ASSERT_LABEL(timeout
.tv_sec
, i_label
);
748 ASSERT_LABEL(timeout
.tv_nsec
, i_label
);
750 ASSERT_ORIGIN((long)(rmmsg
[0].msg_len
), msg_len0_o
);
751 ASSERT_ORIGIN((long)(rmmsg
[1].msg_len
), msg_len1_o
);
757 void test_recvmsg() {
759 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
762 char sbuf
[] = "abcdefghijkl";
763 struct iovec siovs
[2] = {{&sbuf
[0], 4}, {&sbuf
[4], 4}};
764 struct msghdr smsg
= {};
765 smsg
.msg_iov
= siovs
;
768 ssize_t sent
= sendmsg(sockfds
[0], &smsg
, 0);
773 struct iovec peek_iov
;
774 peek_iov
.iov_base
= rpbuf
;
775 peek_iov
.iov_len
= 2;
777 struct msghdr peek_header
= {};
778 peek_header
.msg_iov
= &peek_iov
;
779 peek_header
.msg_iovlen
= 1;
781 dfsan_set_label(i_label
, rpbuf
, sizeof(rpbuf
));
782 dfsan_set_label(i_label
, &peek_header
, sizeof(peek_header
));
784 DEFINE_AND_SAVE_ORIGINS(peek_header
)
786 ssize_t received
= recvmsg(sockfds
[1], &peek_header
, MSG_PEEK
| MSG_TRUNC
);
787 assert(received
== sent
);
788 assert(memcmp(sbuf
, rpbuf
, 2) == 0);
789 ASSERT_ZERO_LABEL(received
);
790 ASSERT_READ_ZERO_LABEL(&peek_header
, sizeof(peek_header
));
791 ASSERT_READ_ZERO_LABEL(&rpbuf
[0], 0);
793 ASSERT_SAVED_ORIGINS(peek_header
)
798 struct iovec riovs
[2] = {{&rbuf
[0], 4}, {&rbuf
[4], 4}};
799 struct msghdr rmsg
= {};
800 rmsg
.msg_iov
= riovs
;
803 dfsan_set_label(i_label
, rbuf
, sizeof(rbuf
));
804 dfsan_set_label(i_label
, &rmsg
, sizeof(rmsg
));
806 DEFINE_AND_SAVE_ORIGINS(rmsg
)
808 ssize_t received
= recvmsg(sockfds
[1], &rmsg
, 0);
809 assert(received
== sent
);
810 assert(memcmp(sbuf
, rbuf
, 8) == 0);
811 ASSERT_ZERO_LABEL(received
);
812 ASSERT_READ_ZERO_LABEL(&rmsg
, sizeof(rmsg
));
813 ASSERT_READ_ZERO_LABEL(&rbuf
[0], 8);
814 ASSERT_READ_LABEL(&rbuf
[8], 1, i_label
);
816 ASSERT_SAVED_ORIGINS(rmsg
)
825 dfsan_set_label(i_label
, buf
, 1);
826 dfsan_set_label(j_label
, buf
+ 15, 1);
828 DEFINE_AND_SAVE_ORIGINS(buf
)
829 ASSERT_LABEL(buf
[0], i_label
);
830 ASSERT_LABEL(buf
[15], j_label
);
832 int fd
= open("/dev/zero", O_RDONLY
);
833 int rv
= read(fd
, buf
, sizeof(buf
));
834 assert(rv
== sizeof(buf
));
835 ASSERT_ZERO_LABEL(rv
);
836 ASSERT_ZERO_LABEL(buf
[0]);
837 ASSERT_ZERO_LABEL(buf
[15]);
838 ASSERT_SAVED_ORIGINS(buf
)
844 dfsan_set_label(i_label
, buf
, 1);
845 dfsan_set_label(j_label
, buf
+ 15, 1);
847 DEFINE_AND_SAVE_ORIGINS(buf
)
848 ASSERT_LABEL(buf
[0], i_label
);
849 ASSERT_LABEL(buf
[15], j_label
);
851 int fd
= open("/bin/sh", O_RDONLY
);
852 int rv
= pread(fd
, buf
, sizeof(buf
), 0);
853 assert(rv
== sizeof(buf
));
854 ASSERT_ZERO_LABEL(rv
);
855 ASSERT_ZERO_LABEL(buf
[0]);
856 ASSERT_ZERO_LABEL(buf
[15]);
857 ASSERT_SAVED_ORIGINS(buf
)
862 void *map
= dlopen(NULL
, RTLD_NOW
);
864 ASSERT_ZERO_LABEL(map
);
866 map
= dlopen("/nonexistent", RTLD_NOW
);
868 ASSERT_ZERO_LABEL(map
);
871 void test_clock_gettime() {
873 dfsan_set_label(j_label
, ((char *)&tp
) + 3, 1);
874 dfsan_origin origin
= dfsan_get_origin((long)(((char *)&tp
)[3]));
875 #ifndef ORIGIN_TRACKING
878 int t
= clock_gettime(CLOCK_REALTIME
, &tp
);
880 ASSERT_ZERO_LABEL(t
);
881 ASSERT_ZERO_LABEL(((char *)&tp
)[3]);
882 ASSERT_ORIGIN(((char *)&tp
)[3], origin
);
885 void test_ctime_r() {
886 char *buf
= (char*) malloc(64);
889 DEFINE_AND_SAVE_ORIGINS(buf
)
890 dfsan_origin t_o
= dfsan_get_origin((long)t
);
892 char *ret
= ctime_r(&t
, buf
);
893 ASSERT_ZERO_LABEL(ret
);
895 ASSERT_READ_ZERO_LABEL(buf
, strlen(buf
) + 1);
896 ASSERT_SAVED_ORIGINS(buf
)
898 dfsan_set_label(i_label
, &t
, sizeof(t
));
899 t_o
= dfsan_get_origin((long)t
);
900 ret
= ctime_r(&t
, buf
);
901 ASSERT_ZERO_LABEL(ret
);
902 ASSERT_READ_LABEL(buf
, strlen(buf
) + 1, i_label
);
903 for (int i
= 0; i
< strlen(buf
) + 1; ++i
)
904 ASSERT_ORIGIN(buf
[i
], t_o
);
907 dfsan_set_label(j_label
, &buf
, sizeof(&buf
));
908 dfsan_origin buf_ptr_o
= dfsan_get_origin((long)buf
);
909 #ifndef ORIGIN_TRACKING
912 ret
= ctime_r(&t
, buf
);
913 ASSERT_LABEL(ret
, j_label
);
914 ASSERT_ORIGIN(ret
, buf_ptr_o
);
915 ASSERT_READ_ZERO_LABEL(buf
, strlen(buf
) + 1);
916 for (int i
= 0; i
< strlen(buf
) + 1; ++i
)
917 ASSERT_ORIGIN(buf
[i
], t_o
);
920 static int write_callback_count
= 0;
922 static const unsigned char *last_buf
;
923 static size_t last_count
;
925 void write_callback(int fd
, const void *buf
, size_t count
) {
926 write_callback_count
++;
929 last_buf
= (const unsigned char*) buf
;
933 void test_dfsan_set_write_callback() {
934 char a_buf
[] = "Sample chars";
935 int a_buf_len
= strlen(a_buf
);
937 int fd
= open("/dev/null", O_WRONLY
);
939 dfsan_set_write_callback(write_callback
);
941 write_callback_count
= 0;
943 DEFINE_AND_SAVE_ORIGINS(a_buf
)
945 // Callback should be invoked on every call to write().
946 int res
= write(fd
, a_buf
, a_buf_len
);
947 assert(write_callback_count
== 1);
948 ASSERT_READ_ZERO_LABEL(&res
, sizeof(res
));
949 ASSERT_READ_ZERO_LABEL(&last_fd
, sizeof(last_fd
));
950 ASSERT_READ_ZERO_LABEL(last_buf
, sizeof(last_buf
));
952 for (int i
= 0; i
< a_buf_len
; ++i
)
953 ASSERT_ORIGIN(last_buf
[i
], a_buf_o
[i
]);
955 ASSERT_ZERO_ORIGINS(&last_count
, sizeof(last_count
));
960 char b_buf
[] = "Other chars";
961 int b_buf_len
= strlen(b_buf
);
962 // Create a separate variable so we can taint the pointer.
963 // We would always get a shadow of 0 for b_buf because it is a constant.
964 const unsigned char *buf
= (const unsigned char *)b_buf
;
966 // Add a label to write() arguments. Check that the labels are readable from
967 // the values passed to the callback.
968 dfsan_set_label(i_label
, &fd
, sizeof(fd
));
969 dfsan_set_label(j_label
, &buf
, sizeof(buf
)); // ptr
970 dfsan_set_label(k_label
, &(b_buf
[3]), 1); // content
971 dfsan_set_label(m_label
, &b_buf_len
, sizeof(b_buf_len
));
973 dfsan_origin fd_o
= dfsan_get_origin((long)fd
);
974 dfsan_origin b_buf3_o
= dfsan_get_origin((long)(b_buf
[3]));
975 dfsan_origin b_buf_len_o
= dfsan_get_origin((long)b_buf_len
);
976 #ifndef ORIGIN_TRACKING
981 DEFINE_AND_SAVE_ORIGINS(b_buf
)
983 res
= write(fd
, buf
, b_buf_len
);
984 assert(write_callback_count
== 2);
985 assert(last_fd
== fd
);
986 assert(last_buf
== (const unsigned char *)b_buf
);
987 assert(last_count
== b_buf_len
);
989 ASSERT_READ_ZERO_LABEL(&res
, sizeof(res
));
990 ASSERT_READ_LABEL(&last_fd
, sizeof(last_fd
), i_label
);
991 ASSERT_READ_LABEL(&last_buf
, sizeof(&last_buf
), j_label
); // ptr
992 ASSERT_READ_LABEL(last_buf
, last_count
, k_label
); // content
993 ASSERT_READ_LABEL(&last_buf
[3], sizeof(last_buf
[3]), k_label
); // content
994 ASSERT_READ_LABEL(&last_count
, sizeof(last_count
), m_label
);
995 ASSERT_ZERO_ORIGINS(&res
, sizeof(res
));
996 ASSERT_INIT_ORIGINS(&last_fd
, sizeof(last_fd
), fd_o
);
997 ASSERT_INIT_ORIGINS(&last_buf
[3], sizeof(last_buf
[3]), b_buf3_o
);
999 // Origins are assigned for every 4 contiguous 4-aligned bytes. After
1000 // appending src to dst, origins of src can overwrite origins of dst if their
1001 // application adddresses are within an aligned range. Other origins are not
1003 for (int i
= 0; i
< b_buf_len
; ++i
) {
1004 size_t i_addr
= size_t(&last_buf
[i
]);
1005 if (((size_t(&last_buf
[3]) & ~3UL) > i_addr
) ||
1006 (((size_t(&last_buf
[3]) + 4) & ~3UL) <= i_addr
))
1007 ASSERT_ORIGIN(last_buf
[i
], b_buf_o
[i
]);
1010 ASSERT_INIT_ORIGINS(&last_count
, sizeof(last_count
), b_buf_len_o
);
1012 dfsan_set_write_callback(NULL
);
1016 char *buf
= (char*) malloc(128);
1017 FILE *f
= fopen("/etc/passwd", "r");
1018 dfsan_set_label(j_label
, buf
, 1);
1019 DEFINE_AND_SAVE_N_ORIGINS(buf
, 128)
1021 char *ret
= fgets(buf
, sizeof(buf
), f
);
1023 ASSERT_ZERO_LABEL(ret
);
1024 ASSERT_EQ_ORIGIN(ret
, buf
);
1025 ASSERT_READ_ZERO_LABEL(buf
, 128);
1026 ASSERT_SAVED_N_ORIGINS(buf
, 128)
1028 dfsan_set_label(j_label
, &buf
, sizeof(&buf
));
1029 ret
= fgets(buf
, sizeof(buf
), f
);
1030 ASSERT_LABEL(ret
, j_label
);
1031 ASSERT_EQ_ORIGIN(ret
, buf
);
1032 ASSERT_SAVED_N_ORIGINS(buf
, 128)
1038 void test_getcwd() {
1041 dfsan_set_label(i_label
, buf
+ 2, 2);
1042 DEFINE_AND_SAVE_ORIGINS(buf
)
1044 char* ret
= getcwd(buf
, sizeof(buf
));
1046 assert(ret
[0] == '/');
1047 ASSERT_ZERO_LABEL(ret
);
1048 ASSERT_EQ_ORIGIN(ret
, buf
);
1049 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
1050 ASSERT_SAVED_ORIGINS(buf
)
1052 dfsan_set_label(i_label
, &ptr
, sizeof(ptr
));
1053 ret
= getcwd(ptr
, sizeof(buf
));
1054 ASSERT_LABEL(ret
, i_label
);
1055 ASSERT_EQ_ORIGIN(ret
, ptr
);
1056 ASSERT_SAVED_ORIGINS(buf
)
1059 void test_get_current_dir_name() {
1060 char* ret
= get_current_dir_name();
1062 assert(ret
[0] == '/');
1063 ASSERT_READ_ZERO_LABEL(ret
, strlen(ret
) + 1);
1064 ASSERT_ZERO_LABEL(ret
);
1067 void test_getentropy() {
1069 dfsan_set_label(i_label
, buf
+ 2, 2);
1070 DEFINE_AND_SAVE_ORIGINS(buf
)
1071 #if __GLIBC_PREREQ(2, 25)
1072 // glibc >= 2.25 has getentropy()
1073 int ret
= getentropy(buf
, sizeof(buf
));
1074 ASSERT_ZERO_LABEL(ret
);
1076 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
1077 ASSERT_SAVED_ORIGINS(buf
)
1082 void test_gethostname() {
1084 dfsan_set_label(i_label
, buf
+ 2, 2);
1085 DEFINE_AND_SAVE_ORIGINS(buf
)
1086 int ret
= gethostname(buf
, sizeof(buf
));
1088 ASSERT_ZERO_LABEL(ret
);
1089 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
1090 ASSERT_SAVED_ORIGINS(buf
)
1093 void test_getrlimit() {
1095 dfsan_set_label(i_label
, &rlim
, sizeof(rlim
));
1096 DEFINE_AND_SAVE_ORIGINS(rlim
);
1097 int ret
= getrlimit(RLIMIT_CPU
, &rlim
);
1099 ASSERT_ZERO_LABEL(ret
);
1100 ASSERT_READ_ZERO_LABEL(&rlim
, sizeof(rlim
));
1101 ASSERT_SAVED_ORIGINS(rlim
)
1104 void test_getrusage() {
1105 struct rusage usage
;
1106 dfsan_set_label(i_label
, &usage
, sizeof(usage
));
1107 DEFINE_AND_SAVE_ORIGINS(usage
);
1108 int ret
= getrusage(RUSAGE_SELF
, &usage
);
1110 ASSERT_ZERO_LABEL(ret
);
1111 ASSERT_READ_ZERO_LABEL(&usage
, sizeof(usage
));
1112 ASSERT_SAVED_ORIGINS(usage
)
1115 void test_strcpy() {
1116 char src
[] = "hello world";
1117 char dst
[sizeof(src
) + 2];
1119 dfsan_set_label(0, src
, sizeof(src
));
1120 dfsan_set_label(0, dst
, sizeof(dst
));
1121 dfsan_set_label(k_label
, &p_dst
, sizeof(p_dst
));
1122 dfsan_set_label(i_label
, src
+ 2, 1);
1123 dfsan_set_label(j_label
, src
+ 3, 1);
1124 dfsan_set_label(j_label
, dst
+ 4, 1);
1125 dfsan_set_label(i_label
, dst
+ 12, 1);
1126 char *ret
= strcpy(p_dst
, src
);
1128 assert(strcmp(src
, dst
) == 0);
1129 ASSERT_LABEL(ret
, k_label
);
1130 ASSERT_EQ_ORIGIN(ret
, p_dst
);
1131 for (int i
= 0; i
< strlen(src
) + 1; ++i
) {
1132 assert(dfsan_get_label(dst
[i
]) == dfsan_get_label(src
[i
]));
1133 if (dfsan_get_label(dst
[i
]))
1134 assert(dfsan_get_init_origin(&dst
[i
]) == dfsan_get_origin(src
[i
]));
1136 // Note: if strlen(src) + 1 were used instead to compute the first untouched
1137 // byte of dest, the label would be I|J. This is because strlen() might
1138 // return a non-zero label, and because by default pointer labels are not
1139 // ignored on loads.
1140 ASSERT_LABEL(dst
[12], i_label
);
1143 void test_strtol() {
1144 char non_number_buf
[] = "ab ";
1145 char *endptr
= NULL
;
1146 long int ret
= strtol(non_number_buf
, &endptr
, 10);
1148 assert(endptr
== non_number_buf
);
1149 ASSERT_ZERO_LABEL(ret
);
1151 char buf
[] = "1234578910";
1153 dfsan_set_label(k_label
, &base
, sizeof(base
));
1154 ret
= strtol(buf
, &endptr
, base
);
1155 assert(ret
== 1234578910);
1156 assert(endptr
== buf
+ 10);
1157 ASSERT_LABEL(ret
, k_label
);
1158 ASSERT_EQ_ORIGIN(ret
, base
);
1160 dfsan_set_label(i_label
, buf
+ 1, 1);
1161 dfsan_set_label(j_label
, buf
+ 10, 1);
1162 ret
= strtol(buf
, &endptr
, 10);
1163 assert(ret
== 1234578910);
1164 assert(endptr
== buf
+ 10);
1165 ASSERT_LABEL(ret
, i_j_label
);
1166 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1169 void test_strtoll() {
1170 char non_number_buf
[] = "ab ";
1171 char *endptr
= NULL
;
1172 long long int ret
= strtoll(non_number_buf
, &endptr
, 10);
1174 assert(endptr
== non_number_buf
);
1175 ASSERT_ZERO_LABEL(ret
);
1177 char buf
[] = "1234578910 ";
1179 dfsan_set_label(k_label
, &base
, sizeof(base
));
1180 ret
= strtoll(buf
, &endptr
, base
);
1181 assert(ret
== 1234578910);
1182 assert(endptr
== buf
+ 10);
1183 ASSERT_LABEL(ret
, k_label
);
1184 ASSERT_EQ_ORIGIN(ret
, base
);
1186 dfsan_set_label(i_label
, buf
+ 1, 1);
1187 dfsan_set_label(j_label
, buf
+ 2, 1);
1188 ret
= strtoll(buf
, &endptr
, 10);
1189 assert(ret
== 1234578910);
1190 assert(endptr
== buf
+ 10);
1191 ASSERT_LABEL(ret
, i_j_label
);
1192 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1195 void test_strtoul() {
1196 char non_number_buf
[] = "xy ";
1197 char *endptr
= NULL
;
1198 long unsigned int ret
= strtoul(non_number_buf
, &endptr
, 16);
1200 assert(endptr
== non_number_buf
);
1201 ASSERT_ZERO_LABEL(ret
);
1203 char buf
[] = "ffffffffffffaa";
1205 dfsan_set_label(k_label
, &base
, sizeof(base
));
1206 ret
= strtoul(buf
, &endptr
, base
);
1207 assert(ret
== 72057594037927850);
1208 assert(endptr
== buf
+ 14);
1209 ASSERT_LABEL(ret
, k_label
);
1210 ASSERT_EQ_ORIGIN(ret
, base
);
1212 dfsan_set_label(i_label
, buf
+ 1, 1);
1213 dfsan_set_label(j_label
, buf
+ 2, 1);
1214 ret
= strtoul(buf
, &endptr
, 16);
1215 assert(ret
== 72057594037927850);
1216 assert(endptr
== buf
+ 14);
1217 ASSERT_LABEL(ret
, i_j_label
);
1218 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1221 void test_strtoull() {
1222 char non_number_buf
[] = "xy ";
1223 char *endptr
= NULL
;
1224 long long unsigned int ret
= strtoull(non_number_buf
, &endptr
, 16);
1226 assert(endptr
== non_number_buf
);
1227 ASSERT_ZERO_LABEL(ret
);
1229 char buf
[] = "ffffffffffffffaa";
1231 dfsan_set_label(k_label
, &base
, sizeof(base
));
1232 ret
= strtoull(buf
, &endptr
, base
);
1233 assert(ret
== 0xffffffffffffffaa);
1234 assert(endptr
== buf
+ 16);
1235 ASSERT_LABEL(ret
, k_label
);
1236 ASSERT_EQ_ORIGIN(ret
, base
);
1238 dfsan_set_label(i_label
, buf
+ 1, 1);
1239 dfsan_set_label(j_label
, buf
+ 2, 1);
1240 ret
= strtoull(buf
, &endptr
, 16);
1241 assert(ret
== 0xffffffffffffffaa);
1242 assert(endptr
== buf
+ 16);
1243 ASSERT_LABEL(ret
, i_j_label
);
1244 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1247 void test_strtod() {
1248 char non_number_buf
[] = "ab ";
1249 char *endptr
= NULL
;
1250 double ret
= strtod(non_number_buf
, &endptr
);
1252 assert(endptr
== non_number_buf
);
1253 ASSERT_ZERO_LABEL(ret
);
1255 char buf
[] = "12345.76 foo";
1256 dfsan_set_label(i_label
, buf
+ 1, 1);
1257 dfsan_set_label(j_label
, buf
+ 6, 1);
1258 ret
= strtod(buf
, &endptr
);
1259 assert(ret
== 12345.76);
1260 assert(endptr
== buf
+ 8);
1261 ASSERT_LABEL(ret
, i_j_label
);
1262 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1267 dfsan_set_label(i_label
, &t
, 1);
1268 DEFINE_AND_SAVE_ORIGINS(t
)
1269 time_t ret
= time(&t
);
1272 ASSERT_ZERO_LABEL(ret
);
1273 ASSERT_ZERO_LABEL(t
);
1274 ASSERT_SAVED_ORIGINS(t
)
1277 void test_inet_pton() {
1278 char addr4
[] = "127.0.0.1";
1279 dfsan_set_label(i_label
, addr4
+ 3, 1);
1281 int ret4
= inet_pton(AF_INET
, addr4
, &in4
);
1283 ASSERT_ZERO_LABEL(ret4
);
1284 ASSERT_READ_LABEL(&in4
, sizeof(in4
), i_label
);
1285 ASSERT_ORIGINS(&in4
, sizeof(in4
), dfsan_get_origin((long)(addr4
[3])))
1286 assert(in4
.s_addr
== htonl(0x7f000001));
1288 char addr6
[] = "::1";
1289 dfsan_set_label(j_label
, addr6
+ 3, 1);
1290 struct in6_addr in6
;
1291 int ret6
= inet_pton(AF_INET6
, addr6
, &in6
);
1293 ASSERT_ZERO_LABEL(ret6
);
1294 ASSERT_READ_LABEL(((char *) &in6
) + sizeof(in6
) - 1, 1, j_label
);
1295 ASSERT_ORIGINS(&in6
, sizeof(in6
), dfsan_get_origin((long)(addr6
[3])))
1298 void test_localtime_r() {
1299 time_t t0
= 1384800998;
1301 dfsan_set_label(i_label
, &t0
, sizeof(t0
));
1302 dfsan_origin t0_o
= dfsan_get_origin((long)t0
);
1303 struct tm
*pt1
= &t1
;
1304 dfsan_set_label(j_label
, &pt1
, sizeof(pt1
));
1305 dfsan_origin pt1_o
= dfsan_get_origin((long)pt1
);
1307 #ifndef ORIGIN_TRACKING
1312 struct tm
*ret
= localtime_r(&t0
, pt1
);
1314 assert(t1
.tm_min
== 56);
1315 ASSERT_LABEL(ret
, j_label
);
1316 ASSERT_INIT_ORIGIN(&ret
, pt1_o
);
1317 ASSERT_READ_LABEL(&ret
, sizeof(ret
), j_label
);
1318 ASSERT_LABEL(t1
.tm_mon
, i_label
);
1319 ASSERT_ORIGIN(t1
.tm_mon
, t0_o
);
1322 void test_getpwuid_r() {
1325 struct passwd
*result
;
1327 dfsan_set_label(i_label
, &pwd
, 4);
1328 DEFINE_AND_SAVE_ORIGINS(pwd
)
1329 DEFINE_AND_SAVE_ORIGINS(buf
)
1330 int ret
= getpwuid_r(0, &pwd
, buf
, sizeof(buf
), &result
);
1332 assert(strcmp(pwd
.pw_name
, "root") == 0);
1333 assert(result
== &pwd
);
1334 ASSERT_ZERO_LABEL(ret
);
1335 ASSERT_READ_ZERO_LABEL(&pwd
, 4);
1336 ASSERT_SAVED_ORIGINS(pwd
)
1337 ASSERT_SAVED_ORIGINS(buf
)
1340 void test_epoll_wait() {
1341 // Set up a pipe to monitor with epoll.
1343 int ret
= pipe(pipe_fds
);
1346 // Configure epoll to monitor the pipe.
1347 int epfd
= epoll_create1(0);
1349 struct epoll_event event
;
1350 event
.events
= EPOLLIN
;
1351 event
.data
.fd
= pipe_fds
[0];
1352 ret
= epoll_ctl(epfd
, EPOLL_CTL_ADD
, pipe_fds
[0], &event
);
1355 // Test epoll_wait when no events have occurred.
1357 dfsan_set_label(i_label
, &event
, sizeof(event
));
1358 DEFINE_AND_SAVE_ORIGINS(event
)
1359 ret
= epoll_wait(epfd
, &event
, /*maxevents=*/1, /*timeout=*/0);
1361 assert(event
.events
== 0);
1362 assert(event
.data
.fd
== 0);
1363 ASSERT_ZERO_LABEL(ret
);
1364 ASSERT_READ_LABEL(&event
, sizeof(event
), i_label
);
1365 ASSERT_SAVED_ORIGINS(event
)
1367 // Test epoll_wait when an event occurs.
1368 write(pipe_fds
[1], "x", 1);
1369 ret
= epoll_wait(epfd
, &event
, /*maxevents=*/1, /*timeout=*/0);
1371 assert(event
.events
== EPOLLIN
);
1372 assert(event
.data
.fd
== pipe_fds
[0]);
1373 ASSERT_ZERO_LABEL(ret
);
1374 ASSERT_READ_ZERO_LABEL(&event
, sizeof(event
));
1375 ASSERT_SAVED_ORIGINS(event
)
1387 dfsan_set_label(i_label
, &fd
.revents
, sizeof(fd
.revents
));
1388 DEFINE_AND_SAVE_ORIGINS(fd
)
1389 int ret
= poll(&fd
, 1, 1);
1390 ASSERT_ZERO_LABEL(ret
);
1391 ASSERT_ZERO_LABEL(fd
.revents
);
1392 ASSERT_SAVED_ORIGINS(fd
)
1396 void test_select() {
1401 dfsan_set_label(i_label
, &fds
, sizeof(fds
));
1402 dfsan_set_label(j_label
, &t
, sizeof(t
));
1403 DEFINE_AND_SAVE_ORIGINS(fds
)
1404 DEFINE_AND_SAVE_ORIGINS(t
)
1405 int ret
= select(1, &fds
, NULL
, NULL
, &t
);
1407 ASSERT_ZERO_LABEL(ret
);
1408 ASSERT_ZERO_LABEL(t
.tv_sec
);
1409 ASSERT_READ_ZERO_LABEL(&fds
, sizeof(fds
));
1410 ASSERT_SAVED_ORIGINS(fds
)
1411 ASSERT_SAVED_ORIGINS(t
)
1414 void test_sched_getaffinity() {
1416 dfsan_set_label(j_label
, &mask
, 1);
1417 DEFINE_AND_SAVE_ORIGINS(mask
)
1418 int ret
= sched_getaffinity(0, sizeof(mask
), &mask
);
1420 ASSERT_ZERO_LABEL(ret
);
1421 ASSERT_READ_ZERO_LABEL(&mask
, sizeof(mask
));
1422 ASSERT_SAVED_ORIGINS(mask
)
1425 void test_sigemptyset() {
1427 dfsan_set_label(j_label
, &set
, 1);
1428 DEFINE_AND_SAVE_ORIGINS(set
)
1429 int ret
= sigemptyset(&set
);
1431 ASSERT_ZERO_LABEL(ret
);
1432 ASSERT_READ_ZERO_LABEL(&set
, sizeof(set
));
1433 ASSERT_SAVED_ORIGINS(set
)
1436 static void SignalHandler(int signo
) {}
1438 static void SignalAction(int signo
, siginfo_t
*si
, void *uc
) {}
1440 void test_sigaction() {
1441 struct sigaction newact_with_sigaction
= {};
1442 newact_with_sigaction
.sa_flags
= SA_SIGINFO
;
1443 newact_with_sigaction
.sa_sigaction
= SignalAction
;
1445 // Set sigaction to be SignalAction, save the last one into origin_act
1446 struct sigaction origin_act
;
1447 dfsan_set_label(j_label
, &origin_act
, 1);
1448 DEFINE_AND_SAVE_ORIGINS(origin_act
)
1449 int ret
= sigaction(SIGUSR1
, &newact_with_sigaction
, &origin_act
);
1451 ASSERT_ZERO_LABEL(ret
);
1452 ASSERT_READ_ZERO_LABEL(&origin_act
, sizeof(origin_act
));
1453 ASSERT_SAVED_ORIGINS(origin_act
)
1455 struct sigaction newact_with_sighandler
= {};
1456 newact_with_sighandler
.sa_handler
= SignalHandler
;
1458 // Set sigaction to be SignalHandler, check the last one is SignalAction
1459 struct sigaction oldact
;
1460 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1461 assert(oldact
.sa_sigaction
== SignalAction
);
1462 assert(oldact
.sa_flags
& SA_SIGINFO
);
1464 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1465 newact_with_sighandler
.sa_handler
= SIG_IGN
;
1466 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1467 assert(oldact
.sa_handler
== SignalHandler
);
1468 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1470 newact_with_sighandler
.sa_handler
= SIG_DFL
;
1471 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1472 assert(oldact
.sa_handler
== SIG_IGN
);
1473 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1475 // Restore sigaction to the orginal setting, check the last one is SignalHandler
1476 assert(0 == sigaction(SIGUSR1
, &origin_act
, &oldact
));
1477 assert(oldact
.sa_handler
== SIG_DFL
);
1478 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1481 void test_signal() {
1482 // Set signal to be SignalHandler, save the previous one into
1483 // old_signal_handler.
1484 sighandler_t old_signal_handler
= signal(SIGHUP
, SignalHandler
);
1485 ASSERT_ZERO_LABEL(old_signal_handler
);
1487 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1488 assert(SignalHandler
== signal(SIGHUP
, SIG_DFL
));
1489 assert(SIG_DFL
== signal(SIGHUP
, SIG_IGN
));
1491 // Restore signal to old_signal_handler.
1492 assert(SIG_IGN
== signal(SIGHUP
, old_signal_handler
));
1495 void test_sigaltstack() {
1496 stack_t old_altstack
= {};
1497 dfsan_set_label(j_label
, &old_altstack
, sizeof(old_altstack
));
1498 DEFINE_AND_SAVE_ORIGINS(old_altstack
)
1499 int ret
= sigaltstack(NULL
, &old_altstack
);
1501 ASSERT_ZERO_LABEL(ret
);
1502 ASSERT_READ_ZERO_LABEL(&old_altstack
, sizeof(old_altstack
));
1503 ASSERT_SAVED_ORIGINS(old_altstack
)
1506 void test_gettimeofday() {
1509 dfsan_set_label(i_label
, &tv
, sizeof(tv
));
1510 dfsan_set_label(j_label
, &tz
, sizeof(tz
));
1511 DEFINE_AND_SAVE_ORIGINS(tv
)
1512 DEFINE_AND_SAVE_ORIGINS(tz
)
1513 int ret
= gettimeofday(&tv
, &tz
);
1515 ASSERT_READ_ZERO_LABEL(&tv
, sizeof(tv
));
1516 ASSERT_READ_ZERO_LABEL(&tz
, sizeof(tz
));
1517 ASSERT_SAVED_ORIGINS(tv
)
1518 ASSERT_SAVED_ORIGINS(tz
)
1521 void *pthread_create_test_cb(void *p
) {
1522 assert(p
== (void *)1);
1523 ASSERT_ZERO_LABEL(p
);
1527 void test_pthread_create() {
1529 int create_ret
= pthread_create(&pt
, 0, pthread_create_test_cb
, (void *)1);
1530 assert(create_ret
== 0);
1531 ASSERT_ZERO_LABEL(create_ret
);
1533 dfsan_set_label(i_label
, &cbrv
, sizeof(cbrv
));
1534 DEFINE_AND_SAVE_ORIGINS(cbrv
)
1535 int joint_ret
= pthread_join(pt
, &cbrv
);
1536 assert(joint_ret
== 0);
1537 assert(cbrv
== (void *)2);
1538 ASSERT_ZERO_LABEL(joint_ret
);
1539 ASSERT_ZERO_LABEL(cbrv
);
1540 ASSERT_SAVED_ORIGINS(cbrv
);
1543 // Tested by test_pthread_create(). This empty function is here to appease the
1544 // check-wrappers script.
1545 void test_pthread_join() {}
1547 int dl_iterate_phdr_test_cb(struct dl_phdr_info
*info
, size_t size
,
1549 assert(data
== (void *)3);
1550 ASSERT_ZERO_LABEL(info
);
1551 ASSERT_ZERO_LABEL(size
);
1552 ASSERT_ZERO_LABEL(data
);
1556 void test_dl_iterate_phdr() {
1557 dl_iterate_phdr(dl_iterate_phdr_test_cb
, (void *)3);
1560 // On glibc < 2.27, this symbol is not available. Mark it weak so we can skip
1561 // testing in this case.
1562 __attribute__((weak
)) extern "C" void _dl_get_tls_static_info(size_t *sizep
,
1565 void test__dl_get_tls_static_info() {
1566 if (!_dl_get_tls_static_info
)
1568 size_t sizep
= 0, alignp
= 0;
1569 dfsan_set_label(i_label
, &sizep
, sizeof(sizep
));
1570 dfsan_set_label(i_label
, &alignp
, sizeof(alignp
));
1571 dfsan_origin sizep_o
= dfsan_get_origin(sizep
);
1572 dfsan_origin alignp_o
= dfsan_get_origin(alignp
);
1573 #ifndef ORIGIN_TRACKING
1577 _dl_get_tls_static_info(&sizep
, &alignp
);
1578 ASSERT_ZERO_LABEL(sizep
);
1579 ASSERT_ZERO_LABEL(alignp
);
1580 ASSERT_ORIGIN(sizep
, sizep_o
);
1581 ASSERT_ORIGIN(alignp
, alignp_o
);
1584 void test_strrchr() {
1585 char str1
[] = "str1str1";
1588 dfsan_set_label(j_label
, &p
, sizeof(p
));
1590 char *rv
= strrchr(p
, 'r');
1591 assert(rv
== &str1
[6]);
1592 ASSERT_LABEL(rv
, j_label
);
1593 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p
);
1596 dfsan_set_label(k_label
, &c
, sizeof(c
));
1597 rv
= strrchr(str1
, c
);
1598 assert(rv
== &str1
[6]);
1599 #ifdef STRICT_DATA_DEPENDENCIES
1600 ASSERT_ZERO_LABEL(rv
);
1602 ASSERT_LABEL(rv
, k_label
);
1603 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, c
);
1606 dfsan_set_label(i_label
, &str1
[7], 1);
1608 rv
= strrchr(str1
, 'r');
1609 assert(rv
== &str1
[6]);
1610 #ifdef STRICT_DATA_DEPENDENCIES
1611 ASSERT_ZERO_LABEL(rv
);
1613 ASSERT_LABEL(rv
, i_label
);
1614 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[7]);
1618 void test_strstr() {
1619 char str1
[] = "str1str1";
1622 dfsan_set_label(k_label
, &p1
, sizeof(p1
));
1623 char *rv
= strstr(p1
, "1s");
1624 assert(rv
== &str1
[3]);
1625 ASSERT_LABEL(rv
, k_label
);
1626 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p1
);
1630 dfsan_set_label(m_label
, &p2
, sizeof(p2
));
1631 rv
= strstr(str1
, p2
);
1632 assert(rv
== &str1
[3]);
1633 #ifdef STRICT_DATA_DEPENDENCIES
1634 ASSERT_ZERO_LABEL(rv
);
1636 ASSERT_LABEL(rv
, m_label
);
1637 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p2
);
1640 dfsan_set_label(n_label
, &str2
[0], 1);
1641 rv
= strstr(str1
, str2
);
1642 assert(rv
== &str1
[3]);
1643 #ifdef STRICT_DATA_DEPENDENCIES
1644 ASSERT_ZERO_LABEL(rv
);
1646 ASSERT_LABEL(rv
, n_label
);
1647 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str2
[0]);
1650 dfsan_set_label(i_label
, &str1
[3], 1);
1651 dfsan_set_label(j_label
, &str1
[5], 1);
1653 rv
= strstr(str1
, "1s");
1654 assert(rv
== &str1
[3]);
1655 #ifdef STRICT_DATA_DEPENDENCIES
1656 ASSERT_ZERO_LABEL(rv
);
1658 ASSERT_LABEL(rv
, i_label
);
1659 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[3]);
1662 rv
= strstr(str1
, "2s");
1664 #ifdef STRICT_DATA_DEPENDENCIES
1665 ASSERT_ZERO_LABEL(rv
);
1667 ASSERT_LABEL(rv
, i_j_label
);
1668 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[3]);
1672 void test_strpbrk() {
1673 char s
[] = "abcdefg";
1674 char accept
[] = "123fd";
1677 char *p_accept
= accept
;
1679 dfsan_set_label(n_label
, &p_accept
, sizeof(p_accept
));
1681 char *rv
= strpbrk(p_s
, p_accept
);
1682 assert(rv
== &s
[3]);
1683 #ifdef STRICT_DATA_DEPENDENCIES
1684 ASSERT_ZERO_LABEL(rv
);
1686 ASSERT_LABEL(rv
, n_label
);
1687 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_accept
);
1690 dfsan_set_label(m_label
, &p_s
, sizeof(p_s
));
1692 rv
= strpbrk(p_s
, p_accept
);
1693 assert(rv
== &s
[3]);
1694 #ifdef STRICT_DATA_DEPENDENCIES
1695 ASSERT_LABEL(rv
, m_label
);
1696 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_s
);
1698 ASSERT_LABEL(rv
, dfsan_union(m_label
, n_label
));
1699 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_s
);
1702 dfsan_set_label(i_label
, &s
[5], 1);
1703 dfsan_set_label(j_label
, &accept
[1], 1);
1705 rv
= strpbrk(s
, accept
);
1706 assert(rv
== &s
[3]);
1707 #ifdef STRICT_DATA_DEPENDENCIES
1708 ASSERT_ZERO_LABEL(rv
);
1710 ASSERT_LABEL(rv
, j_label
);
1711 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, accept
[1]);
1715 dfsan_set_label(j_label
, &ps
, sizeof(ps
));
1717 rv
= strpbrk(ps
, "123gf");
1718 assert(rv
== &s
[5]);
1719 #ifdef STRICT_DATA_DEPENDENCIES
1720 ASSERT_LABEL(rv
, j_label
);
1722 ASSERT_LABEL(rv
, i_j_label
);
1723 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, s
[5]);
1726 rv
= strpbrk(ps
, "123");
1728 #ifdef STRICT_DATA_DEPENDENCIES
1729 ASSERT_ZERO_LABEL(rv
);
1731 ASSERT_LABEL(rv
, i_j_label
);
1732 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, s
[5]);
1736 void test_strsep() {
1737 char *s
= strdup("Hello world/");
1738 char *delim
= strdup(" /");
1742 char *p_delim
= delim
;
1744 // taint delim bytes
1745 dfsan_set_label(i_label
, p_delim
, strlen(p_delim
));
1746 // taint delim pointer
1747 dfsan_set_label(j_label
, &p_delim
, sizeof(p_delim
));
1748 // taint the string data bytes
1749 dfsan_set_label(k_label
, s
, 5);
1750 // taint the string pointer
1751 dfsan_set_label(m_label
, &p_s
, sizeof(p_s
));
1753 char *rv
= strsep(&p_s
, p_delim
);
1754 assert(rv
== &base
[0]);
1755 #ifdef STRICT_DATA_DEPENDENCIES
1756 ASSERT_LABEL(rv
, m_label
);
1757 ASSERT_READ_LABEL(rv
, strlen(rv
), k_label
);
1759 ASSERT_LABEL(rv
, dfsan_union(dfsan_union(i_label
, j_label
),
1760 dfsan_union(k_label
, m_label
)));
1761 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_s
);
1764 // taint the remaining string's pointer
1766 char **pp_s_base
= pp_s
;
1767 dfsan_set_label(n_label
, pp_s
, sizeof(pp_s
));
1769 rv
= strsep(pp_s
, p_delim
);
1771 assert(rv
== &base
[6]);
1772 #ifdef STRICT_DATA_DEPENDENCIES
1773 ASSERT_LABEL(rv
, n_label
);
1774 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, *pp_s
);
1776 ASSERT_LABEL(rv
, dfsan_union(dfsan_union(i_label
, j_label
), n_label
));
1777 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, *pp_s
);
1781 void test_memchr() {
1782 char str1
[] = "str1";
1783 dfsan_set_label(i_label
, &str1
[3], 1);
1784 dfsan_set_label(j_label
, &str1
[4], 1);
1786 char *crv
= (char *) memchr(str1
, 'r', sizeof(str1
));
1787 assert(crv
== &str1
[2]);
1788 ASSERT_ZERO_LABEL(crv
);
1791 dfsan_set_label(k_label
, &c
, sizeof(c
));
1792 crv
= (char *)memchr(str1
, c
, sizeof(str1
));
1793 assert(crv
== &str1
[2]);
1794 #ifdef STRICT_DATA_DEPENDENCIES
1795 ASSERT_ZERO_LABEL(crv
);
1797 ASSERT_LABEL(crv
, k_label
);
1798 ASSERT_EQ_ORIGIN(crv
, c
);
1802 dfsan_set_label(k_label
, &ptr
, sizeof(ptr
));
1803 crv
= (char *)memchr(ptr
, 'r', sizeof(str1
));
1804 assert(crv
== &str1
[2]);
1805 ASSERT_LABEL(crv
, k_label
);
1806 ASSERT_EQ_ORIGIN(crv
, ptr
);
1808 crv
= (char *) memchr(str1
, '1', sizeof(str1
));
1809 assert(crv
== &str1
[3]);
1810 #ifdef STRICT_DATA_DEPENDENCIES
1811 ASSERT_ZERO_LABEL(crv
);
1813 ASSERT_LABEL(crv
, i_label
);
1814 ASSERT_EQ_ORIGIN(crv
, str1
[3]);
1817 crv
= (char *) memchr(str1
, 'x', sizeof(str1
));
1819 #ifdef STRICT_DATA_DEPENDENCIES
1820 ASSERT_ZERO_LABEL(crv
);
1822 ASSERT_LABEL(crv
, i_j_label
);
1823 ASSERT_EQ_ORIGIN(crv
, str1
[3]);
1827 void alarm_handler(int unused
) {
1831 void test_nanosleep() {
1832 struct timespec req
, rem
;
1835 dfsan_set_label(i_label
, &rem
, sizeof(rem
));
1836 DEFINE_AND_SAVE_ORIGINS(rem
)
1839 int rv
= nanosleep(&req
, &rem
);
1841 ASSERT_ZERO_LABEL(rv
);
1842 ASSERT_READ_LABEL(&rem
, 1, i_label
);
1843 ASSERT_SAVED_ORIGINS(rem
)
1845 // interrupted by an alarm
1846 signal(SIGALRM
, alarm_handler
);
1849 rv
= nanosleep(&req
, &rem
);
1851 ASSERT_ZERO_LABEL(rv
);
1852 ASSERT_READ_ZERO_LABEL(&rem
, sizeof(rem
));
1853 ASSERT_SAVED_ORIGINS(rem
)
1856 void test_socketpair() {
1858 dfsan_origin fd_o
[2];
1860 dfsan_set_label(i_label
, fd
, sizeof(fd
));
1861 fd_o
[0] = dfsan_get_origin((long)(fd
[0]));
1862 fd_o
[1] = dfsan_get_origin((long)(fd
[1]));
1863 int rv
= socketpair(PF_LOCAL
, SOCK_STREAM
, 0, fd
);
1865 ASSERT_ZERO_LABEL(rv
);
1866 ASSERT_READ_ZERO_LABEL(fd
, sizeof(fd
));
1867 ASSERT_ORIGIN(fd
[0], fd_o
[0]);
1868 ASSERT_ORIGIN(fd
[1], fd_o
[1]);
1871 void test_getpeername() {
1873 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
1876 struct sockaddr addr
= {};
1877 socklen_t addrlen
= sizeof(addr
);
1878 dfsan_set_label(i_label
, &addr
, addrlen
);
1879 dfsan_set_label(i_label
, &addrlen
, sizeof(addrlen
));
1880 DEFINE_AND_SAVE_ORIGINS(addr
)
1881 DEFINE_AND_SAVE_ORIGINS(addrlen
)
1883 ret
= getpeername(sockfds
[0], &addr
, &addrlen
);
1885 ASSERT_ZERO_LABEL(ret
);
1886 ASSERT_ZERO_LABEL(addrlen
);
1887 assert(addrlen
< sizeof(addr
));
1888 ASSERT_READ_ZERO_LABEL(&addr
, addrlen
);
1889 ASSERT_READ_LABEL(((char *)&addr
) + addrlen
, 1, i_label
);
1890 ASSERT_SAVED_ORIGINS(addr
)
1891 ASSERT_SAVED_ORIGINS(addrlen
)
1897 void test_getsockname() {
1898 int sockfd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
1899 assert(sockfd
!= -1);
1901 struct sockaddr addr
= {};
1902 socklen_t addrlen
= sizeof(addr
);
1903 dfsan_set_label(i_label
, &addr
, addrlen
);
1904 dfsan_set_label(i_label
, &addrlen
, sizeof(addrlen
));
1905 DEFINE_AND_SAVE_ORIGINS(addr
)
1906 DEFINE_AND_SAVE_ORIGINS(addrlen
)
1907 int ret
= getsockname(sockfd
, &addr
, &addrlen
);
1909 ASSERT_ZERO_LABEL(ret
);
1910 ASSERT_ZERO_LABEL(addrlen
);
1911 assert(addrlen
< sizeof(addr
));
1912 ASSERT_READ_ZERO_LABEL(&addr
, addrlen
);
1913 ASSERT_READ_LABEL(((char *)&addr
) + addrlen
, 1, i_label
);
1914 ASSERT_SAVED_ORIGINS(addr
)
1915 ASSERT_SAVED_ORIGINS(addrlen
)
1920 void test_getsockopt() {
1921 int sockfd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
1922 assert(sockfd
!= -1);
1924 int optval
[2] = {-1, -1};
1925 socklen_t optlen
= sizeof(optval
);
1926 dfsan_set_label(i_label
, &optval
, sizeof(optval
));
1927 dfsan_set_label(i_label
, &optlen
, sizeof(optlen
));
1928 DEFINE_AND_SAVE_ORIGINS(optval
)
1929 DEFINE_AND_SAVE_ORIGINS(optlen
)
1930 int ret
= getsockopt(sockfd
, SOL_SOCKET
, SO_KEEPALIVE
, &optval
, &optlen
);
1932 assert(optlen
== sizeof(int));
1933 assert(optval
[0] == 0);
1934 assert(optval
[1] == -1);
1935 ASSERT_ZERO_LABEL(ret
);
1936 ASSERT_ZERO_LABEL(optlen
);
1937 ASSERT_ZERO_LABEL(optval
[0]);
1938 ASSERT_LABEL(optval
[1], i_label
);
1939 ASSERT_SAVED_ORIGINS(optval
)
1940 ASSERT_SAVED_ORIGINS(optlen
)
1946 int fd
= open("/dev/null", O_WRONLY
);
1948 char buf
[] = "a string";
1949 int len
= strlen(buf
);
1951 // The result of a write always unlabeled.
1952 int res
= write(fd
, buf
, len
);
1954 ASSERT_ZERO_LABEL(res
);
1956 // Label all arguments to write().
1957 dfsan_set_label(i_label
, &(buf
[3]), 1);
1958 dfsan_set_label(j_label
, &fd
, sizeof(fd
));
1959 dfsan_set_label(k_label
, &len
, sizeof(len
));
1961 // The value returned by write() should have no label.
1962 res
= write(fd
, buf
, len
);
1963 ASSERT_ZERO_LABEL(res
);
1969 void test_sprintf_chunk(const char* expected
, const char* format
, T arg
) {
1971 memset(buf
, 'a', sizeof(buf
));
1973 char padded_expected
[512];
1974 strcpy(padded_expected
, "foo ");
1975 strcat(padded_expected
, expected
);
1976 strcat(padded_expected
, " bar");
1978 char padded_format
[512];
1979 strcpy(padded_format
, "foo ");
1980 strcat(padded_format
, format
);
1981 strcat(padded_format
, " bar");
1983 // Non labelled arg.
1984 assert(sprintf(buf
, padded_format
, arg
) == strlen(padded_expected
));
1985 assert(strcmp(buf
, padded_expected
) == 0);
1986 ASSERT_READ_LABEL(buf
, strlen(padded_expected
), 0);
1987 memset(buf
, 'a', sizeof(buf
));
1990 dfsan_set_label(i_label
, &arg
, sizeof(arg
));
1991 dfsan_origin a_o
= dfsan_get_origin((long)(arg
));
1992 #ifndef ORIGIN_TRACKING
1995 assert(sprintf(buf
, padded_format
, arg
) == strlen(padded_expected
));
1996 assert(strcmp(buf
, padded_expected
) == 0);
1997 ASSERT_READ_LABEL(buf
, 4, 0);
1998 ASSERT_READ_LABEL(buf
+ 4, strlen(padded_expected
) - 8, i_label
);
1999 ASSERT_INIT_ORIGINS(buf
+ 4, strlen(padded_expected
) - 8, a_o
);
2000 ASSERT_READ_LABEL(buf
+ (strlen(padded_expected
) - 4), 4, 0);
2003 void test_sprintf() {
2005 memset(buf
, 'a', sizeof(buf
));
2007 // Test formatting (no conversion specifier).
2008 assert(sprintf(buf
, "Hello world!") == 12);
2009 assert(strcmp(buf
, "Hello world!") == 0);
2010 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
2012 // Test for extra arguments.
2013 assert(sprintf(buf
, "Hello world!", 42, "hello") == 12);
2014 assert(strcmp(buf
, "Hello world!") == 0);
2015 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
2017 // Test formatting & label propagation (multiple conversion specifiers): %s,
2018 // %d, %n, %f, and %%.
2019 const char* s
= "world";
2022 dfsan_set_label(k_label
, (void *) (s
+ 1), 2);
2023 dfsan_origin s_o
= dfsan_get_origin((long)(s
[1]));
2024 dfsan_set_label(i_label
, &m
, sizeof(m
));
2025 dfsan_origin m_o
= dfsan_get_origin((long)m
);
2026 dfsan_set_label(j_label
, &d
, sizeof(d
));
2027 dfsan_origin d_o
= dfsan_get_origin((long)d
);
2028 #ifndef ORIGIN_TRACKING
2034 int r
= sprintf(buf
, "hello %s, %-d/%d/%d %f %% %n%d", s
, 2014, m
, d
,
2035 12345.6781234, &n
, 1000);
2037 assert(strcmp(buf
, "hello world, 2014/8/27 12345.678123 % 1000") == 0);
2038 ASSERT_READ_LABEL(buf
, 7, 0);
2039 ASSERT_READ_LABEL(buf
+ 7, 2, k_label
);
2040 ASSERT_INIT_ORIGINS(buf
+ 7, 2, s_o
);
2041 ASSERT_READ_LABEL(buf
+ 9, 9, 0);
2042 ASSERT_READ_LABEL(buf
+ 18, 1, i_label
);
2043 ASSERT_INIT_ORIGINS(buf
+ 18, 1, m_o
);
2044 ASSERT_READ_LABEL(buf
+ 19, 1, 0);
2045 ASSERT_READ_LABEL(buf
+ 20, 2, j_label
);
2046 ASSERT_INIT_ORIGINS(buf
+ 20, 2, d_o
);
2047 ASSERT_READ_LABEL(buf
+ 22, 15, 0);
2051 // Test formatting & label propagation (single conversion specifier, with
2052 // additional length and precision modifiers).
2053 test_sprintf_chunk("-559038737", "%d", 0xdeadbeef);
2054 test_sprintf_chunk("3735928559", "%u", 0xdeadbeef);
2055 test_sprintf_chunk("12345", "%i", 12345);
2056 test_sprintf_chunk("751", "%o", 0751);
2057 test_sprintf_chunk("babe", "%x", 0xbabe);
2058 test_sprintf_chunk("0000BABE", "%.8X", 0xbabe);
2059 test_sprintf_chunk("-17", "%hhd", 0xdeadbeef);
2060 test_sprintf_chunk("-16657", "%hd", 0xdeadbeef);
2061 test_sprintf_chunk("deadbeefdeadbeef", "%lx", 0xdeadbeefdeadbeef);
2062 test_sprintf_chunk("0xdeadbeefdeadbeef", "%p",
2063 (void *) 0xdeadbeefdeadbeef);
2064 test_sprintf_chunk("18446744073709551615", "%ju", (intmax_t) -1);
2065 test_sprintf_chunk("18446744073709551615", "%zu", (size_t) -1);
2066 test_sprintf_chunk("18446744073709551615", "%tu", (size_t) -1);
2068 test_sprintf_chunk("0x1.f9acffa7eb6bfp-4", "%a", 0.123456);
2069 test_sprintf_chunk("0X1.F9ACFFA7EB6BFP-4", "%A", 0.123456);
2070 test_sprintf_chunk("0.12346", "%.5f", 0.123456);
2071 test_sprintf_chunk("0.123456", "%g", 0.123456);
2072 test_sprintf_chunk("1.234560e-01", "%e", 0.123456);
2073 test_sprintf_chunk("1.234560E-01", "%E", 0.123456);
2074 test_sprintf_chunk("0.1234567891234560", "%.16Lf",
2075 (long double) 0.123456789123456);
2077 test_sprintf_chunk("z", "%c", 'z');
2079 // %n, %s, %d, %f, and %% already tested
2081 // Test formatting with width passed as an argument.
2082 r
= sprintf(buf
, "hi %*d my %*s friend %.*f", 3, 1, 6, "dear", 4, 3.14159265359);
2084 assert(strcmp(buf
, "hi 1 my dear friend 3.1416") == 0);
2087 void test_snprintf() {
2089 memset(buf
, 'a', sizeof(buf
));
2090 dfsan_set_label(0, buf
, sizeof(buf
));
2091 const char* s
= "world";
2095 dfsan_set_label(k_label
, (void *) (s
+ 1), 2);
2096 dfsan_origin s_o
= dfsan_get_origin((long)(s
[1]));
2097 dfsan_set_label(i_label
, &y
, sizeof(y
));
2098 dfsan_origin y_o
= dfsan_get_origin((long)y
);
2099 dfsan_set_label(j_label
, &m
, sizeof(m
));
2100 dfsan_origin m_o
= dfsan_get_origin((long)m
);
2101 #ifndef ORIGIN_TRACKING
2106 int r
= snprintf(buf
, 19, "hello %s, %-d/ %d/%d %f", s
, y
, m
, d
,
2108 // The return value is the number of bytes that would have been written to
2109 // the final string if enough space had been available.
2111 assert(memcmp(buf
, "hello world, 2014/", 19) == 0);
2112 ASSERT_READ_LABEL(buf
, 7, 0);
2113 ASSERT_READ_LABEL(buf
+ 7, 2, k_label
);
2114 ASSERT_INIT_ORIGINS(buf
+ 7, 2, s_o
);
2115 ASSERT_READ_LABEL(buf
+ 9, 4, 0);
2116 ASSERT_READ_LABEL(buf
+ 13, 4, i_label
);
2117 ASSERT_INIT_ORIGINS(buf
+ 13, 4, y_o
);
2118 ASSERT_READ_LABEL(buf
+ 17, 2, 0);
2123 void test_sscanf_chunk(T expected
, const char *format
, char *input
,
2125 char padded_input
[512];
2126 strcpy(padded_input
, "foo ");
2127 strcat(padded_input
, input
);
2128 strcpy(padded_input
, "@");
2129 strcat(padded_input
, input
);
2130 strcat(padded_input
, " bar");
2132 char padded_format
[512];
2133 strcpy(padded_format
, "foo ");
2134 // Swap the first '%' for '%*' so this input is skipped.
2135 strcpy(padded_format
, "%*");
2136 strcat(padded_format
, format
+ 1);
2137 strcpy(padded_format
, "@");
2138 strcat(padded_format
, format
);
2139 strcat(padded_format
, " bar");
2141 char *s
= padded_input
+ 4;
2143 memset(&arg
, 0, sizeof(arg
));
2144 dfsan_set_label(i_label
, (void *)(padded_input
), strlen(padded_input
));
2145 dfsan_set_label(j_label
, (void *)(padded_format
), strlen(padded_format
));
2146 dfsan_origin a_o
= dfsan_get_origin((long)(*s
));
2147 #ifndef ORIGIN_TRACKING
2152 int rv
= sscanf(padded_input
, padded_format
, &arg
);
2153 assert(rv
== items_num
);
2154 assert(arg
== expected
);
2155 ASSERT_READ_LABEL(&arg
, sizeof(arg
), i_label
);
2156 ASSERT_INIT_ORIGINS(&arg
, 1, a_o
);
2159 void test_sscanf() {
2162 memset(buf
, 'a', sizeof(buf
));
2163 memset(buf_out
, 'a', sizeof(buf_out
));
2166 strcpy(buf
, "Hello world!");
2167 assert(sscanf(buf
, "%s", buf_out
) == 1);
2168 assert(strcmp(buf
, "Hello world!") == 0);
2169 assert(strcmp(buf_out
, "Hello") == 0);
2170 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
2171 ASSERT_READ_LABEL(buf_out
, sizeof(buf_out
), 0);
2173 // Test for extra arguments.
2174 assert(sscanf(buf
, "%s", buf_out
, 42, "hello") == 1);
2175 assert(strcmp(buf
, "Hello world!") == 0);
2176 assert(strcmp(buf_out
, "Hello") == 0);
2177 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
2178 ASSERT_READ_LABEL(buf_out
, sizeof(buf_out
), 0);
2180 // Test formatting & label propagation (multiple conversion specifiers): %s,
2181 // %d, %n, %f, and %%.
2183 strcpy(buf
, "hello world, 42 2014/8/31 12345.678123 % 1000");
2184 char *s
= buf
+ 6; //starts with world
2190 dfsan_set_label(k_label
, (void *)(s
+ 1), 2); // buf[7]-b[9]
2191 dfsan_origin s_o
= dfsan_get_origin((long)(s
[1]));
2192 assert(s
[10] == '2');
2193 dfsan_set_label(i_label
, (void *)(s
+ 10), 4); // 2014
2194 dfsan_origin y_o
= dfsan_get_origin((long)s
[10]); // buf[16]
2195 assert(s
[17] == '3');
2196 dfsan_set_label(j_label
, (void *)(s
+ 17), 2); // 31
2197 dfsan_origin d_o
= dfsan_get_origin((long)s
[17]); // buf[23]
2198 assert(s
[20] == '1');
2199 dfsan_set_label(m_label
, (void *)(s
+ 20), 5); // 12345
2200 dfsan_origin f_o
= dfsan_get_origin((long)s
[20]); //buf[26]
2202 #ifndef ORIGIN_TRACKING
2213 int r
= sscanf(buf
, "hello %s %*d %d/%d/%d %f %% %n%d", buf_out
, &y
, &m
, &d
,
2216 assert(strcmp(buf_out
, "world,") == 0);
2220 assert(fval
> 12300.0f
);
2221 assert(fval
< 12400.0f
);
2222 ASSERT_READ_LABEL(buf_out
, 1, 0);
2223 ASSERT_READ_LABEL(buf_out
+ 1, 2, k_label
);
2224 ASSERT_INIT_ORIGINS(buf_out
+ 1, 2, s_o
);
2225 ASSERT_READ_LABEL(&y
, sizeof(y
), i_label
);
2226 ASSERT_INIT_ORIGINS(&y
, sizeof(y
), y_o
);
2227 ASSERT_READ_LABEL(&d
, sizeof(d
), j_label
);
2228 ASSERT_INIT_ORIGINS(&d
, sizeof(d
), d_o
);
2229 ASSERT_READ_LABEL(&fval
, sizeof(fval
), m_label
);
2230 ASSERT_INIT_ORIGINS(&fval
, sizeof(fval
), f_o
);
2231 ASSERT_READ_LABEL(&val
, 4, 0);
2234 assert(val
== 1000);
2236 // Test formatting & label propagation (single conversion specifier, with
2237 // additional length and precision modifiers).
2238 char input_buf
[512];
2239 char *input_ptr
= input_buf
;
2240 strcpy(input_buf
, "-559038737");
2241 test_sscanf_chunk(-559038737, "%d", input_ptr
, 1);
2242 strcpy(input_buf
, "3735928559");
2243 test_sscanf_chunk(3735928559, "%u", input_ptr
, 1);
2244 strcpy(input_buf
, "12345");
2245 test_sscanf_chunk(12345, "%i", input_ptr
, 1);
2246 strcpy(input_buf
, "0751");
2247 test_sscanf_chunk(489, "%o", input_ptr
, 1);
2248 strcpy(input_buf
, "0xbabe");
2249 test_sscanf_chunk(47806, "%x", input_ptr
, 1);
2250 strcpy(input_buf
, "0x0000BABE");
2251 test_sscanf_chunk(47806, "%10X", input_ptr
, 1);
2252 strcpy(input_buf
, "3735928559");
2253 test_sscanf_chunk((char)-17, "%hhd", input_ptr
, 1);
2254 strcpy(input_buf
, "3735928559");
2255 test_sscanf_chunk((short)-16657, "%hd", input_ptr
, 1);
2256 strcpy(input_buf
, "0xdeadbeefdeadbeef");
2257 test_sscanf_chunk(0xdeadbeefdeadbeefL
, "%lx", input_buf
, 1);
2258 test_sscanf_chunk((void *)0xdeadbeefdeadbeefL
, "%p", input_buf
, 1);
2260 intmax_t _x
= (intmax_t)-1;
2262 memset(_buf
, 0, sizeof(_buf
));
2263 sprintf(_buf
, "%ju", _x
);
2264 test_sscanf_chunk((intmax_t)18446744073709551615, "%ju", _buf
, 1);
2265 memset(_buf
, 0, sizeof(_buf
));
2266 size_t _y
= (size_t)-1;
2267 sprintf(_buf
, "%zu", _y
);
2268 test_sscanf_chunk((size_t)18446744073709551615, "%zu", _buf
, 1);
2269 memset(_buf
, 0, sizeof(_buf
));
2270 ptrdiff_t _z
= (size_t)-1;
2271 sprintf(_buf
, "%tu", _z
);
2272 test_sscanf_chunk((ptrdiff_t)18446744073709551615, "%tu", _buf
, 1);
2274 strcpy(input_buf
, "0.123456");
2275 test_sscanf_chunk((float)0.123456, "%8f", input_ptr
, 1);
2276 test_sscanf_chunk((float)0.123456, "%g", input_ptr
, 1);
2277 test_sscanf_chunk((float)1.234560e-01, "%e", input_ptr
, 1);
2278 test_sscanf_chunk((char)'z', "%c", "z", 1);
2280 // %n, %s, %d, %f, and %% already tested
2283 // Tested by a separate source file. This empty function is here to appease the
2284 // check-wrappers script.
2293 i_j_label
= dfsan_union(i_label
, j_label
);
2294 assert(i_j_label
!= i_label
);
2295 assert(i_j_label
!= j_label
);
2296 assert(i_j_label
!= k_label
);
2298 test__dl_get_tls_static_info();
2300 test_clock_gettime();
2302 test_dfsan_set_write_callback();
2303 test_dl_iterate_phdr();
2309 test_get_current_dir_name();
2319 test_gettimeofday();
2330 test_pthread_create();
2331 test_pthread_join();
2335 test_sched_getaffinity();