1 // RUN: %clang_dfsan %s -o %t && 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 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
6 // Tests custom implementations of various glibc functions.
8 // REQUIRES: x86_64-target-arch
10 #pragma clang diagnostic ignored "-Wformat-extra-args"
12 #include <sanitizer/dfsan_interface.h>
14 #include <arpa/inet.h>
28 #include <sys/epoll.h>
29 #include <sys/resource.h>
30 #include <sys/select.h>
31 #include <sys/socket.h>
34 #include <sys/types.h>
38 dfsan_label i_label
= 0;
39 dfsan_label j_label
= 0;
40 dfsan_label k_label
= 0;
41 dfsan_label m_label
= 0;
42 dfsan_label n_label
= 0;
43 dfsan_label i_j_label
= 0;
45 #define ASSERT_ZERO_LABEL(data) \
46 assert(0 == dfsan_get_label((long) (data)))
48 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
49 assert(0 == dfsan_read_label(ptr, size))
51 #define ASSERT_LABEL(data, label) \
52 assert(label == dfsan_get_label((long) (data)))
54 #define ASSERT_READ_LABEL(ptr, size, label) \
55 assert(label == dfsan_read_label(ptr, size))
57 #ifdef ORIGIN_TRACKING
58 #define ASSERT_ZERO_ORIGIN(data) \
59 assert(0 == dfsan_get_origin((long)(data)))
61 #define ASSERT_ZERO_ORIGIN(data)
64 #ifdef ORIGIN_TRACKING
65 #define ASSERT_ZERO_ORIGINS(ptr, size) \
66 for (int i = 0; i < size; ++i) { \
67 assert(0 == dfsan_get_origin((long)(((char *)ptr)[i]))); \
70 #define ASSERT_ZERO_ORIGINS(ptr, size)
73 #ifdef ORIGIN_TRACKING
74 #define ASSERT_ORIGIN(data, origin) \
75 assert(origin == dfsan_get_origin((long)(data)))
77 #define ASSERT_ORIGIN(data, origin)
80 #ifdef ORIGIN_TRACKING
81 #define ASSERT_ORIGINS(ptr, size, origin) \
82 for (int i = 0; i < size; ++i) { \
83 assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \
86 #define ASSERT_ORIGINS(ptr, size, origin)
89 #ifdef ORIGIN_TRACKING
90 #define ASSERT_INIT_ORIGIN(ptr, origin) \
91 assert(origin == dfsan_get_init_origin(ptr))
93 #define ASSERT_INIT_ORIGIN(ptr, origin)
96 #ifdef ORIGIN_TRACKING
97 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) \
98 assert(dfsan_get_origin((long)(data)) == dfsan_get_init_origin(ptr))
100 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data)
103 #ifdef ORIGIN_TRACKING
104 #define ASSERT_INIT_ORIGINS(ptr, size, origin) \
105 for (int i = 0; i < size; ++i) { \
106 assert(origin == dfsan_get_init_origin(&((char *)ptr)[i])); \
109 #define ASSERT_INIT_ORIGINS(ptr, size, origin)
112 #ifdef ORIGIN_TRACKING
113 #define ASSERT_EQ_ORIGIN(data1, data2) \
114 assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2)))
116 #define ASSERT_EQ_ORIGIN(data1, data2)
119 #ifdef ORIGIN_TRACKING
120 #define DEFINE_AND_SAVE_ORIGINS(val) \
121 dfsan_origin val##_o[sizeof(val)]; \
122 for (int i = 0; i < sizeof(val); ++i) \
123 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
125 #define DEFINE_AND_SAVE_ORIGINS(val)
128 #ifdef ORIGIN_TRACKING
129 #define SAVE_ORIGINS(val) \
130 for (int i = 0; i < sizeof(val); ++i) \
131 val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
133 #define SAVE_ORIGINS(val)
136 #ifdef ORIGIN_TRACKING
137 #define ASSERT_SAVED_ORIGINS(val) \
138 for (int i = 0; i < sizeof(val); ++i) \
139 ASSERT_ORIGIN(((char *)(&val))[i], val##_o[i]);
141 #define ASSERT_SAVED_ORIGINS(val)
144 #ifdef ORIGIN_TRACKING
145 #define DEFINE_AND_SAVE_N_ORIGINS(val, n) \
146 dfsan_origin val##_o[n]; \
147 for (int i = 0; i < n; ++i) \
148 val##_o[i] = dfsan_get_origin((long)(val[i]));
150 #define DEFINE_AND_SAVE_N_ORIGINS(val, n)
153 #ifdef ORIGIN_TRACKING
154 #define ASSERT_SAVED_N_ORIGINS(val, n) \
155 for (int i = 0; i < n; ++i) \
156 ASSERT_ORIGIN(val[i], val##_o[i]);
158 #define ASSERT_SAVED_N_ORIGINS(val, n)
161 #if !defined(__GLIBC_PREREQ)
162 # define __GLIBC_PREREQ(a, b) 0
167 dfsan_set_label(i_label
, &i
, sizeof(i
));
171 DEFINE_AND_SAVE_ORIGINS(s
)
172 int ret
= stat("/", &s
);
174 ASSERT_ZERO_LABEL(ret
);
175 ASSERT_ZERO_LABEL(s
.st_dev
);
176 ASSERT_SAVED_ORIGINS(s
)
180 ret
= stat("/nonexistent", &s
);
182 ASSERT_ZERO_LABEL(ret
);
183 ASSERT_LABEL(s
.st_dev
, i_label
);
184 ASSERT_SAVED_ORIGINS(s
)
189 dfsan_set_label(i_label
, &i
, sizeof(i
));
192 int fd
= open("/dev/zero", O_RDONLY
);
194 DEFINE_AND_SAVE_ORIGINS(s
)
195 int rv
= fstat(fd
, &s
);
197 ASSERT_ZERO_LABEL(rv
);
198 ASSERT_ZERO_LABEL(s
.st_dev
);
199 ASSERT_SAVED_ORIGINS(s
)
203 char str1
[] = "str1", str2
[] = "str2";
204 dfsan_set_label(i_label
, &str1
[3], 1);
205 dfsan_set_label(j_label
, &str2
[3], 1);
207 int rv
= memcmp(str1
, str2
, sizeof(str1
));
209 #ifdef STRICT_DATA_DEPENDENCIES
210 ASSERT_ZERO_LABEL(rv
);
212 ASSERT_LABEL(rv
, i_j_label
);
213 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
216 rv
= memcmp(str1
, str2
, sizeof(str1
) - 2);
218 ASSERT_ZERO_LABEL(rv
);
222 char str1
[] = "str1", str2
[] = "str2";
223 dfsan_set_label(i_label
, &str1
[3], 1);
224 dfsan_set_label(j_label
, &str2
[3], 1);
226 int rv
= bcmp(str1
, str2
, sizeof(str1
));
228 #ifdef STRICT_DATA_DEPENDENCIES
229 ASSERT_ZERO_LABEL(rv
);
231 ASSERT_LABEL(rv
, i_j_label
);
232 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
235 rv
= bcmp(str1
, str2
, sizeof(str1
) - 2);
237 ASSERT_ZERO_LABEL(rv
);
241 char str1
[] = "str1";
242 char str2
[sizeof(str1
)];
243 dfsan_set_label(i_label
, &str1
[3], 1);
245 DEFINE_AND_SAVE_ORIGINS(str1
)
248 dfsan_set_label(j_label
, &ptr2
, sizeof(ptr2
));
250 void *r
= memcpy(ptr2
, str1
, sizeof(str1
));
251 ASSERT_LABEL(r
, j_label
);
252 ASSERT_EQ_ORIGIN(r
, ptr2
);
253 assert(0 == memcmp(str2
, str1
, sizeof(str1
)));
254 ASSERT_ZERO_LABEL(str2
[0]);
255 ASSERT_LABEL(str2
[3], i_label
);
257 for (int i
= 0; i
< sizeof(str2
); ++i
) {
258 if (!dfsan_get_label(str2
[i
]))
260 ASSERT_INIT_ORIGIN(&(str2
[i
]), str1_o
[i
]);
264 void test_memmove() {
265 char str
[] = "str1xx";
266 dfsan_set_label(i_label
, &str
[3], 1);
268 DEFINE_AND_SAVE_ORIGINS(str
)
271 dfsan_set_label(j_label
, &ptr
, sizeof(ptr
));
273 void *r
= memmove(ptr
, str
, 4);
274 ASSERT_LABEL(r
, j_label
);
275 ASSERT_EQ_ORIGIN(r
, ptr
);
276 assert(0 == memcmp(str
+ 2, "str1", 4));
277 ASSERT_ZERO_LABEL(str
[4]);
278 ASSERT_LABEL(str
[5], i_label
);
280 for (int i
= 0; i
< 4; ++i
) {
281 if (!dfsan_get_label(ptr
[i
]))
283 ASSERT_INIT_ORIGIN(&(ptr
[i
]), str_o
[i
]);
291 dfsan_set_label(j_label
, &j
, sizeof(j
));
292 dfsan_set_label(k_label
, &ptr
, sizeof(ptr
));
293 void *ret
= memset(ptr
, j
, sizeof(buf
));
294 ASSERT_LABEL(ret
, k_label
);
295 ASSERT_EQ_ORIGIN(ret
, ptr
);
296 for (int i
= 0; i
< 8; ++i
) {
297 ASSERT_LABEL(buf
[i
], j_label
);
298 ASSERT_EQ_ORIGIN(buf
[i
], j
);
299 assert(buf
[i
] == 'a');
304 char str1
[] = "str1", str2
[] = "str2";
305 dfsan_set_label(i_label
, &str1
[3], 1);
306 dfsan_set_label(j_label
, &str2
[3], 1);
308 int rv
= strcmp(str1
, str2
);
310 #ifdef STRICT_DATA_DEPENDENCIES
311 ASSERT_ZERO_LABEL(rv
);
313 ASSERT_LABEL(rv
, i_j_label
);
314 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
317 rv
= strcmp(str1
, str1
);
319 #ifdef STRICT_DATA_DEPENDENCIES
320 ASSERT_ZERO_LABEL(rv
);
321 ASSERT_ZERO_ORIGIN(rv
);
323 ASSERT_LABEL(rv
, i_label
);
324 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
329 char src
[] = "world";
330 int volatile x
= 0; // buffer to ensure src and dst do not share origins
332 char dst
[] = "hello \0 ";
333 int volatile y
= 0; // buffer to ensure dst and p do not share origins
336 dfsan_set_label(k_label
, &p
, sizeof(p
));
337 dfsan_set_label(i_label
, src
, sizeof(src
));
338 dfsan_set_label(j_label
, dst
, sizeof(dst
));
339 dfsan_origin dst_o
= dfsan_get_origin((long)dst
[0]);
341 char *ret
= strcat(p
, src
);
342 ASSERT_LABEL(ret
, k_label
);
343 ASSERT_EQ_ORIGIN(ret
, p
);
345 assert(strcmp(src
, dst
+ 6) == 0);
346 // Origins are assigned for every 4 contiguous 4-aligned bytes. After
347 // appending src to dst, origins of src can overwrite origins of dst if their
348 // application adddresses are within [start_aligned_down, end_aligned_up).
349 // Other origins are not changed.
350 char *start_aligned_down
= (char *)(((size_t)(dst
+ 6)) & ~3UL);
351 char *end_aligned_up
= (char *)(((size_t)(dst
+ 11 + 4)) & ~3UL);
352 for (int i
= 0; i
< 12; ++i
) {
353 if (dst
+ i
< start_aligned_down
|| dst
+ i
>= end_aligned_up
) {
354 ASSERT_INIT_ORIGIN(&dst
[i
], dst_o
);
356 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst
[i
], src
[0]);
359 for (int i
= 0; i
< 6; ++i
) {
360 ASSERT_LABEL(dst
[i
], j_label
);
362 for (int i
= 6; i
< strlen(dst
); ++i
) {
363 ASSERT_LABEL(dst
[i
], i_label
);
364 assert(dfsan_get_label(dst
[i
]) == dfsan_get_label(src
[i
- 6]));
366 ASSERT_LABEL(dst
[11], j_label
);
370 char str1
[] = "str1";
371 dfsan_set_label(i_label
, &str1
[3], 1);
373 int rv
= strlen(str1
);
375 #ifdef STRICT_DATA_DEPENDENCIES
376 ASSERT_ZERO_LABEL(rv
);
378 ASSERT_LABEL(rv
, i_label
);
379 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
384 char str1
[] = "str1";
385 dfsan_set_label(i_label
, &str1
[3], 1);
386 DEFINE_AND_SAVE_ORIGINS(str1
)
388 char *strd
= strdup(str1
);
389 ASSERT_ZERO_LABEL(strd
);
390 ASSERT_ZERO_LABEL(strd
[0]);
391 ASSERT_LABEL(strd
[3], i_label
);
393 for (int i
= 0; i
< strlen(strd
); ++i
) {
394 if (!dfsan_get_label(strd
[i
]))
396 ASSERT_INIT_ORIGIN(&(strd
[i
]), str1_o
[i
]);
402 void test_strncpy() {
403 char str1
[] = "str1";
404 char str2
[sizeof(str1
)];
405 dfsan_set_label(i_label
, &str1
[3], 1);
407 char *strd
= strncpy(str2
, str1
, 5);
408 assert(strd
== str2
);
409 assert(strcmp(str1
, str2
) == 0);
410 ASSERT_ZERO_LABEL(strd
);
411 ASSERT_ZERO_LABEL(strd
[0]);
412 ASSERT_ZERO_LABEL(strd
[1]);
413 ASSERT_ZERO_LABEL(strd
[2]);
414 ASSERT_LABEL(strd
[3], i_label
);
415 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd
[3]), str1
[3]);
418 dfsan_set_label(j_label
, &p2
, sizeof(p2
));
419 strd
= strncpy(p2
, str1
, 3);
420 assert(strd
== str2
);
421 assert(strncmp(str1
, str2
, 3) == 0);
422 ASSERT_LABEL(strd
, j_label
);
423 ASSERT_EQ_ORIGIN(strd
, p2
);
424 // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates
425 // to strd[i]'s label. When ORIGIN_TRACKING is defined,
426 // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag
428 #if defined(ORIGIN_TRACKING)
429 ASSERT_ZERO_LABEL(strd
[0]);
430 ASSERT_ZERO_LABEL(strd
[1]);
431 ASSERT_ZERO_LABEL(strd
[2]);
433 ASSERT_LABEL(strd
[0], j_label
);
434 ASSERT_LABEL(strd
[1], j_label
);
435 ASSERT_LABEL(strd
[2], j_label
);
439 void test_strncmp() {
440 char str1
[] = "str1", str2
[] = "str2";
441 dfsan_set_label(i_label
, &str1
[3], 1);
442 dfsan_set_label(j_label
, &str2
[3], 1);
444 int rv
= strncmp(str1
, str2
, sizeof(str1
));
446 #ifdef STRICT_DATA_DEPENDENCIES
447 ASSERT_ZERO_LABEL(rv
);
449 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
450 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
453 rv
= strncmp(str1
, str2
, 0);
455 ASSERT_ZERO_LABEL(rv
);
457 rv
= strncmp(str1
, str2
, 3);
459 ASSERT_ZERO_LABEL(rv
);
461 rv
= strncmp(str1
, str1
, 4);
463 #ifdef STRICT_DATA_DEPENDENCIES
464 ASSERT_ZERO_LABEL(rv
);
466 ASSERT_LABEL(rv
, i_label
);
467 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
471 void test_strcasecmp() {
472 char str1
[] = "str1", str2
[] = "str2", str3
[] = "Str1";
473 dfsan_set_label(i_label
, &str1
[3], 1);
474 dfsan_set_label(j_label
, &str2
[3], 1);
475 dfsan_set_label(j_label
, &str3
[2], 1);
477 int rv
= strcasecmp(str1
, str2
);
479 #ifdef STRICT_DATA_DEPENDENCIES
480 ASSERT_ZERO_LABEL(rv
);
482 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
483 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
486 rv
= strcasecmp(str1
, str3
);
488 #ifdef STRICT_DATA_DEPENDENCIES
489 ASSERT_ZERO_LABEL(rv
);
491 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
492 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
497 dfsan_set_label(i_label
, &s1
[2], 1);
498 dfsan_set_label(j_label
, &s2
[2], 1);
500 rv
= strcasecmp(s1
, s2
);
501 assert(rv
> 0); // 'Z' > 'y'
502 #ifdef STRICT_DATA_DEPENDENCIES
503 ASSERT_ZERO_LABEL(rv
);
505 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
506 ASSERT_EQ_ORIGIN(rv
, s1
[2]);
510 void test_strncasecmp() {
511 char str1
[] = "Str1", str2
[] = "str2";
512 dfsan_set_label(i_label
, &str1
[3], 1);
513 dfsan_set_label(j_label
, &str2
[3], 1);
515 int rv
= strncasecmp(str1
, str2
, sizeof(str1
));
517 #ifdef STRICT_DATA_DEPENDENCIES
518 ASSERT_ZERO_LABEL(rv
);
520 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
521 ASSERT_EQ_ORIGIN(rv
, str1
[3]);
524 rv
= strncasecmp(str1
, str2
, 3);
526 ASSERT_ZERO_LABEL(rv
);
530 dfsan_set_label(i_label
, &s1
[2], 1);
531 dfsan_set_label(j_label
, &s2
[2], 1);
533 rv
= strncasecmp(s1
, s2
, 0);
534 assert(rv
== 0); // Compare zero chars.
535 ASSERT_ZERO_LABEL(rv
);
537 rv
= strncasecmp(s1
, s2
, 1);
538 assert(rv
== 0); // 'A' == 'a'
539 ASSERT_ZERO_LABEL(rv
);
541 rv
= strncasecmp(s1
, s2
, 2);
542 assert(rv
== 0); // 'b' == 'B'
543 ASSERT_ZERO_LABEL(rv
);
545 rv
= strncasecmp(s1
, s2
, 3);
546 assert(rv
> 0); // 'Z' > 'y'
547 #ifdef STRICT_DATA_DEPENDENCIES
548 ASSERT_ZERO_LABEL(rv
);
550 ASSERT_LABEL(rv
, dfsan_union(i_label
, j_label
));
551 ASSERT_EQ_ORIGIN(rv
, s1
[2]);
556 char str1
[] = "str1";
557 dfsan_set_label(i_label
, &str1
[3], 1);
561 dfsan_set_label(k_label
, &c
, sizeof(c
));
563 char *crv
= strchr(p1
, c
);
564 assert(crv
== &str1
[2]);
565 #ifdef STRICT_DATA_DEPENDENCIES
566 ASSERT_ZERO_LABEL(crv
);
568 ASSERT_LABEL(crv
, k_label
);
569 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, c
);
572 dfsan_set_label(j_label
, &p1
, sizeof(p1
));
573 crv
= strchr(p1
, 'r');
574 assert(crv
== &str1
[2]);
575 ASSERT_LABEL(crv
, j_label
);
576 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
578 crv
= strchr(p1
, '1');
579 assert(crv
== &str1
[3]);
580 #ifdef STRICT_DATA_DEPENDENCIES
581 ASSERT_LABEL(crv
, j_label
);
582 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
584 ASSERT_LABEL(crv
, i_j_label
);
585 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
588 crv
= strchr(p1
, 'x');
590 #ifdef STRICT_DATA_DEPENDENCIES
591 ASSERT_LABEL(crv
, j_label
);
592 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
594 ASSERT_LABEL(crv
, i_j_label
);
595 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
598 // `man strchr` says:
599 // The terminating null byte is considered part of the string, so that if c
600 // is specified as '\0', these functions return a pointer to the terminator.
601 crv
= strchr(p1
, '\0');
602 assert(crv
== &str1
[4]);
603 #ifdef STRICT_DATA_DEPENDENCIES
604 ASSERT_LABEL(crv
, j_label
);
605 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, p1
);
607 ASSERT_LABEL(crv
, i_j_label
);
608 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv
, str1
[3]);
612 void test_recvmmsg() {
614 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
617 // Setup messages to send.
618 struct mmsghdr smmsg
[2] = {};
619 char sbuf0
[] = "abcdefghijkl";
620 struct iovec siov0
[2] = {{&sbuf0
[0], 4}, {&sbuf0
[4], 4}};
621 smmsg
[0].msg_hdr
.msg_iov
= siov0
;
622 smmsg
[0].msg_hdr
.msg_iovlen
= 2;
623 char sbuf1
[] = "1234567890";
624 struct iovec siov1
[1] = {{&sbuf1
[0], 7}};
625 smmsg
[1].msg_hdr
.msg_iov
= siov1
;
626 smmsg
[1].msg_hdr
.msg_iovlen
= 1;
629 int sent_msgs
= sendmmsg(sockfds
[0], smmsg
, 2, 0);
630 assert(sent_msgs
== 2);
632 // Setup receive buffers.
633 struct mmsghdr rmmsg
[2] = {};
635 struct iovec riov0
[2] = {{&rbuf0
[0], 4}, {&rbuf0
[4], 4}};
636 rmmsg
[0].msg_hdr
.msg_iov
= riov0
;
637 rmmsg
[0].msg_hdr
.msg_iovlen
= 2;
639 struct iovec riov1
[1] = {{&rbuf1
[0], 16}};
640 rmmsg
[1].msg_hdr
.msg_iov
= riov1
;
641 rmmsg
[1].msg_hdr
.msg_iovlen
= 1;
642 struct timespec timeout
= {1, 1};
643 dfsan_set_label(i_label
, rbuf0
, sizeof(rbuf0
));
644 dfsan_set_label(i_label
, rbuf1
, sizeof(rbuf1
));
645 dfsan_set_label(i_label
, &rmmsg
[0].msg_len
, sizeof(rmmsg
[0].msg_len
));
646 dfsan_set_label(i_label
, &rmmsg
[1].msg_len
, sizeof(rmmsg
[1].msg_len
));
647 dfsan_set_label(i_label
, &timeout
, sizeof(timeout
));
649 dfsan_origin msg_len0_o
= dfsan_get_origin((long)(rmmsg
[0].msg_len
));
650 dfsan_origin msg_len1_o
= dfsan_get_origin((long)(rmmsg
[1].msg_len
));
651 #ifndef ORIGIN_TRACKING
656 // Receive messages and check labels.
657 int received_msgs
= recvmmsg(sockfds
[1], rmmsg
, 2, 0, &timeout
);
658 assert(received_msgs
== sent_msgs
);
659 assert(rmmsg
[0].msg_len
== smmsg
[0].msg_len
);
660 assert(rmmsg
[1].msg_len
== smmsg
[1].msg_len
);
661 assert(memcmp(sbuf0
, rbuf0
, 8) == 0);
662 assert(memcmp(sbuf1
, rbuf1
, 7) == 0);
663 ASSERT_ZERO_LABEL(received_msgs
);
664 ASSERT_ZERO_LABEL(rmmsg
[0].msg_len
);
665 ASSERT_ZERO_LABEL(rmmsg
[1].msg_len
);
666 ASSERT_READ_ZERO_LABEL(&rbuf0
[0], 8);
667 ASSERT_READ_LABEL(&rbuf0
[8], 1, i_label
);
668 ASSERT_READ_ZERO_LABEL(&rbuf1
[0], 7);
669 ASSERT_READ_LABEL(&rbuf1
[7], 1, i_label
);
670 ASSERT_LABEL(timeout
.tv_sec
, i_label
);
671 ASSERT_LABEL(timeout
.tv_nsec
, i_label
);
673 ASSERT_ORIGIN((long)(rmmsg
[0].msg_len
), msg_len0_o
);
674 ASSERT_ORIGIN((long)(rmmsg
[1].msg_len
), msg_len1_o
);
680 void test_recvmsg() {
682 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
685 char sbuf
[] = "abcdefghijkl";
686 struct iovec siovs
[2] = {{&sbuf
[0], 4}, {&sbuf
[4], 4}};
687 struct msghdr smsg
= {};
688 smsg
.msg_iov
= siovs
;
691 ssize_t sent
= sendmsg(sockfds
[0], &smsg
, 0);
695 struct iovec riovs
[2] = {{&rbuf
[0], 4}, {&rbuf
[4], 4}};
696 struct msghdr rmsg
= {};
697 rmsg
.msg_iov
= riovs
;
700 dfsan_set_label(i_label
, rbuf
, sizeof(rbuf
));
701 dfsan_set_label(i_label
, &rmsg
, sizeof(rmsg
));
703 DEFINE_AND_SAVE_ORIGINS(rmsg
)
705 ssize_t received
= recvmsg(sockfds
[1], &rmsg
, 0);
706 assert(received
== sent
);
707 assert(memcmp(sbuf
, rbuf
, 8) == 0);
708 ASSERT_ZERO_LABEL(received
);
709 ASSERT_READ_ZERO_LABEL(&rmsg
, sizeof(rmsg
));
710 ASSERT_READ_ZERO_LABEL(&rbuf
[0], 8);
711 ASSERT_READ_LABEL(&rbuf
[8], 1, i_label
);
713 ASSERT_SAVED_ORIGINS(rmsg
)
721 dfsan_set_label(i_label
, buf
, 1);
722 dfsan_set_label(j_label
, buf
+ 15, 1);
724 DEFINE_AND_SAVE_ORIGINS(buf
)
725 ASSERT_LABEL(buf
[0], i_label
);
726 ASSERT_LABEL(buf
[15], j_label
);
728 int fd
= open("/dev/zero", O_RDONLY
);
729 int rv
= read(fd
, buf
, sizeof(buf
));
730 assert(rv
== sizeof(buf
));
731 ASSERT_ZERO_LABEL(rv
);
732 ASSERT_ZERO_LABEL(buf
[0]);
733 ASSERT_ZERO_LABEL(buf
[15]);
734 ASSERT_SAVED_ORIGINS(buf
)
740 dfsan_set_label(i_label
, buf
, 1);
741 dfsan_set_label(j_label
, buf
+ 15, 1);
743 DEFINE_AND_SAVE_ORIGINS(buf
)
744 ASSERT_LABEL(buf
[0], i_label
);
745 ASSERT_LABEL(buf
[15], j_label
);
747 int fd
= open("/bin/sh", O_RDONLY
);
748 int rv
= pread(fd
, buf
, sizeof(buf
), 0);
749 assert(rv
== sizeof(buf
));
750 ASSERT_ZERO_LABEL(rv
);
751 ASSERT_ZERO_LABEL(buf
[0]);
752 ASSERT_ZERO_LABEL(buf
[15]);
753 ASSERT_SAVED_ORIGINS(buf
)
758 void *map
= dlopen(NULL
, RTLD_NOW
);
760 ASSERT_ZERO_LABEL(map
);
762 map
= dlopen("/nonexistent", RTLD_NOW
);
764 ASSERT_ZERO_LABEL(map
);
767 void test_clock_gettime() {
769 dfsan_set_label(j_label
, ((char *)&tp
) + 3, 1);
770 dfsan_origin origin
= dfsan_get_origin((long)(((char *)&tp
)[3]));
771 #ifndef ORIGIN_TRACKING
774 int t
= clock_gettime(CLOCK_REALTIME
, &tp
);
776 ASSERT_ZERO_LABEL(t
);
777 ASSERT_ZERO_LABEL(((char *)&tp
)[3]);
778 ASSERT_ORIGIN(((char *)&tp
)[3], origin
);
781 void test_ctime_r() {
782 char *buf
= (char*) malloc(64);
785 DEFINE_AND_SAVE_ORIGINS(buf
)
786 dfsan_origin t_o
= dfsan_get_origin((long)t
);
788 char *ret
= ctime_r(&t
, buf
);
789 ASSERT_ZERO_LABEL(ret
);
791 ASSERT_READ_ZERO_LABEL(buf
, strlen(buf
) + 1);
792 ASSERT_SAVED_ORIGINS(buf
)
794 dfsan_set_label(i_label
, &t
, sizeof(t
));
795 t_o
= dfsan_get_origin((long)t
);
796 ret
= ctime_r(&t
, buf
);
797 ASSERT_ZERO_LABEL(ret
);
798 ASSERT_READ_LABEL(buf
, strlen(buf
) + 1, i_label
);
799 for (int i
= 0; i
< strlen(buf
) + 1; ++i
)
800 ASSERT_ORIGIN(buf
[i
], t_o
);
803 dfsan_set_label(j_label
, &buf
, sizeof(&buf
));
804 dfsan_origin buf_ptr_o
= dfsan_get_origin((long)buf
);
805 #ifndef ORIGIN_TRACKING
808 ret
= ctime_r(&t
, buf
);
809 ASSERT_LABEL(ret
, j_label
);
810 ASSERT_ORIGIN(ret
, buf_ptr_o
);
811 ASSERT_READ_ZERO_LABEL(buf
, strlen(buf
) + 1);
812 for (int i
= 0; i
< strlen(buf
) + 1; ++i
)
813 ASSERT_ORIGIN(buf
[i
], t_o
);
816 static int write_callback_count
= 0;
818 static const unsigned char *last_buf
;
819 static size_t last_count
;
821 void write_callback(int fd
, const void *buf
, size_t count
) {
822 write_callback_count
++;
825 last_buf
= (const unsigned char*) buf
;
829 void test_dfsan_set_write_callback() {
830 char a_buf
[] = "Sample chars";
831 int a_buf_len
= strlen(a_buf
);
833 int fd
= open("/dev/null", O_WRONLY
);
835 dfsan_set_write_callback(write_callback
);
837 write_callback_count
= 0;
839 DEFINE_AND_SAVE_ORIGINS(a_buf
)
841 // Callback should be invoked on every call to write().
842 int res
= write(fd
, a_buf
, a_buf_len
);
843 assert(write_callback_count
== 1);
844 ASSERT_READ_ZERO_LABEL(&res
, sizeof(res
));
845 ASSERT_READ_ZERO_LABEL(&last_fd
, sizeof(last_fd
));
846 ASSERT_READ_ZERO_LABEL(last_buf
, sizeof(last_buf
));
848 for (int i
= 0; i
< a_buf_len
; ++i
)
849 ASSERT_ORIGIN(last_buf
[i
], a_buf_o
[i
]);
851 ASSERT_ZERO_ORIGINS(&last_count
, sizeof(last_count
));
856 char b_buf
[] = "Other chars";
857 int b_buf_len
= strlen(b_buf
);
858 // Create a separate variable so we can taint the pointer.
859 // We would always get a shadow of 0 for b_buf because it is a constant.
860 const unsigned char *buf
= (const unsigned char *)b_buf
;
862 // Add a label to write() arguments. Check that the labels are readable from
863 // the values passed to the callback.
864 dfsan_set_label(i_label
, &fd
, sizeof(fd
));
865 dfsan_set_label(j_label
, &buf
, sizeof(buf
)); // ptr
866 dfsan_set_label(k_label
, &(b_buf
[3]), 1); // content
867 dfsan_set_label(m_label
, &b_buf_len
, sizeof(b_buf_len
));
869 dfsan_origin fd_o
= dfsan_get_origin((long)fd
);
870 dfsan_origin b_buf3_o
= dfsan_get_origin((long)(b_buf
[3]));
871 dfsan_origin b_buf_len_o
= dfsan_get_origin((long)b_buf_len
);
872 #ifndef ORIGIN_TRACKING
877 DEFINE_AND_SAVE_ORIGINS(b_buf
)
879 res
= write(fd
, buf
, b_buf_len
);
880 assert(write_callback_count
== 2);
881 assert(last_fd
== fd
);
882 assert(last_buf
== (const unsigned char *)b_buf
);
883 assert(last_count
== b_buf_len
);
885 ASSERT_READ_ZERO_LABEL(&res
, sizeof(res
));
886 ASSERT_READ_LABEL(&last_fd
, sizeof(last_fd
), i_label
);
887 ASSERT_READ_LABEL(&last_buf
, sizeof(&last_buf
), j_label
); // ptr
888 ASSERT_READ_LABEL(last_buf
, last_count
, k_label
); // content
889 ASSERT_READ_LABEL(&last_buf
[3], sizeof(last_buf
[3]), k_label
); // content
890 ASSERT_READ_LABEL(&last_count
, sizeof(last_count
), m_label
);
891 ASSERT_ZERO_ORIGINS(&res
, sizeof(res
));
892 ASSERT_INIT_ORIGINS(&last_fd
, sizeof(last_fd
), fd_o
);
893 ASSERT_INIT_ORIGINS(&last_buf
[3], sizeof(last_buf
[3]), b_buf3_o
);
895 // Origins are assigned for every 4 contiguous 4-aligned bytes. After
896 // appending src to dst, origins of src can overwrite origins of dst if their
897 // application adddresses are within an aligned range. Other origins are not
899 for (int i
= 0; i
< b_buf_len
; ++i
) {
900 size_t i_addr
= size_t(&last_buf
[i
]);
901 if (((size_t(&last_buf
[3]) & ~3UL) > i_addr
) ||
902 (((size_t(&last_buf
[3]) + 4) & ~3UL) <= i_addr
))
903 ASSERT_ORIGIN(last_buf
[i
], b_buf_o
[i
]);
906 ASSERT_INIT_ORIGINS(&last_count
, sizeof(last_count
), b_buf_len_o
);
908 dfsan_set_write_callback(NULL
);
912 char *buf
= (char*) malloc(128);
913 FILE *f
= fopen("/etc/passwd", "r");
914 dfsan_set_label(j_label
, buf
, 1);
915 DEFINE_AND_SAVE_N_ORIGINS(buf
, 128)
917 char *ret
= fgets(buf
, sizeof(buf
), f
);
919 ASSERT_ZERO_LABEL(ret
);
920 ASSERT_EQ_ORIGIN(ret
, buf
);
921 ASSERT_READ_ZERO_LABEL(buf
, 128);
922 ASSERT_SAVED_N_ORIGINS(buf
, 128)
924 dfsan_set_label(j_label
, &buf
, sizeof(&buf
));
925 ret
= fgets(buf
, sizeof(buf
), f
);
926 ASSERT_LABEL(ret
, j_label
);
927 ASSERT_EQ_ORIGIN(ret
, buf
);
928 ASSERT_SAVED_N_ORIGINS(buf
, 128)
937 dfsan_set_label(i_label
, buf
+ 2, 2);
938 DEFINE_AND_SAVE_ORIGINS(buf
)
940 char* ret
= getcwd(buf
, sizeof(buf
));
942 assert(ret
[0] == '/');
943 ASSERT_ZERO_LABEL(ret
);
944 ASSERT_EQ_ORIGIN(ret
, buf
);
945 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
946 ASSERT_SAVED_ORIGINS(buf
)
948 dfsan_set_label(i_label
, &ptr
, sizeof(ptr
));
949 ret
= getcwd(ptr
, sizeof(buf
));
950 ASSERT_LABEL(ret
, i_label
);
951 ASSERT_EQ_ORIGIN(ret
, ptr
);
952 ASSERT_SAVED_ORIGINS(buf
)
955 void test_get_current_dir_name() {
956 char* ret
= get_current_dir_name();
958 assert(ret
[0] == '/');
959 ASSERT_READ_ZERO_LABEL(ret
, strlen(ret
) + 1);
960 ASSERT_ZERO_LABEL(ret
);
963 void test_getentropy() {
965 dfsan_set_label(i_label
, buf
+ 2, 2);
966 DEFINE_AND_SAVE_ORIGINS(buf
)
967 #if __GLIBC_PREREQ(2, 25)
968 // glibc >= 2.25 has getentropy()
969 int ret
= getentropy(buf
, sizeof(buf
));
970 ASSERT_ZERO_LABEL(ret
);
972 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
973 ASSERT_SAVED_ORIGINS(buf
)
978 void test_gethostname() {
980 dfsan_set_label(i_label
, buf
+ 2, 2);
981 DEFINE_AND_SAVE_ORIGINS(buf
)
982 int ret
= gethostname(buf
, sizeof(buf
));
984 ASSERT_ZERO_LABEL(ret
);
985 ASSERT_READ_ZERO_LABEL(buf
+ 2, 2);
986 ASSERT_SAVED_ORIGINS(buf
)
989 void test_getrlimit() {
991 dfsan_set_label(i_label
, &rlim
, sizeof(rlim
));
992 DEFINE_AND_SAVE_ORIGINS(rlim
);
993 int ret
= getrlimit(RLIMIT_CPU
, &rlim
);
995 ASSERT_ZERO_LABEL(ret
);
996 ASSERT_READ_ZERO_LABEL(&rlim
, sizeof(rlim
));
997 ASSERT_SAVED_ORIGINS(rlim
)
1000 void test_getrusage() {
1001 struct rusage usage
;
1002 dfsan_set_label(i_label
, &usage
, sizeof(usage
));
1003 DEFINE_AND_SAVE_ORIGINS(usage
);
1004 int ret
= getrusage(RUSAGE_SELF
, &usage
);
1006 ASSERT_ZERO_LABEL(ret
);
1007 ASSERT_READ_ZERO_LABEL(&usage
, sizeof(usage
));
1008 ASSERT_SAVED_ORIGINS(usage
)
1011 void test_strcpy() {
1012 char src
[] = "hello world";
1013 char dst
[sizeof(src
) + 2];
1015 dfsan_set_label(0, src
, sizeof(src
));
1016 dfsan_set_label(0, dst
, sizeof(dst
));
1017 dfsan_set_label(k_label
, &p_dst
, sizeof(p_dst
));
1018 dfsan_set_label(i_label
, src
+ 2, 1);
1019 dfsan_set_label(j_label
, src
+ 3, 1);
1020 dfsan_set_label(j_label
, dst
+ 4, 1);
1021 dfsan_set_label(i_label
, dst
+ 12, 1);
1022 char *ret
= strcpy(p_dst
, src
);
1024 assert(strcmp(src
, dst
) == 0);
1025 ASSERT_LABEL(ret
, k_label
);
1026 ASSERT_EQ_ORIGIN(ret
, p_dst
);
1027 for (int i
= 0; i
< strlen(src
) + 1; ++i
) {
1028 assert(dfsan_get_label(dst
[i
]) == dfsan_get_label(src
[i
]));
1029 if (dfsan_get_label(dst
[i
]))
1030 assert(dfsan_get_init_origin(&dst
[i
]) == dfsan_get_origin(src
[i
]));
1032 // Note: if strlen(src) + 1 were used instead to compute the first untouched
1033 // byte of dest, the label would be I|J. This is because strlen() might
1034 // return a non-zero label, and because by default pointer labels are not
1035 // ignored on loads.
1036 ASSERT_LABEL(dst
[12], i_label
);
1039 void test_strtol() {
1040 char non_number_buf
[] = "ab ";
1041 char *endptr
= NULL
;
1042 long int ret
= strtol(non_number_buf
, &endptr
, 10);
1044 assert(endptr
== non_number_buf
);
1045 ASSERT_ZERO_LABEL(ret
);
1047 char buf
[] = "1234578910";
1049 dfsan_set_label(k_label
, &base
, sizeof(base
));
1050 ret
= strtol(buf
, &endptr
, base
);
1051 assert(ret
== 1234578910);
1052 assert(endptr
== buf
+ 10);
1053 ASSERT_LABEL(ret
, k_label
);
1054 ASSERT_EQ_ORIGIN(ret
, base
);
1056 dfsan_set_label(i_label
, buf
+ 1, 1);
1057 dfsan_set_label(j_label
, buf
+ 10, 1);
1058 ret
= strtol(buf
, &endptr
, 10);
1059 assert(ret
== 1234578910);
1060 assert(endptr
== buf
+ 10);
1061 ASSERT_LABEL(ret
, i_j_label
);
1062 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1065 void test_strtoll() {
1066 char non_number_buf
[] = "ab ";
1067 char *endptr
= NULL
;
1068 long long int ret
= strtoll(non_number_buf
, &endptr
, 10);
1070 assert(endptr
== non_number_buf
);
1071 ASSERT_ZERO_LABEL(ret
);
1073 char buf
[] = "1234578910 ";
1075 dfsan_set_label(k_label
, &base
, sizeof(base
));
1076 ret
= strtoll(buf
, &endptr
, base
);
1077 assert(ret
== 1234578910);
1078 assert(endptr
== buf
+ 10);
1079 ASSERT_LABEL(ret
, k_label
);
1080 ASSERT_EQ_ORIGIN(ret
, base
);
1082 dfsan_set_label(i_label
, buf
+ 1, 1);
1083 dfsan_set_label(j_label
, buf
+ 2, 1);
1084 ret
= strtoll(buf
, &endptr
, 10);
1085 assert(ret
== 1234578910);
1086 assert(endptr
== buf
+ 10);
1087 ASSERT_LABEL(ret
, i_j_label
);
1088 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1091 void test_strtoul() {
1092 char non_number_buf
[] = "xy ";
1093 char *endptr
= NULL
;
1094 long unsigned int ret
= strtoul(non_number_buf
, &endptr
, 16);
1096 assert(endptr
== non_number_buf
);
1097 ASSERT_ZERO_LABEL(ret
);
1099 char buf
[] = "ffffffffffffaa";
1101 dfsan_set_label(k_label
, &base
, sizeof(base
));
1102 ret
= strtoul(buf
, &endptr
, base
);
1103 assert(ret
== 72057594037927850);
1104 assert(endptr
== buf
+ 14);
1105 ASSERT_LABEL(ret
, k_label
);
1106 ASSERT_EQ_ORIGIN(ret
, base
);
1108 dfsan_set_label(i_label
, buf
+ 1, 1);
1109 dfsan_set_label(j_label
, buf
+ 2, 1);
1110 ret
= strtoul(buf
, &endptr
, 16);
1111 assert(ret
== 72057594037927850);
1112 assert(endptr
== buf
+ 14);
1113 ASSERT_LABEL(ret
, i_j_label
);
1114 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1117 void test_strtoull() {
1118 char non_number_buf
[] = "xy ";
1119 char *endptr
= NULL
;
1120 long long unsigned int ret
= strtoull(non_number_buf
, &endptr
, 16);
1122 assert(endptr
== non_number_buf
);
1123 ASSERT_ZERO_LABEL(ret
);
1125 char buf
[] = "ffffffffffffffaa";
1127 dfsan_set_label(k_label
, &base
, sizeof(base
));
1128 ret
= strtoull(buf
, &endptr
, base
);
1129 assert(ret
== 0xffffffffffffffaa);
1130 assert(endptr
== buf
+ 16);
1131 ASSERT_LABEL(ret
, k_label
);
1132 ASSERT_EQ_ORIGIN(ret
, base
);
1134 dfsan_set_label(i_label
, buf
+ 1, 1);
1135 dfsan_set_label(j_label
, buf
+ 2, 1);
1136 ret
= strtoull(buf
, &endptr
, 16);
1137 assert(ret
== 0xffffffffffffffaa);
1138 assert(endptr
== buf
+ 16);
1139 ASSERT_LABEL(ret
, i_j_label
);
1140 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1143 void test_strtod() {
1144 char non_number_buf
[] = "ab ";
1145 char *endptr
= NULL
;
1146 double ret
= strtod(non_number_buf
, &endptr
);
1148 assert(endptr
== non_number_buf
);
1149 ASSERT_ZERO_LABEL(ret
);
1151 char buf
[] = "12345.76 foo";
1152 dfsan_set_label(i_label
, buf
+ 1, 1);
1153 dfsan_set_label(j_label
, buf
+ 6, 1);
1154 ret
= strtod(buf
, &endptr
);
1155 assert(ret
== 12345.76);
1156 assert(endptr
== buf
+ 8);
1157 ASSERT_LABEL(ret
, i_j_label
);
1158 ASSERT_EQ_ORIGIN(ret
, buf
[1]);
1163 dfsan_set_label(i_label
, &t
, 1);
1164 DEFINE_AND_SAVE_ORIGINS(t
)
1165 time_t ret
= time(&t
);
1168 ASSERT_ZERO_LABEL(ret
);
1169 ASSERT_ZERO_LABEL(t
);
1170 ASSERT_SAVED_ORIGINS(t
)
1173 void test_inet_pton() {
1174 char addr4
[] = "127.0.0.1";
1175 dfsan_set_label(i_label
, addr4
+ 3, 1);
1177 int ret4
= inet_pton(AF_INET
, addr4
, &in4
);
1179 ASSERT_ZERO_LABEL(ret4
);
1180 ASSERT_READ_LABEL(&in4
, sizeof(in4
), i_label
);
1181 ASSERT_ORIGINS(&in4
, sizeof(in4
), dfsan_get_origin((long)(addr4
[3])))
1182 assert(in4
.s_addr
== htonl(0x7f000001));
1184 char addr6
[] = "::1";
1185 dfsan_set_label(j_label
, addr6
+ 3, 1);
1186 struct in6_addr in6
;
1187 int ret6
= inet_pton(AF_INET6
, addr6
, &in6
);
1189 ASSERT_ZERO_LABEL(ret6
);
1190 ASSERT_READ_LABEL(((char *) &in6
) + sizeof(in6
) - 1, 1, j_label
);
1191 ASSERT_ORIGINS(&in6
, sizeof(in6
), dfsan_get_origin((long)(addr6
[3])))
1194 void test_localtime_r() {
1195 time_t t0
= 1384800998;
1197 dfsan_set_label(i_label
, &t0
, sizeof(t0
));
1198 dfsan_origin t0_o
= dfsan_get_origin((long)t0
);
1199 struct tm
*pt1
= &t1
;
1200 dfsan_set_label(j_label
, &pt1
, sizeof(pt1
));
1201 dfsan_origin pt1_o
= dfsan_get_origin((long)pt1
);
1203 #ifndef ORIGIN_TRACKING
1208 struct tm
*ret
= localtime_r(&t0
, pt1
);
1210 assert(t1
.tm_min
== 56);
1211 ASSERT_LABEL(ret
, j_label
);
1212 ASSERT_INIT_ORIGIN(&ret
, pt1_o
);
1213 ASSERT_READ_LABEL(&ret
, sizeof(ret
), j_label
);
1214 ASSERT_LABEL(t1
.tm_mon
, i_label
);
1215 ASSERT_ORIGIN(t1
.tm_mon
, t0_o
);
1218 void test_getpwuid_r() {
1221 struct passwd
*result
;
1223 dfsan_set_label(i_label
, &pwd
, 4);
1224 DEFINE_AND_SAVE_ORIGINS(pwd
)
1225 DEFINE_AND_SAVE_ORIGINS(buf
)
1226 int ret
= getpwuid_r(0, &pwd
, buf
, sizeof(buf
), &result
);
1228 assert(strcmp(pwd
.pw_name
, "root") == 0);
1229 assert(result
== &pwd
);
1230 ASSERT_ZERO_LABEL(ret
);
1231 ASSERT_READ_ZERO_LABEL(&pwd
, 4);
1232 ASSERT_SAVED_ORIGINS(pwd
)
1233 ASSERT_SAVED_ORIGINS(buf
)
1236 void test_epoll_wait() {
1237 // Set up a pipe to monitor with epoll.
1239 int ret
= pipe(pipe_fds
);
1242 // Configure epoll to monitor the pipe.
1243 int epfd
= epoll_create1(0);
1245 struct epoll_event event
;
1246 event
.events
= EPOLLIN
;
1247 event
.data
.fd
= pipe_fds
[0];
1248 ret
= epoll_ctl(epfd
, EPOLL_CTL_ADD
, pipe_fds
[0], &event
);
1251 // Test epoll_wait when no events have occurred.
1253 dfsan_set_label(i_label
, &event
, sizeof(event
));
1254 DEFINE_AND_SAVE_ORIGINS(event
)
1255 ret
= epoll_wait(epfd
, &event
, /*maxevents=*/1, /*timeout=*/0);
1257 assert(event
.events
== 0);
1258 assert(event
.data
.fd
== 0);
1259 ASSERT_ZERO_LABEL(ret
);
1260 ASSERT_READ_LABEL(&event
, sizeof(event
), i_label
);
1261 ASSERT_SAVED_ORIGINS(event
)
1263 // Test epoll_wait when an event occurs.
1264 write(pipe_fds
[1], "x", 1);
1265 ret
= epoll_wait(epfd
, &event
, /*maxevents=*/1, /*timeout=*/0);
1267 assert(event
.events
== EPOLLIN
);
1268 assert(event
.data
.fd
== pipe_fds
[0]);
1269 ASSERT_ZERO_LABEL(ret
);
1270 ASSERT_READ_ZERO_LABEL(&event
, sizeof(event
));
1271 ASSERT_SAVED_ORIGINS(event
)
1283 dfsan_set_label(i_label
, &fd
.revents
, sizeof(fd
.revents
));
1284 DEFINE_AND_SAVE_ORIGINS(fd
)
1285 int ret
= poll(&fd
, 1, 1);
1286 ASSERT_ZERO_LABEL(ret
);
1287 ASSERT_ZERO_LABEL(fd
.revents
);
1288 ASSERT_SAVED_ORIGINS(fd
)
1292 void test_select() {
1297 dfsan_set_label(i_label
, &fds
, sizeof(fds
));
1298 dfsan_set_label(j_label
, &t
, sizeof(t
));
1299 DEFINE_AND_SAVE_ORIGINS(fds
)
1300 DEFINE_AND_SAVE_ORIGINS(t
)
1301 int ret
= select(1, &fds
, NULL
, NULL
, &t
);
1303 ASSERT_ZERO_LABEL(ret
);
1304 ASSERT_ZERO_LABEL(t
.tv_sec
);
1305 ASSERT_READ_ZERO_LABEL(&fds
, sizeof(fds
));
1306 ASSERT_SAVED_ORIGINS(fds
)
1307 ASSERT_SAVED_ORIGINS(t
)
1310 void test_sched_getaffinity() {
1312 dfsan_set_label(j_label
, &mask
, 1);
1313 DEFINE_AND_SAVE_ORIGINS(mask
)
1314 int ret
= sched_getaffinity(0, sizeof(mask
), &mask
);
1316 ASSERT_ZERO_LABEL(ret
);
1317 ASSERT_READ_ZERO_LABEL(&mask
, sizeof(mask
));
1318 ASSERT_SAVED_ORIGINS(mask
)
1321 void test_sigemptyset() {
1323 dfsan_set_label(j_label
, &set
, 1);
1324 DEFINE_AND_SAVE_ORIGINS(set
)
1325 int ret
= sigemptyset(&set
);
1327 ASSERT_ZERO_LABEL(ret
);
1328 ASSERT_READ_ZERO_LABEL(&set
, sizeof(set
));
1329 ASSERT_SAVED_ORIGINS(set
)
1332 static void SignalHandler(int signo
) {}
1334 static void SignalAction(int signo
, siginfo_t
*si
, void *uc
) {}
1336 void test_sigaction() {
1337 struct sigaction newact_with_sigaction
= {};
1338 newact_with_sigaction
.sa_flags
= SA_SIGINFO
;
1339 newact_with_sigaction
.sa_sigaction
= SignalAction
;
1341 // Set sigaction to be SignalAction, save the last one into origin_act
1342 struct sigaction origin_act
;
1343 dfsan_set_label(j_label
, &origin_act
, 1);
1344 DEFINE_AND_SAVE_ORIGINS(origin_act
)
1345 int ret
= sigaction(SIGUSR1
, &newact_with_sigaction
, &origin_act
);
1347 ASSERT_ZERO_LABEL(ret
);
1348 ASSERT_READ_ZERO_LABEL(&origin_act
, sizeof(origin_act
));
1349 ASSERT_SAVED_ORIGINS(origin_act
)
1351 struct sigaction newact_with_sighandler
= {};
1352 newact_with_sighandler
.sa_handler
= SignalHandler
;
1354 // Set sigaction to be SignalHandler, check the last one is SignalAction
1355 struct sigaction oldact
;
1356 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1357 assert(oldact
.sa_sigaction
== SignalAction
);
1358 assert(oldact
.sa_flags
& SA_SIGINFO
);
1360 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1361 newact_with_sighandler
.sa_handler
= SIG_IGN
;
1362 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1363 assert(oldact
.sa_handler
== SignalHandler
);
1364 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1366 newact_with_sighandler
.sa_handler
= SIG_DFL
;
1367 assert(0 == sigaction(SIGUSR1
, &newact_with_sighandler
, &oldact
));
1368 assert(oldact
.sa_handler
== SIG_IGN
);
1369 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1371 // Restore sigaction to the orginal setting, check the last one is SignalHandler
1372 assert(0 == sigaction(SIGUSR1
, &origin_act
, &oldact
));
1373 assert(oldact
.sa_handler
== SIG_DFL
);
1374 assert((oldact
.sa_flags
& SA_SIGINFO
) == 0);
1377 void test_signal() {
1378 // Set signal to be SignalHandler, save the previous one into
1379 // old_signal_handler.
1380 sighandler_t old_signal_handler
= signal(SIGHUP
, SignalHandler
);
1381 ASSERT_ZERO_LABEL(old_signal_handler
);
1383 // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1384 assert(SignalHandler
== signal(SIGHUP
, SIG_DFL
));
1385 assert(SIG_DFL
== signal(SIGHUP
, SIG_IGN
));
1387 // Restore signal to old_signal_handler.
1388 assert(SIG_IGN
== signal(SIGHUP
, old_signal_handler
));
1391 void test_sigaltstack() {
1392 stack_t old_altstack
= {};
1393 dfsan_set_label(j_label
, &old_altstack
, sizeof(old_altstack
));
1394 DEFINE_AND_SAVE_ORIGINS(old_altstack
)
1395 int ret
= sigaltstack(NULL
, &old_altstack
);
1397 ASSERT_ZERO_LABEL(ret
);
1398 ASSERT_READ_ZERO_LABEL(&old_altstack
, sizeof(old_altstack
));
1399 ASSERT_SAVED_ORIGINS(old_altstack
)
1402 void test_gettimeofday() {
1405 dfsan_set_label(i_label
, &tv
, sizeof(tv
));
1406 dfsan_set_label(j_label
, &tz
, sizeof(tz
));
1407 DEFINE_AND_SAVE_ORIGINS(tv
)
1408 DEFINE_AND_SAVE_ORIGINS(tz
)
1409 int ret
= gettimeofday(&tv
, &tz
);
1411 ASSERT_READ_ZERO_LABEL(&tv
, sizeof(tv
));
1412 ASSERT_READ_ZERO_LABEL(&tz
, sizeof(tz
));
1413 ASSERT_SAVED_ORIGINS(tv
)
1414 ASSERT_SAVED_ORIGINS(tz
)
1417 void *pthread_create_test_cb(void *p
) {
1418 assert(p
== (void *)1);
1419 ASSERT_ZERO_LABEL(p
);
1423 void test_pthread_create() {
1425 int create_ret
= pthread_create(&pt
, 0, pthread_create_test_cb
, (void *)1);
1426 assert(create_ret
== 0);
1427 ASSERT_ZERO_LABEL(create_ret
);
1429 dfsan_set_label(i_label
, &cbrv
, sizeof(cbrv
));
1430 DEFINE_AND_SAVE_ORIGINS(cbrv
)
1431 int joint_ret
= pthread_join(pt
, &cbrv
);
1432 assert(joint_ret
== 0);
1433 assert(cbrv
== (void *)2);
1434 ASSERT_ZERO_LABEL(joint_ret
);
1435 ASSERT_ZERO_LABEL(cbrv
);
1436 ASSERT_SAVED_ORIGINS(cbrv
);
1439 // Tested by test_pthread_create(). This empty function is here to appease the
1440 // check-wrappers script.
1441 void test_pthread_join() {}
1443 int dl_iterate_phdr_test_cb(struct dl_phdr_info
*info
, size_t size
,
1445 assert(data
== (void *)3);
1446 ASSERT_ZERO_LABEL(info
);
1447 ASSERT_ZERO_LABEL(size
);
1448 ASSERT_ZERO_LABEL(data
);
1452 void test_dl_iterate_phdr() {
1453 dl_iterate_phdr(dl_iterate_phdr_test_cb
, (void *)3);
1456 // On glibc < 2.27, this symbol is not available. Mark it weak so we can skip
1457 // testing in this case.
1458 __attribute__((weak
)) extern "C" void _dl_get_tls_static_info(size_t *sizep
,
1461 void test__dl_get_tls_static_info() {
1462 if (!_dl_get_tls_static_info
)
1464 size_t sizep
= 0, alignp
= 0;
1465 dfsan_set_label(i_label
, &sizep
, sizeof(sizep
));
1466 dfsan_set_label(i_label
, &alignp
, sizeof(alignp
));
1467 dfsan_origin sizep_o
= dfsan_get_origin(sizep
);
1468 dfsan_origin alignp_o
= dfsan_get_origin(alignp
);
1469 #ifndef ORIGIN_TRACKING
1473 _dl_get_tls_static_info(&sizep
, &alignp
);
1474 ASSERT_ZERO_LABEL(sizep
);
1475 ASSERT_ZERO_LABEL(alignp
);
1476 ASSERT_ORIGIN(sizep
, sizep_o
);
1477 ASSERT_ORIGIN(alignp
, alignp_o
);
1480 void test_strrchr() {
1481 char str1
[] = "str1str1";
1484 dfsan_set_label(j_label
, &p
, sizeof(p
));
1486 char *rv
= strrchr(p
, 'r');
1487 assert(rv
== &str1
[6]);
1488 ASSERT_LABEL(rv
, j_label
);
1489 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p
);
1492 dfsan_set_label(k_label
, &c
, sizeof(c
));
1493 rv
= strrchr(str1
, c
);
1494 assert(rv
== &str1
[6]);
1495 #ifdef STRICT_DATA_DEPENDENCIES
1496 ASSERT_ZERO_LABEL(rv
);
1498 ASSERT_LABEL(rv
, k_label
);
1499 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, c
);
1502 dfsan_set_label(i_label
, &str1
[7], 1);
1504 rv
= strrchr(str1
, 'r');
1505 assert(rv
== &str1
[6]);
1506 #ifdef STRICT_DATA_DEPENDENCIES
1507 ASSERT_ZERO_LABEL(rv
);
1509 ASSERT_LABEL(rv
, i_label
);
1510 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[7]);
1514 void test_strstr() {
1515 char str1
[] = "str1str1";
1518 dfsan_set_label(k_label
, &p1
, sizeof(p1
));
1519 char *rv
= strstr(p1
, "1s");
1520 assert(rv
== &str1
[3]);
1521 ASSERT_LABEL(rv
, k_label
);
1522 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p1
);
1526 dfsan_set_label(m_label
, &p2
, sizeof(p2
));
1527 rv
= strstr(str1
, p2
);
1528 assert(rv
== &str1
[3]);
1529 #ifdef STRICT_DATA_DEPENDENCIES
1530 ASSERT_ZERO_LABEL(rv
);
1532 ASSERT_LABEL(rv
, m_label
);
1533 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p2
);
1536 dfsan_set_label(n_label
, &str2
[0], 1);
1537 rv
= strstr(str1
, str2
);
1538 assert(rv
== &str1
[3]);
1539 #ifdef STRICT_DATA_DEPENDENCIES
1540 ASSERT_ZERO_LABEL(rv
);
1542 ASSERT_LABEL(rv
, n_label
);
1543 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str2
[0]);
1546 dfsan_set_label(i_label
, &str1
[3], 1);
1547 dfsan_set_label(j_label
, &str1
[5], 1);
1549 rv
= strstr(str1
, "1s");
1550 assert(rv
== &str1
[3]);
1551 #ifdef STRICT_DATA_DEPENDENCIES
1552 ASSERT_ZERO_LABEL(rv
);
1554 ASSERT_LABEL(rv
, i_label
);
1555 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[3]);
1558 rv
= strstr(str1
, "2s");
1560 #ifdef STRICT_DATA_DEPENDENCIES
1561 ASSERT_ZERO_LABEL(rv
);
1563 ASSERT_LABEL(rv
, i_j_label
);
1564 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, str1
[3]);
1568 void test_strpbrk() {
1569 char s
[] = "abcdefg";
1570 char accept
[] = "123fd";
1573 char *p_accept
= accept
;
1575 dfsan_set_label(n_label
, &p_accept
, sizeof(p_accept
));
1577 char *rv
= strpbrk(p_s
, p_accept
);
1578 assert(rv
== &s
[3]);
1579 #ifdef STRICT_DATA_DEPENDENCIES
1580 ASSERT_ZERO_LABEL(rv
);
1582 ASSERT_LABEL(rv
, n_label
);
1583 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_accept
);
1586 dfsan_set_label(m_label
, &p_s
, sizeof(p_s
));
1588 rv
= strpbrk(p_s
, p_accept
);
1589 assert(rv
== &s
[3]);
1590 #ifdef STRICT_DATA_DEPENDENCIES
1591 ASSERT_LABEL(rv
, m_label
);
1592 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_s
);
1594 ASSERT_LABEL(rv
, dfsan_union(m_label
, n_label
));
1595 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, p_s
);
1598 dfsan_set_label(i_label
, &s
[5], 1);
1599 dfsan_set_label(j_label
, &accept
[1], 1);
1601 rv
= strpbrk(s
, accept
);
1602 assert(rv
== &s
[3]);
1603 #ifdef STRICT_DATA_DEPENDENCIES
1604 ASSERT_ZERO_LABEL(rv
);
1606 ASSERT_LABEL(rv
, j_label
);
1607 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, accept
[1]);
1611 dfsan_set_label(j_label
, &ps
, sizeof(ps
));
1613 rv
= strpbrk(ps
, "123gf");
1614 assert(rv
== &s
[5]);
1615 #ifdef STRICT_DATA_DEPENDENCIES
1616 ASSERT_LABEL(rv
, j_label
);
1618 ASSERT_LABEL(rv
, i_j_label
);
1619 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, s
[5]);
1622 rv
= strpbrk(ps
, "123");
1624 #ifdef STRICT_DATA_DEPENDENCIES
1625 ASSERT_ZERO_LABEL(rv
);
1627 ASSERT_LABEL(rv
, i_j_label
);
1628 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv
, s
[5]);
1632 void test_memchr() {
1633 char str1
[] = "str1";
1634 dfsan_set_label(i_label
, &str1
[3], 1);
1635 dfsan_set_label(j_label
, &str1
[4], 1);
1637 char *crv
= (char *) memchr(str1
, 'r', sizeof(str1
));
1638 assert(crv
== &str1
[2]);
1639 ASSERT_ZERO_LABEL(crv
);
1642 dfsan_set_label(k_label
, &c
, sizeof(c
));
1643 crv
= (char *)memchr(str1
, c
, sizeof(str1
));
1644 assert(crv
== &str1
[2]);
1645 #ifdef STRICT_DATA_DEPENDENCIES
1646 ASSERT_ZERO_LABEL(crv
);
1648 ASSERT_LABEL(crv
, k_label
);
1649 ASSERT_EQ_ORIGIN(crv
, c
);
1653 dfsan_set_label(k_label
, &ptr
, sizeof(ptr
));
1654 crv
= (char *)memchr(ptr
, 'r', sizeof(str1
));
1655 assert(crv
== &str1
[2]);
1656 ASSERT_LABEL(crv
, k_label
);
1657 ASSERT_EQ_ORIGIN(crv
, ptr
);
1659 crv
= (char *) memchr(str1
, '1', sizeof(str1
));
1660 assert(crv
== &str1
[3]);
1661 #ifdef STRICT_DATA_DEPENDENCIES
1662 ASSERT_ZERO_LABEL(crv
);
1664 ASSERT_LABEL(crv
, i_label
);
1665 ASSERT_EQ_ORIGIN(crv
, str1
[3]);
1668 crv
= (char *) memchr(str1
, 'x', sizeof(str1
));
1670 #ifdef STRICT_DATA_DEPENDENCIES
1671 ASSERT_ZERO_LABEL(crv
);
1673 ASSERT_LABEL(crv
, i_j_label
);
1674 ASSERT_EQ_ORIGIN(crv
, str1
[3]);
1678 void alarm_handler(int unused
) {
1682 void test_nanosleep() {
1683 struct timespec req
, rem
;
1686 dfsan_set_label(i_label
, &rem
, sizeof(rem
));
1687 DEFINE_AND_SAVE_ORIGINS(rem
)
1690 int rv
= nanosleep(&req
, &rem
);
1692 ASSERT_ZERO_LABEL(rv
);
1693 ASSERT_READ_LABEL(&rem
, 1, i_label
);
1694 ASSERT_SAVED_ORIGINS(rem
)
1696 // interrupted by an alarm
1697 signal(SIGALRM
, alarm_handler
);
1700 rv
= nanosleep(&req
, &rem
);
1702 ASSERT_ZERO_LABEL(rv
);
1703 ASSERT_READ_ZERO_LABEL(&rem
, sizeof(rem
));
1704 ASSERT_SAVED_ORIGINS(rem
)
1707 void test_socketpair() {
1709 dfsan_origin fd_o
[2];
1711 dfsan_set_label(i_label
, fd
, sizeof(fd
));
1712 fd_o
[0] = dfsan_get_origin((long)(fd
[0]));
1713 fd_o
[1] = dfsan_get_origin((long)(fd
[1]));
1714 int rv
= socketpair(PF_LOCAL
, SOCK_STREAM
, 0, fd
);
1716 ASSERT_ZERO_LABEL(rv
);
1717 ASSERT_READ_ZERO_LABEL(fd
, sizeof(fd
));
1718 ASSERT_ORIGIN(fd
[0], fd_o
[0]);
1719 ASSERT_ORIGIN(fd
[1], fd_o
[1]);
1722 void test_getpeername() {
1724 int ret
= socketpair(AF_UNIX
, SOCK_DGRAM
, 0, sockfds
);
1727 struct sockaddr addr
= {};
1728 socklen_t addrlen
= sizeof(addr
);
1729 dfsan_set_label(i_label
, &addr
, addrlen
);
1730 dfsan_set_label(i_label
, &addrlen
, sizeof(addrlen
));
1731 DEFINE_AND_SAVE_ORIGINS(addr
)
1732 DEFINE_AND_SAVE_ORIGINS(addrlen
)
1734 ret
= getpeername(sockfds
[0], &addr
, &addrlen
);
1736 ASSERT_ZERO_LABEL(ret
);
1737 ASSERT_ZERO_LABEL(addrlen
);
1738 assert(addrlen
< sizeof(addr
));
1739 ASSERT_READ_ZERO_LABEL(&addr
, addrlen
);
1740 ASSERT_READ_LABEL(((char *)&addr
) + addrlen
, 1, i_label
);
1741 ASSERT_SAVED_ORIGINS(addr
)
1742 ASSERT_SAVED_ORIGINS(addrlen
)
1748 void test_getsockname() {
1749 int sockfd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
1750 assert(sockfd
!= -1);
1752 struct sockaddr addr
= {};
1753 socklen_t addrlen
= sizeof(addr
);
1754 dfsan_set_label(i_label
, &addr
, addrlen
);
1755 dfsan_set_label(i_label
, &addrlen
, sizeof(addrlen
));
1756 DEFINE_AND_SAVE_ORIGINS(addr
)
1757 DEFINE_AND_SAVE_ORIGINS(addrlen
)
1758 int ret
= getsockname(sockfd
, &addr
, &addrlen
);
1760 ASSERT_ZERO_LABEL(ret
);
1761 ASSERT_ZERO_LABEL(addrlen
);
1762 assert(addrlen
< sizeof(addr
));
1763 ASSERT_READ_ZERO_LABEL(&addr
, addrlen
);
1764 ASSERT_READ_LABEL(((char *)&addr
) + addrlen
, 1, i_label
);
1765 ASSERT_SAVED_ORIGINS(addr
)
1766 ASSERT_SAVED_ORIGINS(addrlen
)
1771 void test_getsockopt() {
1772 int sockfd
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
1773 assert(sockfd
!= -1);
1775 int optval
[2] = {-1, -1};
1776 socklen_t optlen
= sizeof(optval
);
1777 dfsan_set_label(i_label
, &optval
, sizeof(optval
));
1778 dfsan_set_label(i_label
, &optlen
, sizeof(optlen
));
1779 DEFINE_AND_SAVE_ORIGINS(optval
)
1780 DEFINE_AND_SAVE_ORIGINS(optlen
)
1781 int ret
= getsockopt(sockfd
, SOL_SOCKET
, SO_KEEPALIVE
, &optval
, &optlen
);
1783 assert(optlen
== sizeof(int));
1784 assert(optval
[0] == 0);
1785 assert(optval
[1] == -1);
1786 ASSERT_ZERO_LABEL(ret
);
1787 ASSERT_ZERO_LABEL(optlen
);
1788 ASSERT_ZERO_LABEL(optval
[0]);
1789 ASSERT_LABEL(optval
[1], i_label
);
1790 ASSERT_SAVED_ORIGINS(optval
)
1791 ASSERT_SAVED_ORIGINS(optlen
)
1797 int fd
= open("/dev/null", O_WRONLY
);
1799 char buf
[] = "a string";
1800 int len
= strlen(buf
);
1802 // The result of a write always unlabeled.
1803 int res
= write(fd
, buf
, len
);
1805 ASSERT_ZERO_LABEL(res
);
1807 // Label all arguments to write().
1808 dfsan_set_label(i_label
, &(buf
[3]), 1);
1809 dfsan_set_label(j_label
, &fd
, sizeof(fd
));
1810 dfsan_set_label(k_label
, &len
, sizeof(len
));
1812 // The value returned by write() should have no label.
1813 res
= write(fd
, buf
, len
);
1814 ASSERT_ZERO_LABEL(res
);
1820 void test_sprintf_chunk(const char* expected
, const char* format
, T arg
) {
1822 memset(buf
, 'a', sizeof(buf
));
1824 char padded_expected
[512];
1825 strcpy(padded_expected
, "foo ");
1826 strcat(padded_expected
, expected
);
1827 strcat(padded_expected
, " bar");
1829 char padded_format
[512];
1830 strcpy(padded_format
, "foo ");
1831 strcat(padded_format
, format
);
1832 strcat(padded_format
, " bar");
1834 // Non labelled arg.
1835 assert(sprintf(buf
, padded_format
, arg
) == strlen(padded_expected
));
1836 assert(strcmp(buf
, padded_expected
) == 0);
1837 ASSERT_READ_LABEL(buf
, strlen(padded_expected
), 0);
1838 memset(buf
, 'a', sizeof(buf
));
1841 dfsan_set_label(i_label
, &arg
, sizeof(arg
));
1842 dfsan_origin a_o
= dfsan_get_origin((long)(arg
));
1843 #ifndef ORIGIN_TRACKING
1846 assert(sprintf(buf
, padded_format
, arg
) == strlen(padded_expected
));
1847 assert(strcmp(buf
, padded_expected
) == 0);
1848 ASSERT_READ_LABEL(buf
, 4, 0);
1849 ASSERT_READ_LABEL(buf
+ 4, strlen(padded_expected
) - 8, i_label
);
1850 ASSERT_INIT_ORIGINS(buf
+ 4, strlen(padded_expected
) - 8, a_o
);
1851 ASSERT_READ_LABEL(buf
+ (strlen(padded_expected
) - 4), 4, 0);
1854 void test_sprintf() {
1856 memset(buf
, 'a', sizeof(buf
));
1858 // Test formatting (no conversion specifier).
1859 assert(sprintf(buf
, "Hello world!") == 12);
1860 assert(strcmp(buf
, "Hello world!") == 0);
1861 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
1863 // Test for extra arguments.
1864 assert(sprintf(buf
, "Hello world!", 42, "hello") == 12);
1865 assert(strcmp(buf
, "Hello world!") == 0);
1866 ASSERT_READ_LABEL(buf
, sizeof(buf
), 0);
1868 // Test formatting & label propagation (multiple conversion specifiers): %s,
1869 // %d, %n, %f, and %%.
1870 const char* s
= "world";
1873 dfsan_set_label(k_label
, (void *) (s
+ 1), 2);
1874 dfsan_origin s_o
= dfsan_get_origin((long)(s
[1]));
1875 dfsan_set_label(i_label
, &m
, sizeof(m
));
1876 dfsan_origin m_o
= dfsan_get_origin((long)m
);
1877 dfsan_set_label(j_label
, &d
, sizeof(d
));
1878 dfsan_origin d_o
= dfsan_get_origin((long)d
);
1879 #ifndef ORIGIN_TRACKING
1885 int r
= sprintf(buf
, "hello %s, %-d/%d/%d %f %% %n%d", s
, 2014, m
, d
,
1886 12345.6781234, &n
, 1000);
1888 assert(strcmp(buf
, "hello world, 2014/8/27 12345.678123 % 1000") == 0);
1889 ASSERT_READ_LABEL(buf
, 7, 0);
1890 ASSERT_READ_LABEL(buf
+ 7, 2, k_label
);
1891 ASSERT_INIT_ORIGINS(buf
+ 7, 2, s_o
);
1892 ASSERT_READ_LABEL(buf
+ 9, 9, 0);
1893 ASSERT_READ_LABEL(buf
+ 18, 1, i_label
);
1894 ASSERT_INIT_ORIGINS(buf
+ 18, 1, m_o
);
1895 ASSERT_READ_LABEL(buf
+ 19, 1, 0);
1896 ASSERT_READ_LABEL(buf
+ 20, 2, j_label
);
1897 ASSERT_INIT_ORIGINS(buf
+ 20, 2, d_o
);
1898 ASSERT_READ_LABEL(buf
+ 22, 15, 0);
1902 // Test formatting & label propagation (single conversion specifier, with
1903 // additional length and precision modifiers).
1904 test_sprintf_chunk("-559038737", "%d", 0xdeadbeef);
1905 test_sprintf_chunk("3735928559", "%u", 0xdeadbeef);
1906 test_sprintf_chunk("12345", "%i", 12345);
1907 test_sprintf_chunk("751", "%o", 0751);
1908 test_sprintf_chunk("babe", "%x", 0xbabe);
1909 test_sprintf_chunk("0000BABE", "%.8X", 0xbabe);
1910 test_sprintf_chunk("-17", "%hhd", 0xdeadbeef);
1911 test_sprintf_chunk("-16657", "%hd", 0xdeadbeef);
1912 test_sprintf_chunk("deadbeefdeadbeef", "%lx", 0xdeadbeefdeadbeef);
1913 test_sprintf_chunk("0xdeadbeefdeadbeef", "%p",
1914 (void *) 0xdeadbeefdeadbeef);
1915 test_sprintf_chunk("18446744073709551615", "%ju", (intmax_t) -1);
1916 test_sprintf_chunk("18446744073709551615", "%zu", (size_t) -1);
1917 test_sprintf_chunk("18446744073709551615", "%tu", (size_t) -1);
1919 test_sprintf_chunk("0x1.f9acffa7eb6bfp-4", "%a", 0.123456);
1920 test_sprintf_chunk("0X1.F9ACFFA7EB6BFP-4", "%A", 0.123456);
1921 test_sprintf_chunk("0.12346", "%.5f", 0.123456);
1922 test_sprintf_chunk("0.123456", "%g", 0.123456);
1923 test_sprintf_chunk("1.234560e-01", "%e", 0.123456);
1924 test_sprintf_chunk("1.234560E-01", "%E", 0.123456);
1925 test_sprintf_chunk("0.1234567891234560", "%.16Lf",
1926 (long double) 0.123456789123456);
1928 test_sprintf_chunk("z", "%c", 'z');
1930 // %n, %s, %d, %f, and %% already tested
1932 // Test formatting with width passed as an argument.
1933 r
= sprintf(buf
, "hi %*d my %*s friend %.*f", 3, 1, 6, "dear", 4, 3.14159265359);
1935 assert(strcmp(buf
, "hi 1 my dear friend 3.1416") == 0);
1938 void test_snprintf() {
1940 memset(buf
, 'a', sizeof(buf
));
1941 dfsan_set_label(0, buf
, sizeof(buf
));
1942 const char* s
= "world";
1946 dfsan_set_label(k_label
, (void *) (s
+ 1), 2);
1947 dfsan_origin s_o
= dfsan_get_origin((long)(s
[1]));
1948 dfsan_set_label(i_label
, &y
, sizeof(y
));
1949 dfsan_origin y_o
= dfsan_get_origin((long)y
);
1950 dfsan_set_label(j_label
, &m
, sizeof(m
));
1951 dfsan_origin m_o
= dfsan_get_origin((long)m
);
1952 #ifndef ORIGIN_TRACKING
1957 int r
= snprintf(buf
, 19, "hello %s, %-d/ %d/%d %f", s
, y
, m
, d
,
1959 // The return value is the number of bytes that would have been written to
1960 // the final string if enough space had been available.
1962 assert(memcmp(buf
, "hello world, 2014/", 19) == 0);
1963 ASSERT_READ_LABEL(buf
, 7, 0);
1964 ASSERT_READ_LABEL(buf
+ 7, 2, k_label
);
1965 ASSERT_INIT_ORIGINS(buf
+ 7, 2, s_o
);
1966 ASSERT_READ_LABEL(buf
+ 9, 4, 0);
1967 ASSERT_READ_LABEL(buf
+ 13, 4, i_label
);
1968 ASSERT_INIT_ORIGINS(buf
+ 13, 4, y_o
);
1969 ASSERT_READ_LABEL(buf
+ 17, 2, 0);
1973 // Tested by a seperate source file. This empty function is here to appease the
1974 // check-wrappers script.
1983 i_j_label
= dfsan_union(i_label
, j_label
);
1984 assert(i_j_label
!= i_label
);
1985 assert(i_j_label
!= j_label
);
1986 assert(i_j_label
!= k_label
);
1988 test__dl_get_tls_static_info();
1990 test_clock_gettime();
1992 test_dfsan_set_write_callback();
1993 test_dl_iterate_phdr();
1999 test_get_current_dir_name();
2009 test_gettimeofday();
2020 test_pthread_create();
2021 test_pthread_join();
2025 test_sched_getaffinity();