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
9 
10 #pragma clang diagnostic ignored "-Wformat-extra-args"
11 
12 #include <sanitizer/dfsan_interface.h>
13 
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>
37 
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;
44 
45 #define ASSERT_ZERO_LABEL(data) \
46   assert(0 == dfsan_get_label((long) (data)))
47 
48 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
49   assert(0 == dfsan_read_label(ptr, size))
50 
51 #define ASSERT_LABEL(data, label) \
52   assert(label == dfsan_get_label((long) (data)))
53 
54 #define ASSERT_READ_LABEL(ptr, size, label) \
55   assert(label == dfsan_read_label(ptr, size))
56 
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
63 
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]))); \
68   }
69 #else
70 #define ASSERT_ZERO_ORIGINS(ptr, size)
71 #endif
72 
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
79 
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]))); \
84   }
85 #else
86 #define ASSERT_ORIGINS(ptr, size, origin)
87 #endif
88 
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
95 
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
102 
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])); \
107   }
108 #else
109 #define ASSERT_INIT_ORIGINS(ptr, size, origin)
110 #endif
111 
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
118 
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
127 
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
135 
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
143 
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
152 
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
160 
161 #if !defined(__GLIBC_PREREQ)
162 #  define __GLIBC_PREREQ(a, b) 0
163 #endif
164 
test_stat()165 void test_stat() {
166   int i = 1;
167   dfsan_set_label(i_label, &i, sizeof(i));
168 
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)
177 
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)
185 }
186 
test_fstat()187 void test_fstat() {
188   int i = 1;
189   dfsan_set_label(i_label, &i, sizeof(i));
190 
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)
200 }
201 
test_memcmp()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);
206 
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
215 
216   rv = memcmp(str1, str2, sizeof(str1) - 2);
217   assert(rv == 0);
218   ASSERT_ZERO_LABEL(rv);
219 }
220 
test_bcmp()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);
225 
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
234 
235   rv = bcmp(str1, str2, sizeof(str1) - 2);
236   assert(rv == 0);
237   ASSERT_ZERO_LABEL(rv);
238 }
239 
test_memcpy()240 void test_memcpy() {
241   char str1[] = "str1";
242   char str2[sizeof(str1)];
243   dfsan_set_label(i_label, &str1[3], 1);
244 
245   DEFINE_AND_SAVE_ORIGINS(str1)
246 
247   char *ptr2 = str2;
248   dfsan_set_label(j_label, &ptr2, sizeof(ptr2));
249 
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);
256 
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]);
261   }
262 }
263 
test_memmove()264 void test_memmove() {
265   char str[] = "str1xx";
266   dfsan_set_label(i_label, &str[3], 1);
267 
268   DEFINE_AND_SAVE_ORIGINS(str)
269 
270   char *ptr = str + 2;
271   dfsan_set_label(j_label, &ptr, sizeof(ptr));
272 
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);
279 
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]);
284   }
285 }
286 
test_memset()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');
300   }
301 }
302 
test_strcmp()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);
307 
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
316 
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
326 }
327 
test_strcat()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]);
357     }
358   }
359   for (int i = 0; i < 6; ++i) {
360     ASSERT_LABEL(dst[i], j_label);
361   }
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]));
365   }
366   ASSERT_LABEL(dst[11], j_label);
367 }
368 
test_strlen()369 void test_strlen() {
370   char str1[] = "str1";
371   dfsan_set_label(i_label, &str1[3], 1);
372 
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
381 }
382 
test_strdup()383 void test_strdup() {
384   char str1[] = "str1";
385   dfsan_set_label(i_label, &str1[3], 1);
386   DEFINE_AND_SAVE_ORIGINS(str1)
387 
388   char *strd = strdup(str1);
389   ASSERT_ZERO_LABEL(strd);
390   ASSERT_ZERO_LABEL(strd[0]);
391   ASSERT_LABEL(strd[3], i_label);
392 
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]);
397   }
398 
399   free(strd);
400 }
401 
test_strncpy()402 void test_strncpy() {
403   char str1[] = "str1";
404   char str2[sizeof(str1)];
405   dfsan_set_label(i_label, &str1[3], 1);
406 
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]);
416 
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
437 }
438 
test_strncmp()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);
443 
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
452 
453   rv = strncmp(str1, str2, 0);
454   assert(rv == 0);
455   ASSERT_ZERO_LABEL(rv);
456 
457   rv = strncmp(str1, str2, 3);
458   assert(rv == 0);
459   ASSERT_ZERO_LABEL(rv);
460 
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
469 }
470 
test_strcasecmp()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);
476 
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
485 
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
494 
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);
499 
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
508 }
509 
test_strncasecmp()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);
514 
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
523 
524   rv = strncasecmp(str1, str2, 3);
525   assert(rv == 0);
526   ASSERT_ZERO_LABEL(rv);
527 
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);
532 
533   rv = strncasecmp(s1, s2, 0);
534   assert(rv == 0); // Compare zero chars.
535   ASSERT_ZERO_LABEL(rv);
536 
537   rv = strncasecmp(s1, s2, 1);
538   assert(rv == 0); // 'A' == 'a'
539   ASSERT_ZERO_LABEL(rv);
540 
541   rv = strncasecmp(s1, s2, 2);
542   assert(rv == 0); // 'b' == 'B'
543   ASSERT_ZERO_LABEL(rv);
544 
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
553 }
554 
test_strchr()555 void test_strchr() {
556   char str1[] = "str1";
557   dfsan_set_label(i_label, &str1[3], 1);
558 
559   char *p1 = str1;
560   char c = 'r';
561   dfsan_set_label(k_label, &c, sizeof(c));
562 
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
571 
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);
577 
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
587 
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
597 
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
610 }
611 
test_recvmmsg()612 void test_recvmmsg() {
613   int sockfds[2];
614   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
615   assert(ret != -1);
616 
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;
627 
628   // Send messages.
629   int sent_msgs = sendmmsg(sockfds[0], smmsg, 2, 0);
630   assert(sent_msgs == 2);
631 
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));
648 
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
655 
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);
672 
673   ASSERT_ORIGIN((long)(rmmsg[0].msg_len), msg_len0_o);
674   ASSERT_ORIGIN((long)(rmmsg[1].msg_len), msg_len1_o);
675 
676   close(sockfds[0]);
677   close(sockfds[1]);
678 }
679 
test_recvmsg()680 void test_recvmsg() {
681   int sockfds[2];
682   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
683   assert(ret != -1);
684 
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;
690 
691   ssize_t sent = sendmsg(sockfds[0], &smsg, 0);
692   assert(sent > 0);
693 
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;
699 
700   dfsan_set_label(i_label, rbuf, sizeof(rbuf));
701   dfsan_set_label(i_label, &rmsg, sizeof(rmsg));
702 
703   DEFINE_AND_SAVE_ORIGINS(rmsg)
704 
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);
712 
713   ASSERT_SAVED_ORIGINS(rmsg)
714 
715   close(sockfds[0]);
716   close(sockfds[1]);
717 }
718 
test_read()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);
723 
724   DEFINE_AND_SAVE_ORIGINS(buf)
725   ASSERT_LABEL(buf[0], i_label);
726   ASSERT_LABEL(buf[15], j_label);
727 
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);
736 }
737 
test_pread()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);
742 
743   DEFINE_AND_SAVE_ORIGINS(buf)
744   ASSERT_LABEL(buf[0], i_label);
745   ASSERT_LABEL(buf[15], j_label);
746 
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);
755 }
756 
test_dlopen()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);
765 }
766 
test_clock_gettime()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);
779 }
780 
test_ctime_r()781 void test_ctime_r() {
782   char *buf = (char*) malloc(64);
783   time_t t = 0;
784 
785   DEFINE_AND_SAVE_ORIGINS(buf)
786   dfsan_origin t_o = dfsan_get_origin((long)t);
787 
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)
793 
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);
801 
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);
814 }
815 
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;
820 
write_callback(int fd,const void * buf,size_t count)821 void write_callback(int fd, const void *buf, size_t count) {
822   write_callback_count++;
823 
824   last_fd = fd;
825   last_buf = (const unsigned char*) buf;
826   last_count = count;
827 }
828 
test_dfsan_set_write_callback()829 void test_dfsan_set_write_callback() {
830   char a_buf[] = "Sample chars";
831   int a_buf_len = strlen(a_buf);
832 
833   int fd = open("/dev/null", O_WRONLY);
834 
835   dfsan_set_write_callback(write_callback);
836 
837   write_callback_count = 0;
838 
839   DEFINE_AND_SAVE_ORIGINS(a_buf)
840 
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));
847 
848   for (int i = 0; i < a_buf_len; ++i)
849     ASSERT_ORIGIN(last_buf[i], a_buf_o[i]);
850 
851   ASSERT_ZERO_ORIGINS(&last_count, sizeof(last_count));
852   last_fd = 0;
853   last_buf = 0;
854   last_count = 0;
855 
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;
861 
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));
868 
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)
878 
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);
884 
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);
894 
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]);
904   }
905 
906   ASSERT_INIT_ORIGINS(&last_count, sizeof(last_count), b_buf_len_o);
907 
908   dfsan_set_write_callback(NULL);
909 }
910 
test_fgets()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)
916 
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)
923 
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)
929 
930   fclose(f);
931   free(buf);
932 }
933 
test_getcwd()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)
939 
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)
947 
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)
953 }
954 
test_get_current_dir_name()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);
961 }
962 
test_getentropy()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)
974   }
975 #endif
976 }
977 
test_gethostname()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)
987 }
988 
test_getrlimit()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)
998 }
999 
test_getrusage()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)
1009 }
1010 
test_strcpy()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]));
1031   }
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);
1037 }
1038 
test_strtol()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);
1046 
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);
1055 
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]);
1063 }
1064 
test_strtoll()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);
1072 
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);
1081 
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]);
1089 }
1090 
test_strtoul()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);
1098 
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);
1107 
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]);
1115 }
1116 
test_strtoull()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);
1124 
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);
1133 
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]);
1141 }
1142 
test_strtod()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);
1150 
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]);
1159 }
1160 
test_time()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)
1171 }
1172 
test_inet_pton()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));
1183 
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])))
1192 }
1193 
test_localtime_r()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);
1202 
1203 #ifndef ORIGIN_TRACKING
1204   (void)t0_o;
1205   (void)pt1_o;
1206 #endif
1207 
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);
1216 }
1217 
test_getpwuid_r()1218 void test_getpwuid_r() {
1219   struct passwd pwd;
1220   char buf[1024];
1221   struct passwd *result;
1222 
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)
1234 }
1235 
test_epoll_wait()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);
1241 
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);
1250 
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)
1262 
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)
1272 
1273   // Clean up.
1274   close(epfd);
1275   close(pipe_fds[0]);
1276   close(pipe_fds[1]);
1277 }
1278 
test_poll()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);
1290 }
1291 
test_select()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)
1308 }
1309 
test_sched_getaffinity()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)
1319 }
1320 
test_sigemptyset()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)
1330 }
1331 
SignalHandler(int signo)1332 static void SignalHandler(int signo) {}
1333 
SignalAction(int signo,siginfo_t * si,void * uc)1334 static void SignalAction(int signo, siginfo_t *si, void *uc) {}
1335 
test_sigaction()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;
1340 
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)
1350 
1351   struct sigaction newact_with_sighandler = {};
1352   newact_with_sighandler.sa_handler = SignalHandler;
1353 
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);
1359 
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);
1365 
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);
1370 
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);
1375 }
1376 
test_signal()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);
1382 
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));
1386 
1387   // Restore signal to old_signal_handler.
1388   assert(SIG_IGN == signal(SIGHUP, old_signal_handler));
1389 }
1390 
test_sigaltstack()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)
1400 }
1401 
test_gettimeofday()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)
1415 }
1416 
pthread_create_test_cb(void * p)1417 void *pthread_create_test_cb(void *p) {
1418   assert(p == (void *)1);
1419   ASSERT_ZERO_LABEL(p);
1420   return (void *)2;
1421 }
1422 
test_pthread_create()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);
1437 }
1438 
1439 // Tested by test_pthread_create().  This empty function is here to appease the
1440 // check-wrappers script.
test_pthread_join()1441 void test_pthread_join() {}
1442 
dl_iterate_phdr_test_cb(struct dl_phdr_info * info,size_t size,void * data)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;
1450 }
1451 
test_dl_iterate_phdr()1452 void test_dl_iterate_phdr() {
1453   dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3);
1454 }
1455 
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);
1460 
test__dl_get_tls_static_info()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);
1478 }
1479 
test_strrchr()1480 void test_strrchr() {
1481   char str1[] = "str1str1";
1482 
1483   char *p = str1;
1484   dfsan_set_label(j_label, &p, sizeof(p));
1485 
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);
1490 
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
1501 
1502   dfsan_set_label(i_label, &str1[7], 1);
1503 
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
1512 }
1513 
test_strstr()1514 void test_strstr() {
1515   char str1[] = "str1str1";
1516 
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);
1523 
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
1535 
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
1545 
1546   dfsan_set_label(i_label, &str1[3], 1);
1547   dfsan_set_label(j_label, &str1[5], 1);
1548 
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
1557 
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
1566 }
1567 
test_strpbrk()1568 void test_strpbrk() {
1569   char s[] = "abcdefg";
1570   char accept[] = "123fd";
1571 
1572   char *p_s = s;
1573   char *p_accept = accept;
1574 
1575   dfsan_set_label(n_label, &p_accept, sizeof(p_accept));
1576 
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
1585 
1586   dfsan_set_label(m_label, &p_s, sizeof(p_s));
1587 
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
1597 
1598   dfsan_set_label(i_label, &s[5], 1);
1599   dfsan_set_label(j_label, &accept[1], 1);
1600 
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
1609 
1610   char *ps = s;
1611   dfsan_set_label(j_label, &ps, sizeof(ps));
1612 
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
1621 
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
1630 }
1631 
test_memchr()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);
1636 
1637   char *crv = (char *) memchr(str1, 'r', sizeof(str1));
1638   assert(crv == &str1[2]);
1639   ASSERT_ZERO_LABEL(crv);
1640 
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
1651 
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);
1658 
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
1667 
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
1676 }
1677 
alarm_handler(int unused)1678 void alarm_handler(int unused) {
1679   ;
1680 }
1681 
test_nanosleep()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)
1688 
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)
1695 
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)
1705 }
1706 
test_socketpair()1707 void test_socketpair() {
1708   int fd[2];
1709   dfsan_origin fd_o[2];
1710 
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]);
1720 }
1721 
test_getpeername()1722 void test_getpeername() {
1723   int sockfds[2];
1724   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
1725   assert(ret != -1);
1726 
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)
1733 
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)
1743 
1744   close(sockfds[0]);
1745   close(sockfds[1]);
1746 }
1747 
test_getsockname()1748 void test_getsockname() {
1749   int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
1750   assert(sockfd != -1);
1751 
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)
1767 
1768   close(sockfd);
1769 }
1770 
test_getsockopt()1771 void test_getsockopt() {
1772   int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
1773   assert(sockfd != -1);
1774 
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)
1792 
1793   close(sockfd);
1794 }
1795 
test_write()1796 void test_write() {
1797   int fd = open("/dev/null", O_WRONLY);
1798 
1799   char buf[] = "a string";
1800   int len = strlen(buf);
1801 
1802   // The result of a write always unlabeled.
1803   int res = write(fd, buf, len);
1804   assert(res > 0);
1805   ASSERT_ZERO_LABEL(res);
1806 
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));
1811 
1812   // The value returned by write() should have no label.
1813   res = write(fd, buf, len);
1814   ASSERT_ZERO_LABEL(res);
1815 
1816   close(fd);
1817 }
1818 
1819 template <class T>
test_sprintf_chunk(const char * expected,const char * format,T arg)1820 void test_sprintf_chunk(const char* expected, const char* format, T arg) {
1821   char buf[512];
1822   memset(buf, 'a', sizeof(buf));
1823 
1824   char padded_expected[512];
1825   strcpy(padded_expected, "foo ");
1826   strcat(padded_expected, expected);
1827   strcat(padded_expected, " bar");
1828 
1829   char padded_format[512];
1830   strcpy(padded_format, "foo ");
1831   strcat(padded_format, format);
1832   strcat(padded_format, " bar");
1833 
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));
1839 
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);
1852 }
1853 
test_sprintf()1854 void test_sprintf() {
1855   char buf[2048];
1856   memset(buf, 'a', sizeof(buf));
1857 
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);
1862 
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);
1867 
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);
1901 
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);
1918 
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);
1927 
1928   test_sprintf_chunk("z", "%c", 'z');
1929 
1930   // %n, %s, %d, %f, and %% already tested
1931 
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);
1936 }
1937 
test_snprintf()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);
1971 }
1972 
1973 // Tested by a seperate source file.  This empty function is here to appease the
1974 // check-wrappers script.
test_fork()1975 void test_fork() {}
1976 
main(void)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);
1987 
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();
2055 }
2056