[docs] Fix build-docs.sh
[llvm-project.git] / compiler-rt / test / dfsan / custom.cpp
blobe15fb61d4dc47e3872125fd502679504581c726e
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
5 //
6 // Tests custom implementations of various glibc functions.
7 //
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>
15 #include <assert.h>
16 #include <fcntl.h>
17 #include <link.h>
18 #include <poll.h>
19 #include <pthread.h>
20 #include <pwd.h>
21 #include <sched.h>
22 #include <signal.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <strings.h>
28 #include <sys/epoll.h>
29 #include <sys/resource.h>
30 #include <sys/select.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <sys/types.h>
35 #include <time.h>
36 #include <unistd.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)))
60 #else
61 #define ASSERT_ZERO_ORIGIN(data)
62 #endif
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]))); \
69 #else
70 #define ASSERT_ZERO_ORIGINS(ptr, size)
71 #endif
73 #ifdef ORIGIN_TRACKING
74 #define ASSERT_ORIGIN(data, origin) \
75 assert(origin == dfsan_get_origin((long)(data)))
76 #else
77 #define ASSERT_ORIGIN(data, origin)
78 #endif
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]))); \
85 #else
86 #define ASSERT_ORIGINS(ptr, size, origin)
87 #endif
89 #ifdef ORIGIN_TRACKING
90 #define ASSERT_INIT_ORIGIN(ptr, origin) \
91 assert(origin == dfsan_get_init_origin(ptr))
92 #else
93 #define ASSERT_INIT_ORIGIN(ptr, origin)
94 #endif
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))
99 #else
100 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data)
101 #endif
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])); \
108 #else
109 #define ASSERT_INIT_ORIGINS(ptr, size, origin)
110 #endif
112 #ifdef ORIGIN_TRACKING
113 #define ASSERT_EQ_ORIGIN(data1, data2) \
114 assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2)))
115 #else
116 #define ASSERT_EQ_ORIGIN(data1, data2)
117 #endif
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]));
124 #else
125 #define DEFINE_AND_SAVE_ORIGINS(val)
126 #endif
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]));
132 #else
133 #define SAVE_ORIGINS(val)
134 #endif
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]);
140 #else
141 #define ASSERT_SAVED_ORIGINS(val)
142 #endif
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]));
149 #else
150 #define DEFINE_AND_SAVE_N_ORIGINS(val, n)
151 #endif
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]);
157 #else
158 #define ASSERT_SAVED_N_ORIGINS(val, n)
159 #endif
161 #if !defined(__GLIBC_PREREQ)
162 # define __GLIBC_PREREQ(a, b) 0
163 #endif
165 void test_stat() {
166 int i = 1;
167 dfsan_set_label(i_label, &i, sizeof(i));
169 struct stat s;
170 s.st_dev = i;
171 DEFINE_AND_SAVE_ORIGINS(s)
172 int ret = stat("/", &s);
173 assert(0 == ret);
174 ASSERT_ZERO_LABEL(ret);
175 ASSERT_ZERO_LABEL(s.st_dev);
176 ASSERT_SAVED_ORIGINS(s)
178 s.st_dev = i;
179 SAVE_ORIGINS(s)
180 ret = stat("/nonexistent", &s);
181 assert(-1 == ret);
182 ASSERT_ZERO_LABEL(ret);
183 ASSERT_LABEL(s.st_dev, i_label);
184 ASSERT_SAVED_ORIGINS(s)
187 void test_fstat() {
188 int i = 1;
189 dfsan_set_label(i_label, &i, sizeof(i));
191 struct stat s;
192 int fd = open("/dev/zero", O_RDONLY);
193 s.st_dev = i;
194 DEFINE_AND_SAVE_ORIGINS(s)
195 int rv = fstat(fd, &s);
196 assert(0 == rv);
197 ASSERT_ZERO_LABEL(rv);
198 ASSERT_ZERO_LABEL(s.st_dev);
199 ASSERT_SAVED_ORIGINS(s)
202 void test_memcmp() {
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));
208 assert(rv < 0);
209 #ifdef STRICT_DATA_DEPENDENCIES
210 ASSERT_ZERO_LABEL(rv);
211 #else
212 ASSERT_LABEL(rv, i_j_label);
213 ASSERT_EQ_ORIGIN(rv, str1[3]);
214 #endif
216 rv = memcmp(str1, str2, sizeof(str1) - 2);
217 assert(rv == 0);
218 ASSERT_ZERO_LABEL(rv);
221 void test_bcmp() {
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));
227 assert(rv != 0);
228 #ifdef STRICT_DATA_DEPENDENCIES
229 ASSERT_ZERO_LABEL(rv);
230 #else
231 ASSERT_LABEL(rv, i_j_label);
232 ASSERT_EQ_ORIGIN(rv, str1[3]);
233 #endif
235 rv = bcmp(str1, str2, sizeof(str1) - 2);
236 assert(rv == 0);
237 ASSERT_ZERO_LABEL(rv);
240 void test_memcpy() {
241 char str1[] = "str1";
242 char str2[sizeof(str1)];
243 dfsan_set_label(i_label, &str1[3], 1);
245 DEFINE_AND_SAVE_ORIGINS(str1)
247 char *ptr2 = str2;
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]))
259 continue;
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)
270 char *ptr = str + 2;
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]))
282 continue;
283 ASSERT_INIT_ORIGIN(&(ptr[i]), str_o[i]);
287 void test_memset() {
288 char buf[8];
289 int j = 'a';
290 char *ptr = buf;
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');
303 void test_strcmp() {
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);
309 assert(rv < 0);
310 #ifdef STRICT_DATA_DEPENDENCIES
311 ASSERT_ZERO_LABEL(rv);
312 #else
313 ASSERT_LABEL(rv, i_j_label);
314 ASSERT_EQ_ORIGIN(rv, str1[3]);
315 #endif
317 rv = strcmp(str1, str1);
318 assert(rv == 0);
319 #ifdef STRICT_DATA_DEPENDENCIES
320 ASSERT_ZERO_LABEL(rv);
321 ASSERT_ZERO_ORIGIN(rv);
322 #else
323 ASSERT_LABEL(rv, i_label);
324 ASSERT_EQ_ORIGIN(rv, str1[3]);
325 #endif
328 void test_strcat() {
329 char src[] = "world";
330 int volatile x = 0; // buffer to ensure src and dst do not share origins
331 (void)x;
332 char dst[] = "hello \0 ";
333 int volatile y = 0; // buffer to ensure dst and p do not share origins
334 (void)y;
335 char *p = dst;
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]);
340 (void)dst_o;
341 char *ret = strcat(p, src);
342 ASSERT_LABEL(ret, k_label);
343 ASSERT_EQ_ORIGIN(ret, p);
344 assert(ret == dst);
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);
355 } else {
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);
369 void test_strlen() {
370 char str1[] = "str1";
371 dfsan_set_label(i_label, &str1[3], 1);
373 int rv = strlen(str1);
374 assert(rv == 4);
375 #ifdef STRICT_DATA_DEPENDENCIES
376 ASSERT_ZERO_LABEL(rv);
377 #else
378 ASSERT_LABEL(rv, i_label);
379 ASSERT_EQ_ORIGIN(rv, str1[3]);
380 #endif
383 void test_strdup() {
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]))
395 continue;
396 ASSERT_INIT_ORIGIN(&(strd[i]), str1_o[i]);
399 free(strd);
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]);
417 char *p2 = str2;
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
427 // is on by default.
428 #if defined(ORIGIN_TRACKING)
429 ASSERT_ZERO_LABEL(strd[0]);
430 ASSERT_ZERO_LABEL(strd[1]);
431 ASSERT_ZERO_LABEL(strd[2]);
432 #else
433 ASSERT_LABEL(strd[0], j_label);
434 ASSERT_LABEL(strd[1], j_label);
435 ASSERT_LABEL(strd[2], j_label);
436 #endif
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));
445 assert(rv < 0);
446 #ifdef STRICT_DATA_DEPENDENCIES
447 ASSERT_ZERO_LABEL(rv);
448 #else
449 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
450 ASSERT_EQ_ORIGIN(rv, str1[3]);
451 #endif
453 rv = strncmp(str1, str2, 0);
454 assert(rv == 0);
455 ASSERT_ZERO_LABEL(rv);
457 rv = strncmp(str1, str2, 3);
458 assert(rv == 0);
459 ASSERT_ZERO_LABEL(rv);
461 rv = strncmp(str1, str1, 4);
462 assert(rv == 0);
463 #ifdef STRICT_DATA_DEPENDENCIES
464 ASSERT_ZERO_LABEL(rv);
465 #else
466 ASSERT_LABEL(rv, i_label);
467 ASSERT_EQ_ORIGIN(rv, str1[3]);
468 #endif
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);
478 assert(rv < 0);
479 #ifdef STRICT_DATA_DEPENDENCIES
480 ASSERT_ZERO_LABEL(rv);
481 #else
482 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
483 ASSERT_EQ_ORIGIN(rv, str1[3]);
484 #endif
486 rv = strcasecmp(str1, str3);
487 assert(rv == 0);
488 #ifdef STRICT_DATA_DEPENDENCIES
489 ASSERT_ZERO_LABEL(rv);
490 #else
491 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
492 ASSERT_EQ_ORIGIN(rv, str1[3]);
493 #endif
495 char s1[] = "AbZ";
496 char s2[] = "aBy";
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);
504 #else
505 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
506 ASSERT_EQ_ORIGIN(rv, s1[2]);
507 #endif
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));
516 assert(rv < 0);
517 #ifdef STRICT_DATA_DEPENDENCIES
518 ASSERT_ZERO_LABEL(rv);
519 #else
520 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
521 ASSERT_EQ_ORIGIN(rv, str1[3]);
522 #endif
524 rv = strncasecmp(str1, str2, 3);
525 assert(rv == 0);
526 ASSERT_ZERO_LABEL(rv);
528 char s1[] = "AbZ";
529 char s2[] = "aBy";
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);
549 #else
550 ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
551 ASSERT_EQ_ORIGIN(rv, s1[2]);
552 #endif
555 void test_strchr() {
556 char str1[] = "str1";
557 dfsan_set_label(i_label, &str1[3], 1);
559 char *p1 = str1;
560 char c = 'r';
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);
567 #else
568 ASSERT_LABEL(crv, k_label);
569 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, c);
570 #endif
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);
583 #else
584 ASSERT_LABEL(crv, i_j_label);
585 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
586 #endif
588 crv = strchr(p1, 'x');
589 assert(!crv);
590 #ifdef STRICT_DATA_DEPENDENCIES
591 ASSERT_LABEL(crv, j_label);
592 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
593 #else
594 ASSERT_LABEL(crv, i_j_label);
595 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
596 #endif
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);
606 #else
607 ASSERT_LABEL(crv, i_j_label);
608 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
609 #endif
612 void test_recvmmsg() {
613 int sockfds[2];
614 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
615 assert(ret != -1);
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;
628 // Send messages.
629 int sent_msgs = sendmmsg(sockfds[0], smmsg, 2, 0);
630 assert(sent_msgs == 2);
632 // Setup receive buffers.
633 struct mmsghdr rmmsg[2] = {};
634 char rbuf0[128];
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;
638 char rbuf1[128];
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
652 (void)msg_len0_o;
653 (void)msg_len1_o;
654 #endif
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);
676 close(sockfds[0]);
677 close(sockfds[1]);
680 void test_recvmsg() {
681 int sockfds[2];
682 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
683 assert(ret != -1);
685 char sbuf[] = "abcdefghijkl";
686 struct iovec siovs[2] = {{&sbuf[0], 4}, {&sbuf[4], 4}};
687 struct msghdr smsg = {};
688 smsg.msg_iov = siovs;
689 smsg.msg_iovlen = 2;
691 ssize_t sent = sendmsg(sockfds[0], &smsg, 0);
692 assert(sent > 0);
694 char rbuf[128];
695 struct iovec riovs[2] = {{&rbuf[0], 4}, {&rbuf[4], 4}};
696 struct msghdr rmsg = {};
697 rmsg.msg_iov = riovs;
698 rmsg.msg_iovlen = 2;
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)
715 close(sockfds[0]);
716 close(sockfds[1]);
719 void test_read() {
720 char buf[16];
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)
735 close(fd);
738 void test_pread() {
739 char buf[16];
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)
754 close(fd);
757 void test_dlopen() {
758 void *map = dlopen(NULL, RTLD_NOW);
759 assert(map);
760 ASSERT_ZERO_LABEL(map);
761 dlclose(map);
762 map = dlopen("/nonexistent", RTLD_NOW);
763 assert(!map);
764 ASSERT_ZERO_LABEL(map);
767 void test_clock_gettime() {
768 struct timespec tp;
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
772 (void)origin;
773 #endif
774 int t = clock_gettime(CLOCK_REALTIME, &tp);
775 assert(t == 0);
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);
783 time_t t = 0;
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);
790 assert(buf == 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);
802 t = 0;
803 dfsan_set_label(j_label, &buf, sizeof(&buf));
804 dfsan_origin buf_ptr_o = dfsan_get_origin((long)buf);
805 #ifndef ORIGIN_TRACKING
806 (void)buf_ptr_o;
807 #endif
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;
817 static int last_fd;
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++;
824 last_fd = fd;
825 last_buf = (const unsigned char*) buf;
826 last_count = count;
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));
852 last_fd = 0;
853 last_buf = 0;
854 last_count = 0;
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
873 (void)fd_o;
874 (void)b_buf3_o;
875 (void)b_buf_len_o;
876 #endif
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
898 // changed.
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);
911 void test_fgets() {
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);
918 assert(ret == buf);
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)
930 fclose(f);
931 free(buf);
934 void test_getcwd() {
935 char buf[1024];
936 char *ptr = buf;
937 dfsan_set_label(i_label, buf + 2, 2);
938 DEFINE_AND_SAVE_ORIGINS(buf)
940 char* ret = getcwd(buf, sizeof(buf));
941 assert(ret == 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();
957 assert(ret);
958 assert(ret[0] == '/');
959 ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1);
960 ASSERT_ZERO_LABEL(ret);
963 void test_getentropy() {
964 char buf[64];
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);
971 if (ret == 0) {
972 ASSERT_READ_ZERO_LABEL(buf + 2, 2);
973 ASSERT_SAVED_ORIGINS(buf)
975 #endif
978 void test_gethostname() {
979 char buf[1024];
980 dfsan_set_label(i_label, buf + 2, 2);
981 DEFINE_AND_SAVE_ORIGINS(buf)
982 int ret = gethostname(buf, sizeof(buf));
983 assert(ret == 0);
984 ASSERT_ZERO_LABEL(ret);
985 ASSERT_READ_ZERO_LABEL(buf + 2, 2);
986 ASSERT_SAVED_ORIGINS(buf)
989 void test_getrlimit() {
990 struct rlimit rlim;
991 dfsan_set_label(i_label, &rlim, sizeof(rlim));
992 DEFINE_AND_SAVE_ORIGINS(rlim);
993 int ret = getrlimit(RLIMIT_CPU, &rlim);
994 assert(ret == 0);
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);
1005 assert(ret == 0);
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];
1014 char *p_dst = dst;
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);
1023 assert(ret == dst);
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);
1043 assert(ret == 0);
1044 assert(endptr == non_number_buf);
1045 ASSERT_ZERO_LABEL(ret);
1047 char buf[] = "1234578910";
1048 int base = 10;
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);
1069 assert(ret == 0);
1070 assert(endptr == non_number_buf);
1071 ASSERT_ZERO_LABEL(ret);
1073 char buf[] = "1234578910 ";
1074 int base = 10;
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);
1095 assert(ret == 0);
1096 assert(endptr == non_number_buf);
1097 ASSERT_ZERO_LABEL(ret);
1099 char buf[] = "ffffffffffffaa";
1100 int base = 16;
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);
1121 assert(ret == 0);
1122 assert(endptr == non_number_buf);
1123 ASSERT_ZERO_LABEL(ret);
1125 char buf[] = "ffffffffffffffaa";
1126 int base = 16;
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);
1147 assert(ret == 0);
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]);
1161 void test_time() {
1162 time_t t = 0;
1163 dfsan_set_label(i_label, &t, 1);
1164 DEFINE_AND_SAVE_ORIGINS(t)
1165 time_t ret = time(&t);
1166 assert(ret == t);
1167 assert(ret > 0);
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);
1176 struct in_addr in4;
1177 int ret4 = inet_pton(AF_INET, addr4, &in4);
1178 assert(ret4 == 1);
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);
1188 assert(ret6 == 1);
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;
1196 struct tm t1;
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
1204 (void)t0_o;
1205 (void)pt1_o;
1206 #endif
1208 struct tm *ret = localtime_r(&t0, pt1);
1209 assert(ret == &t1);
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() {
1219 struct passwd pwd;
1220 char buf[1024];
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);
1227 assert(ret == 0);
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.
1238 int pipe_fds[2];
1239 int ret = pipe(pipe_fds);
1240 assert(ret != -1);
1242 // Configure epoll to monitor the pipe.
1243 int epfd = epoll_create1(0);
1244 assert(epfd != -1);
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);
1249 assert(ret != -1);
1251 // Test epoll_wait when no events have occurred.
1252 event = {};
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);
1256 assert(ret == 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);
1266 assert(ret == 1);
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)
1273 // Clean up.
1274 close(epfd);
1275 close(pipe_fds[0]);
1276 close(pipe_fds[1]);
1279 void test_poll() {
1280 struct pollfd fd;
1281 fd.fd = 0;
1282 fd.events = POLLIN;
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)
1289 assert(ret >= 0);
1292 void test_select() {
1293 struct timeval t;
1294 fd_set fds;
1295 t.tv_sec = 2;
1296 FD_SET(0, &fds);
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);
1302 assert(ret >= 0);
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() {
1311 cpu_set_t mask;
1312 dfsan_set_label(j_label, &mask, 1);
1313 DEFINE_AND_SAVE_ORIGINS(mask)
1314 int ret = sched_getaffinity(0, sizeof(mask), &mask);
1315 assert(ret == 0);
1316 ASSERT_ZERO_LABEL(ret);
1317 ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask));
1318 ASSERT_SAVED_ORIGINS(mask)
1321 void test_sigemptyset() {
1322 sigset_t set;
1323 dfsan_set_label(j_label, &set, 1);
1324 DEFINE_AND_SAVE_ORIGINS(set)
1325 int ret = sigemptyset(&set);
1326 assert(ret == 0);
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);
1346 assert(ret == 0);
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);
1396 assert(ret == 0);
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() {
1403 struct timeval tv;
1404 struct timezone tz;
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);
1410 assert(ret == 0);
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);
1420 return (void *)2;
1423 void test_pthread_create() {
1424 pthread_t pt;
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);
1428 void *cbrv;
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,
1444 void *data) {
1445 assert(data == (void *)3);
1446 ASSERT_ZERO_LABEL(info);
1447 ASSERT_ZERO_LABEL(size);
1448 ASSERT_ZERO_LABEL(data);
1449 return 0;
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,
1459 size_t *alignp);
1461 void test__dl_get_tls_static_info() {
1462 if (!_dl_get_tls_static_info)
1463 return;
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
1470 (void)sizep_o;
1471 (void)alignp_o;
1472 #endif
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";
1483 char *p = str1;
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);
1491 char c = 'r';
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);
1497 #else
1498 ASSERT_LABEL(rv, k_label);
1499 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, c);
1500 #endif
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);
1508 #else
1509 ASSERT_LABEL(rv, i_label);
1510 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[7]);
1511 #endif
1514 void test_strstr() {
1515 char str1[] = "str1str1";
1517 char *p1 = str1;
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);
1524 char str2[] = "1s";
1525 char *p2 = str2;
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);
1531 #else
1532 ASSERT_LABEL(rv, m_label);
1533 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p2);
1534 #endif
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);
1541 #else
1542 ASSERT_LABEL(rv, n_label);
1543 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str2[0]);
1544 #endif
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);
1553 #else
1554 ASSERT_LABEL(rv, i_label);
1555 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);
1556 #endif
1558 rv = strstr(str1, "2s");
1559 assert(rv == NULL);
1560 #ifdef STRICT_DATA_DEPENDENCIES
1561 ASSERT_ZERO_LABEL(rv);
1562 #else
1563 ASSERT_LABEL(rv, i_j_label);
1564 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);
1565 #endif
1568 void test_strpbrk() {
1569 char s[] = "abcdefg";
1570 char accept[] = "123fd";
1572 char *p_s = s;
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);
1581 #else
1582 ASSERT_LABEL(rv, n_label);
1583 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_accept);
1584 #endif
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);
1593 #else
1594 ASSERT_LABEL(rv, dfsan_union(m_label, n_label));
1595 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
1596 #endif
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);
1605 #else
1606 ASSERT_LABEL(rv, j_label);
1607 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, accept[1]);
1608 #endif
1610 char *ps = s;
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);
1617 #else
1618 ASSERT_LABEL(rv, i_j_label);
1619 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
1620 #endif
1622 rv = strpbrk(ps, "123");
1623 assert(rv == NULL);
1624 #ifdef STRICT_DATA_DEPENDENCIES
1625 ASSERT_ZERO_LABEL(rv);
1626 #else
1627 ASSERT_LABEL(rv, i_j_label);
1628 ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
1629 #endif
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);
1641 char c = 'r';
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);
1647 #else
1648 ASSERT_LABEL(crv, k_label);
1649 ASSERT_EQ_ORIGIN(crv, c);
1650 #endif
1652 char *ptr = str1;
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);
1663 #else
1664 ASSERT_LABEL(crv, i_label);
1665 ASSERT_EQ_ORIGIN(crv, str1[3]);
1666 #endif
1668 crv = (char *) memchr(str1, 'x', sizeof(str1));
1669 assert(!crv);
1670 #ifdef STRICT_DATA_DEPENDENCIES
1671 ASSERT_ZERO_LABEL(crv);
1672 #else
1673 ASSERT_LABEL(crv, i_j_label);
1674 ASSERT_EQ_ORIGIN(crv, str1[3]);
1675 #endif
1678 void alarm_handler(int unused) {
1682 void test_nanosleep() {
1683 struct timespec req, rem;
1684 req.tv_sec = 1;
1685 req.tv_nsec = 0;
1686 dfsan_set_label(i_label, &rem, sizeof(rem));
1687 DEFINE_AND_SAVE_ORIGINS(rem)
1689 // non interrupted
1690 int rv = nanosleep(&req, &rem);
1691 assert(rv == 0);
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);
1698 req.tv_sec = 3;
1699 alarm(1);
1700 rv = nanosleep(&req, &rem);
1701 assert(rv == -1);
1702 ASSERT_ZERO_LABEL(rv);
1703 ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem));
1704 ASSERT_SAVED_ORIGINS(rem)
1707 void test_socketpair() {
1708 int fd[2];
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);
1715 assert(rv == 0);
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() {
1723 int sockfds[2];
1724 int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
1725 assert(ret != -1);
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);
1735 assert(ret != -1);
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)
1744 close(sockfds[0]);
1745 close(sockfds[1]);
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);
1759 assert(ret != -1);
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)
1768 close(sockfd);
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);
1782 assert(ret != -1);
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)
1793 close(sockfd);
1796 void test_write() {
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);
1804 assert(res > 0);
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);
1816 close(fd);
1819 template <class T>
1820 void test_sprintf_chunk(const char* expected, const char* format, T arg) {
1821 char buf[512];
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));
1840 // Labelled arg.
1841 dfsan_set_label(i_label, &arg, sizeof(arg));
1842 dfsan_origin a_o = dfsan_get_origin((long)(arg));
1843 #ifndef ORIGIN_TRACKING
1844 (void)a_o;
1845 #endif
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() {
1855 char buf[2048];
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";
1871 int m = 8;
1872 int d = 27;
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
1880 (void)s_o;
1881 (void)m_o;
1882 (void)d_o;
1883 #endif
1884 int n;
1885 int r = sprintf(buf, "hello %s, %-d/%d/%d %f %% %n%d", s, 2014, m, d,
1886 12345.6781234, &n, 1000);
1887 assert(r == 42);
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);
1899 ASSERT_LABEL(r, 0);
1900 assert(n == 38);
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);
1934 assert(r == 30);
1935 assert(strcmp(buf, "hi 1 my dear friend 3.1416") == 0);
1938 void test_snprintf() {
1939 char buf[2048];
1940 memset(buf, 'a', sizeof(buf));
1941 dfsan_set_label(0, buf, sizeof(buf));
1942 const char* s = "world";
1943 int y = 2014;
1944 int m = 8;
1945 int d = 27;
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
1953 (void)s_o;
1954 (void)y_o;
1955 (void)m_o;
1956 #endif
1957 int r = snprintf(buf, 19, "hello %s, %-d/ %d/%d %f", s, y, m, d,
1958 12345.6781234);
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.
1961 assert(r == 38);
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);
1970 ASSERT_LABEL(r, 0);
1973 // Tested by a seperate source file. This empty function is here to appease the
1974 // check-wrappers script.
1975 void test_fork() {}
1977 int main(void) {
1978 i_label = 1;
1979 j_label = 2;
1980 k_label = 4;
1981 m_label = 8;
1982 n_label = 16;
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();
1989 test_bcmp();
1990 test_clock_gettime();
1991 test_ctime_r();
1992 test_dfsan_set_write_callback();
1993 test_dl_iterate_phdr();
1994 test_dlopen();
1995 test_epoll_wait();
1996 test_fgets();
1997 test_fork();
1998 test_fstat();
1999 test_get_current_dir_name();
2000 test_getcwd();
2001 test_getentropy();
2002 test_gethostname();
2003 test_getpeername();
2004 test_getpwuid_r();
2005 test_getrlimit();
2006 test_getrusage();
2007 test_getsockname();
2008 test_getsockopt();
2009 test_gettimeofday();
2010 test_inet_pton();
2011 test_localtime_r();
2012 test_memchr();
2013 test_memcmp();
2014 test_memcpy();
2015 test_memmove();
2016 test_memset();
2017 test_nanosleep();
2018 test_poll();
2019 test_pread();
2020 test_pthread_create();
2021 test_pthread_join();
2022 test_read();
2023 test_recvmmsg();
2024 test_recvmsg();
2025 test_sched_getaffinity();
2026 test_select();
2027 test_sigaction();
2028 test_signal();
2029 test_sigaltstack();
2030 test_sigemptyset();
2031 test_snprintf();
2032 test_socketpair();
2033 test_sprintf();
2034 test_stat();
2035 test_strcasecmp();
2036 test_strchr();
2037 test_strcmp();
2038 test_strcat();
2039 test_strcpy();
2040 test_strdup();
2041 test_strlen();
2042 test_strncasecmp();
2043 test_strncmp();
2044 test_strncpy();
2045 test_strpbrk();
2046 test_strrchr();
2047 test_strstr();
2048 test_strtod();
2049 test_strtol();
2050 test_strtoll();
2051 test_strtoul();
2052 test_strtoull();
2053 test_time();
2054 test_write();