1 // RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
2 // RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
3 // RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t
4 // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t
5 // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi %s -o %t && %run %t
6 // 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
7 // 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
8 //
9 // Tests custom implementations of various glibc functions.
10 //
11 // REQUIRES: x86_64-target-arch
12 
13 #pragma clang diagnostic ignored "-Wformat-extra-args"
14 
15 #include <sanitizer/dfsan_interface.h>
16 
17 #include <arpa/inet.h>
18 #include <assert.h>
19 #include <fcntl.h>
20 #include <link.h>
21 #include <poll.h>
22 #include <pthread.h>
23 #include <pwd.h>
24 #include <sched.h>
25 #include <signal.h>
26 #include <stdint.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <sys/epoll.h>
32 #include <sys/resource.h>
33 #include <sys/select.h>
34 #include <sys/socket.h>
35 #include <sys/stat.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <time.h>
39 #include <unistd.h>
40 
41 dfsan_label i_label = 0;
42 dfsan_label j_label = 0;
43 dfsan_label k_label = 0;
44 dfsan_label m_label = 0;
45 dfsan_label n_label = 0;
46 dfsan_label i_j_label = 0;
47 
48 #define ASSERT_ZERO_LABEL(data) \
49   assert(0 == dfsan_get_label((long) (data)))
50 
51 #define ASSERT_READ_ZERO_LABEL(ptr, size) \
52   assert(0 == dfsan_read_label(ptr, size))
53 
54 #define ASSERT_LABEL(data, label) \
55   assert(label == dfsan_get_label((long) (data)))
56 
57 #define ASSERT_READ_LABEL(ptr, size, label) \
58   assert(label == dfsan_read_label(ptr, size))
59 
60 #ifdef ORIGIN_TRACKING
61 #define ASSERT_ZERO_ORIGIN(data) \
62   assert(0 == dfsan_get_origin((long)(data)))
63 #else
64 #define ASSERT_ZERO_ORIGIN(data)
65 #endif
66 
67 #ifdef ORIGIN_TRACKING
68 #define ASSERT_ZERO_ORIGINS(ptr, size)                       \
69   for (int i = 0; i < size; ++i) {                           \
70     assert(0 == dfsan_get_origin((long)(((char *)ptr)[i]))); \
71   }
72 #else
73 #define ASSERT_ZERO_ORIGINS(ptr, size)
74 #endif
75 
76 #ifdef ORIGIN_TRACKING
77 #define ASSERT_ORIGIN(data, origin) \
78   assert(origin == dfsan_get_origin((long)(data)))
79 #else
80 #define ASSERT_ORIGIN(data, origin)
81 #endif
82 
83 #ifdef ORIGIN_TRACKING
84 #define ASSERT_ORIGINS(ptr, size, origin)                         \
85   for (int i = 0; i < size; ++i) {                                \
86     assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \
87   }
88 #else
89 #define ASSERT_ORIGINS(ptr, size, origin)
90 #endif
91 
92 #ifdef ORIGIN_TRACKING
93 #define ASSERT_INIT_ORIGIN(ptr, origin) \
94   assert(origin == dfsan_get_init_origin(ptr))
95 #else
96 #define ASSERT_INIT_ORIGIN(ptr, origin)
97 #endif
98 
99 #ifdef ORIGIN_TRACKING
100 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data) \
101   assert(dfsan_get_origin((long)(data)) == dfsan_get_init_origin(ptr))
102 #else
103 #define ASSERT_INIT_ORIGIN_EQ_ORIGIN(ptr, data)
104 #endif
105 
106 #ifdef ORIGIN_TRACKING
107 #define ASSERT_INIT_ORIGINS(ptr, size, origin)                  \
108   for (int i = 0; i < size; ++i) {                              \
109     assert(origin == dfsan_get_init_origin(&((char *)ptr)[i])); \
110   }
111 #else
112 #define ASSERT_INIT_ORIGINS(ptr, size, origin)
113 #endif
114 
115 #ifdef ORIGIN_TRACKING
116 #define ASSERT_EQ_ORIGIN(data1, data2) \
117   assert(dfsan_get_origin((long)(data1)) == dfsan_get_origin((long)(data2)))
118 #else
119 #define ASSERT_EQ_ORIGIN(data1, data2)
120 #endif
121 
122 #ifdef ORIGIN_TRACKING
123 #define DEFINE_AND_SAVE_ORIGINS(val)    \
124   dfsan_origin val##_o[sizeof(val)];    \
125   for (int i = 0; i < sizeof(val); ++i) \
126     val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
127 #else
128 #define DEFINE_AND_SAVE_ORIGINS(val)
129 #endif
130 
131 #ifdef ORIGIN_TRACKING
132 #define SAVE_ORIGINS(val)               \
133   for (int i = 0; i < sizeof(val); ++i) \
134     val##_o[i] = dfsan_get_origin((long)(((char *)(&val))[i]));
135 #else
136 #define SAVE_ORIGINS(val)
137 #endif
138 
139 #ifdef ORIGIN_TRACKING
140 #define ASSERT_SAVED_ORIGINS(val)       \
141   for (int i = 0; i < sizeof(val); ++i) \
142     ASSERT_ORIGIN(((char *)(&val))[i], val##_o[i]);
143 #else
144 #define ASSERT_SAVED_ORIGINS(val)
145 #endif
146 
147 #ifdef ORIGIN_TRACKING
148 #define DEFINE_AND_SAVE_N_ORIGINS(val, n) \
149   dfsan_origin val##_o[n];                \
150   for (int i = 0; i < n; ++i)             \
151     val##_o[i] = dfsan_get_origin((long)(val[i]));
152 #else
153 #define DEFINE_AND_SAVE_N_ORIGINS(val, n)
154 #endif
155 
156 #ifdef ORIGIN_TRACKING
157 #define ASSERT_SAVED_N_ORIGINS(val, n) \
158   for (int i = 0; i < n; ++i)          \
159     ASSERT_ORIGIN(val[i], val##_o[i]);
160 #else
161 #define ASSERT_SAVED_N_ORIGINS(val, n)
162 #endif
163 
test_stat()164 void test_stat() {
165   int i = 1;
166   dfsan_set_label(i_label, &i, sizeof(i));
167 
168   struct stat s;
169   s.st_dev = i;
170   DEFINE_AND_SAVE_ORIGINS(s)
171   int ret = stat("/", &s);
172   assert(0 == ret);
173   ASSERT_ZERO_LABEL(ret);
174   ASSERT_ZERO_LABEL(s.st_dev);
175   ASSERT_SAVED_ORIGINS(s)
176 
177   s.st_dev = i;
178   SAVE_ORIGINS(s)
179   ret = stat("/nonexistent", &s);
180   assert(-1 == ret);
181   ASSERT_ZERO_LABEL(ret);
182   ASSERT_LABEL(s.st_dev, i_label);
183   ASSERT_SAVED_ORIGINS(s)
184 }
185 
test_fstat()186 void test_fstat() {
187   int i = 1;
188   dfsan_set_label(i_label, &i, sizeof(i));
189 
190   struct stat s;
191   int fd = open("/dev/zero", O_RDONLY);
192   s.st_dev = i;
193   DEFINE_AND_SAVE_ORIGINS(s)
194   int rv = fstat(fd, &s);
195   assert(0 == rv);
196   ASSERT_ZERO_LABEL(rv);
197   ASSERT_ZERO_LABEL(s.st_dev);
198   ASSERT_SAVED_ORIGINS(s)
199 }
200 
test_memcmp()201 void test_memcmp() {
202   char str1[] = "str1", str2[] = "str2";
203   dfsan_set_label(i_label, &str1[3], 1);
204   dfsan_set_label(j_label, &str2[3], 1);
205 
206   int rv = memcmp(str1, str2, sizeof(str1));
207   assert(rv < 0);
208 #ifdef STRICT_DATA_DEPENDENCIES
209   ASSERT_ZERO_LABEL(rv);
210 #else
211   ASSERT_LABEL(rv, i_j_label);
212   ASSERT_EQ_ORIGIN(rv, str1[3]);
213 #endif
214 
215   rv = memcmp(str1, str2, sizeof(str1) - 2);
216   assert(rv == 0);
217   ASSERT_ZERO_LABEL(rv);
218 }
219 
test_bcmp()220 void test_bcmp() {
221   char str1[] = "str1", str2[] = "str2";
222   dfsan_set_label(i_label, &str1[3], 1);
223   dfsan_set_label(j_label, &str2[3], 1);
224 
225   int rv = bcmp(str1, str2, sizeof(str1));
226   assert(rv != 0);
227 #ifdef STRICT_DATA_DEPENDENCIES
228   ASSERT_ZERO_LABEL(rv);
229 #else
230   ASSERT_LABEL(rv, i_j_label);
231   ASSERT_EQ_ORIGIN(rv, str1[3]);
232 #endif
233 
234   rv = bcmp(str1, str2, sizeof(str1) - 2);
235   assert(rv == 0);
236   ASSERT_ZERO_LABEL(rv);
237 }
238 
test_memcpy()239 void test_memcpy() {
240   char str1[] = "str1";
241   char str2[sizeof(str1)];
242   dfsan_set_label(i_label, &str1[3], 1);
243 
244   DEFINE_AND_SAVE_ORIGINS(str1)
245 
246   char *ptr2 = str2;
247   dfsan_set_label(j_label, &ptr2, sizeof(ptr2));
248 
249   void *r = memcpy(ptr2, str1, sizeof(str1));
250   ASSERT_LABEL(r, j_label);
251   ASSERT_EQ_ORIGIN(r, ptr2);
252   assert(0 == memcmp(str2, str1, sizeof(str1)));
253   ASSERT_ZERO_LABEL(str2[0]);
254   ASSERT_LABEL(str2[3], i_label);
255 
256   for (int i = 0; i < sizeof(str2); ++i) {
257     if (!dfsan_get_label(str2[i]))
258       continue;
259     ASSERT_INIT_ORIGIN(&(str2[i]), str1_o[i]);
260   }
261 }
262 
test_memmove()263 void test_memmove() {
264   char str[] = "str1xx";
265   dfsan_set_label(i_label, &str[3], 1);
266 
267   DEFINE_AND_SAVE_ORIGINS(str)
268 
269   char *ptr = str + 2;
270   dfsan_set_label(j_label, &ptr, sizeof(ptr));
271 
272   void *r = memmove(ptr, str, 4);
273   ASSERT_LABEL(r, j_label);
274   ASSERT_EQ_ORIGIN(r, ptr);
275   assert(0 == memcmp(str + 2, "str1", 4));
276   ASSERT_ZERO_LABEL(str[4]);
277   ASSERT_LABEL(str[5], i_label);
278 
279   for (int i = 0; i < 4; ++i) {
280     if (!dfsan_get_label(ptr[i]))
281       continue;
282     ASSERT_INIT_ORIGIN(&(ptr[i]), str_o[i]);
283   }
284 }
285 
test_memset()286 void test_memset() {
287   char buf[8];
288   int j = 'a';
289   char *ptr = buf;
290   dfsan_set_label(j_label, &j, sizeof(j));
291   dfsan_set_label(k_label, &ptr, sizeof(ptr));
292   void *ret = memset(ptr, j, sizeof(buf));
293   ASSERT_LABEL(ret, k_label);
294   ASSERT_EQ_ORIGIN(ret, ptr);
295   for (int i = 0; i < 8; ++i) {
296     ASSERT_LABEL(buf[i], j_label);
297     ASSERT_EQ_ORIGIN(buf[i], j);
298     assert(buf[i] == 'a');
299   }
300 }
301 
test_strcmp()302 void test_strcmp() {
303   char str1[] = "str1", str2[] = "str2";
304   dfsan_set_label(i_label, &str1[3], 1);
305   dfsan_set_label(j_label, &str2[3], 1);
306 
307   int rv = strcmp(str1, str2);
308   assert(rv < 0);
309 #ifdef STRICT_DATA_DEPENDENCIES
310   ASSERT_ZERO_LABEL(rv);
311 #else
312   ASSERT_LABEL(rv, i_j_label);
313   ASSERT_EQ_ORIGIN(rv, str1[3]);
314 #endif
315 
316   rv = strcmp(str1, str1);
317   assert(rv == 0);
318 #ifdef STRICT_DATA_DEPENDENCIES
319   ASSERT_ZERO_LABEL(rv);
320   ASSERT_ZERO_ORIGIN(rv);
321 #else
322   ASSERT_LABEL(rv, i_label);
323   ASSERT_EQ_ORIGIN(rv, str1[3]);
324 #endif
325 }
326 
test_strcat()327 void test_strcat() {
328   char src[] = "world";
329   int volatile x = 0; // buffer to ensure src and dst do not share origins
330   (void)x;
331   char dst[] = "hello \0    ";
332   int volatile y = 0; // buffer to ensure dst and p do not share origins
333   (void)y;
334   char *p = dst;
335   dfsan_set_label(k_label, &p, sizeof(p));
336   dfsan_set_label(i_label, src, sizeof(src));
337   dfsan_set_label(j_label, dst, sizeof(dst));
338   dfsan_origin dst_o = dfsan_get_origin((long)dst[0]);
339   (void)dst_o;
340   char *ret = strcat(p, src);
341   ASSERT_LABEL(ret, k_label);
342   ASSERT_EQ_ORIGIN(ret, p);
343   assert(ret == dst);
344   assert(strcmp(src, dst + 6) == 0);
345   // Origins are assigned for every 4 contiguous 4-aligned bytes. After
346   // appending src to dst, origins of src can overwrite origins of dst if their
347   // application adddresses are within [start_aligned_down, end_aligned_up).
348   // Other origins are not changed.
349   char *start_aligned_down = (char *)(((size_t)(dst + 6)) & ~3UL);
350   char *end_aligned_up = (char *)(((size_t)(dst + 11 + 4)) & ~3UL);
351   for (int i = 0; i < 12; ++i) {
352     if (dst + i < start_aligned_down || dst + i >= end_aligned_up) {
353       ASSERT_INIT_ORIGIN(&dst[i], dst_o);
354     } else {
355       ASSERT_INIT_ORIGIN_EQ_ORIGIN(&dst[i], src[0]);
356     }
357   }
358   for (int i = 0; i < 6; ++i) {
359     ASSERT_LABEL(dst[i], j_label);
360   }
361   for (int i = 6; i < strlen(dst); ++i) {
362     ASSERT_LABEL(dst[i], i_label);
363     assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i - 6]));
364   }
365   ASSERT_LABEL(dst[11], j_label);
366 }
367 
test_strlen()368 void test_strlen() {
369   char str1[] = "str1";
370   dfsan_set_label(i_label, &str1[3], 1);
371 
372   int rv = strlen(str1);
373   assert(rv == 4);
374 #ifdef STRICT_DATA_DEPENDENCIES
375   ASSERT_ZERO_LABEL(rv);
376 #else
377   ASSERT_LABEL(rv, i_label);
378   ASSERT_EQ_ORIGIN(rv, str1[3]);
379 #endif
380 }
381 
test_strdup()382 void test_strdup() {
383   char str1[] = "str1";
384   dfsan_set_label(i_label, &str1[3], 1);
385   DEFINE_AND_SAVE_ORIGINS(str1)
386 
387   char *strd = strdup(str1);
388   ASSERT_ZERO_LABEL(strd);
389   ASSERT_ZERO_LABEL(strd[0]);
390   ASSERT_LABEL(strd[3], i_label);
391 
392   for (int i = 0; i < strlen(strd); ++i) {
393     if (!dfsan_get_label(strd[i]))
394       continue;
395     ASSERT_INIT_ORIGIN(&(strd[i]), str1_o[i]);
396   }
397 
398   free(strd);
399 }
400 
test_strncpy()401 void test_strncpy() {
402   char str1[] = "str1";
403   char str2[sizeof(str1)];
404   dfsan_set_label(i_label, &str1[3], 1);
405 
406   char *strd = strncpy(str2, str1, 5);
407   assert(strd == str2);
408   assert(strcmp(str1, str2) == 0);
409   ASSERT_ZERO_LABEL(strd);
410   ASSERT_ZERO_LABEL(strd[0]);
411   ASSERT_ZERO_LABEL(strd[1]);
412   ASSERT_ZERO_LABEL(strd[2]);
413   ASSERT_LABEL(strd[3], i_label);
414   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&(strd[3]), str1[3]);
415 
416   char *p2 = str2;
417   dfsan_set_label(j_label, &p2, sizeof(p2));
418   strd = strncpy(p2, str1, 3);
419   assert(strd == str2);
420   assert(strncmp(str1, str2, 3) == 0);
421   ASSERT_LABEL(strd, j_label);
422   ASSERT_EQ_ORIGIN(strd, p2);
423   // When -dfsan-combine-pointer-labels-on-load is on, strd's label propagates
424   // to strd[i]'s label. When ORIGIN_TRACKING is defined,
425   // -dfsan-combine-pointer-labels-on-load is always off, otherwise the flag
426   // is on by default.
427 #if defined(ORIGIN_TRACKING)
428   ASSERT_ZERO_LABEL(strd[0]);
429   ASSERT_ZERO_LABEL(strd[1]);
430   ASSERT_ZERO_LABEL(strd[2]);
431 #else
432   ASSERT_LABEL(strd[0], j_label);
433   ASSERT_LABEL(strd[1], j_label);
434   ASSERT_LABEL(strd[2], j_label);
435 #endif
436 }
437 
test_strncmp()438 void test_strncmp() {
439   char str1[] = "str1", str2[] = "str2";
440   dfsan_set_label(i_label, &str1[3], 1);
441   dfsan_set_label(j_label, &str2[3], 1);
442 
443   int rv = strncmp(str1, str2, sizeof(str1));
444   assert(rv < 0);
445 #ifdef STRICT_DATA_DEPENDENCIES
446   ASSERT_ZERO_LABEL(rv);
447 #else
448   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
449   ASSERT_EQ_ORIGIN(rv, str1[3]);
450 #endif
451 
452   rv = strncmp(str1, str2, 0);
453   assert(rv == 0);
454   ASSERT_ZERO_LABEL(rv);
455 
456   rv = strncmp(str1, str2, 3);
457   assert(rv == 0);
458   ASSERT_ZERO_LABEL(rv);
459 
460   rv = strncmp(str1, str1, 4);
461   assert(rv == 0);
462 #ifdef STRICT_DATA_DEPENDENCIES
463   ASSERT_ZERO_LABEL(rv);
464 #else
465   ASSERT_LABEL(rv, i_label);
466   ASSERT_EQ_ORIGIN(rv, str1[3]);
467 #endif
468 }
469 
test_strcasecmp()470 void test_strcasecmp() {
471   char str1[] = "str1", str2[] = "str2", str3[] = "Str1";
472   dfsan_set_label(i_label, &str1[3], 1);
473   dfsan_set_label(j_label, &str2[3], 1);
474   dfsan_set_label(j_label, &str3[2], 1);
475 
476   int rv = strcasecmp(str1, str2);
477   assert(rv < 0);
478 #ifdef STRICT_DATA_DEPENDENCIES
479   ASSERT_ZERO_LABEL(rv);
480 #else
481   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
482   ASSERT_EQ_ORIGIN(rv, str1[3]);
483 #endif
484 
485   rv = strcasecmp(str1, str3);
486   assert(rv == 0);
487 #ifdef STRICT_DATA_DEPENDENCIES
488   ASSERT_ZERO_LABEL(rv);
489 #else
490   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
491   ASSERT_EQ_ORIGIN(rv, str1[3]);
492 #endif
493 
494   char s1[] = "AbZ";
495   char s2[] = "aBy";
496   dfsan_set_label(i_label, &s1[2], 1);
497   dfsan_set_label(j_label, &s2[2], 1);
498 
499   rv = strcasecmp(s1, s2);
500   assert(rv > 0); // 'Z' > 'y'
501 #ifdef STRICT_DATA_DEPENDENCIES
502   ASSERT_ZERO_LABEL(rv);
503 #else
504   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
505   ASSERT_EQ_ORIGIN(rv, s1[2]);
506 #endif
507 }
508 
test_strncasecmp()509 void test_strncasecmp() {
510   char str1[] = "Str1", str2[] = "str2";
511   dfsan_set_label(i_label, &str1[3], 1);
512   dfsan_set_label(j_label, &str2[3], 1);
513 
514   int rv = strncasecmp(str1, str2, sizeof(str1));
515   assert(rv < 0);
516 #ifdef STRICT_DATA_DEPENDENCIES
517   ASSERT_ZERO_LABEL(rv);
518 #else
519   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
520   ASSERT_EQ_ORIGIN(rv, str1[3]);
521 #endif
522 
523   rv = strncasecmp(str1, str2, 3);
524   assert(rv == 0);
525   ASSERT_ZERO_LABEL(rv);
526 
527   char s1[] = "AbZ";
528   char s2[] = "aBy";
529   dfsan_set_label(i_label, &s1[2], 1);
530   dfsan_set_label(j_label, &s2[2], 1);
531 
532   rv = strncasecmp(s1, s2, 0);
533   assert(rv == 0); // Compare zero chars.
534   ASSERT_ZERO_LABEL(rv);
535 
536   rv = strncasecmp(s1, s2, 1);
537   assert(rv == 0); // 'A' == 'a'
538   ASSERT_ZERO_LABEL(rv);
539 
540   rv = strncasecmp(s1, s2, 2);
541   assert(rv == 0); // 'b' == 'B'
542   ASSERT_ZERO_LABEL(rv);
543 
544   rv = strncasecmp(s1, s2, 3);
545   assert(rv > 0); // 'Z' > 'y'
546 #ifdef STRICT_DATA_DEPENDENCIES
547   ASSERT_ZERO_LABEL(rv);
548 #else
549   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
550   ASSERT_EQ_ORIGIN(rv, s1[2]);
551 #endif
552 }
553 
test_strchr()554 void test_strchr() {
555   char str1[] = "str1";
556   dfsan_set_label(i_label, &str1[3], 1);
557 
558   char *p1 = str1;
559   char c = 'r';
560   dfsan_set_label(k_label, &c, sizeof(c));
561 
562   char *crv = strchr(p1, c);
563   assert(crv == &str1[2]);
564 #ifdef STRICT_DATA_DEPENDENCIES
565   ASSERT_ZERO_LABEL(crv);
566 #else
567   ASSERT_LABEL(crv, k_label);
568   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, c);
569 #endif
570 
571   dfsan_set_label(j_label, &p1, sizeof(p1));
572   crv = strchr(p1, 'r');
573   assert(crv == &str1[2]);
574   ASSERT_LABEL(crv, j_label);
575   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
576 
577   crv = strchr(p1, '1');
578   assert(crv == &str1[3]);
579 #ifdef STRICT_DATA_DEPENDENCIES
580   ASSERT_LABEL(crv, j_label);
581   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
582 #else
583   ASSERT_LABEL(crv, i_j_label);
584   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
585 #endif
586 
587   crv = strchr(p1, 'x');
588   assert(!crv);
589 #ifdef STRICT_DATA_DEPENDENCIES
590   ASSERT_LABEL(crv, j_label);
591   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
592 #else
593   ASSERT_LABEL(crv, i_j_label);
594   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
595 #endif
596 
597   // `man strchr` says:
598   // The terminating null byte is considered part of the string, so that if c
599   // is specified as '\0', these functions return a pointer to the terminator.
600   crv = strchr(p1, '\0');
601   assert(crv == &str1[4]);
602 #ifdef STRICT_DATA_DEPENDENCIES
603   ASSERT_LABEL(crv, j_label);
604   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
605 #else
606   ASSERT_LABEL(crv, i_j_label);
607   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
608 #endif
609 }
610 
test_recvmmsg()611 void test_recvmmsg() {
612   int sockfds[2];
613   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
614   assert(ret != -1);
615 
616   // Setup messages to send.
617   struct mmsghdr smmsg[2] = {};
618   char sbuf0[] = "abcdefghijkl";
619   struct iovec siov0[2] = {{&sbuf0[0], 4}, {&sbuf0[4], 4}};
620   smmsg[0].msg_hdr.msg_iov = siov0;
621   smmsg[0].msg_hdr.msg_iovlen = 2;
622   char sbuf1[] = "1234567890";
623   struct iovec siov1[1] = {{&sbuf1[0], 7}};
624   smmsg[1].msg_hdr.msg_iov = siov1;
625   smmsg[1].msg_hdr.msg_iovlen = 1;
626 
627   // Send messages.
628   int sent_msgs = sendmmsg(sockfds[0], smmsg, 2, 0);
629   assert(sent_msgs == 2);
630 
631   // Setup receive buffers.
632   struct mmsghdr rmmsg[2] = {};
633   char rbuf0[128];
634   struct iovec riov0[2] = {{&rbuf0[0], 4}, {&rbuf0[4], 4}};
635   rmmsg[0].msg_hdr.msg_iov = riov0;
636   rmmsg[0].msg_hdr.msg_iovlen = 2;
637   char rbuf1[128];
638   struct iovec riov1[1] = {{&rbuf1[0], 16}};
639   rmmsg[1].msg_hdr.msg_iov = riov1;
640   rmmsg[1].msg_hdr.msg_iovlen = 1;
641   struct timespec timeout = {1, 1};
642   dfsan_set_label(i_label, rbuf0, sizeof(rbuf0));
643   dfsan_set_label(i_label, rbuf1, sizeof(rbuf1));
644   dfsan_set_label(i_label, &rmmsg[0].msg_len, sizeof(rmmsg[0].msg_len));
645   dfsan_set_label(i_label, &rmmsg[1].msg_len, sizeof(rmmsg[1].msg_len));
646   dfsan_set_label(i_label, &timeout, sizeof(timeout));
647 
648   dfsan_origin msg_len0_o = dfsan_get_origin((long)(rmmsg[0].msg_len));
649   dfsan_origin msg_len1_o = dfsan_get_origin((long)(rmmsg[1].msg_len));
650 #ifndef ORIGIN_TRACKING
651   (void)msg_len0_o;
652   (void)msg_len1_o;
653 #endif
654 
655   // Receive messages and check labels.
656   int received_msgs = recvmmsg(sockfds[1], rmmsg, 2, 0, &timeout);
657   assert(received_msgs == sent_msgs);
658   assert(rmmsg[0].msg_len == smmsg[0].msg_len);
659   assert(rmmsg[1].msg_len == smmsg[1].msg_len);
660   assert(memcmp(sbuf0, rbuf0, 8) == 0);
661   assert(memcmp(sbuf1, rbuf1, 7) == 0);
662   ASSERT_ZERO_LABEL(received_msgs);
663   ASSERT_ZERO_LABEL(rmmsg[0].msg_len);
664   ASSERT_ZERO_LABEL(rmmsg[1].msg_len);
665   ASSERT_READ_ZERO_LABEL(&rbuf0[0], 8);
666   ASSERT_READ_LABEL(&rbuf0[8], 1, i_label);
667   ASSERT_READ_ZERO_LABEL(&rbuf1[0], 7);
668   ASSERT_READ_LABEL(&rbuf1[7], 1, i_label);
669   ASSERT_LABEL(timeout.tv_sec, i_label);
670   ASSERT_LABEL(timeout.tv_nsec, i_label);
671 
672   ASSERT_ORIGIN((long)(rmmsg[0].msg_len), msg_len0_o);
673   ASSERT_ORIGIN((long)(rmmsg[1].msg_len), msg_len1_o);
674 
675   close(sockfds[0]);
676   close(sockfds[1]);
677 }
678 
test_recvmsg()679 void test_recvmsg() {
680   int sockfds[2];
681   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
682   assert(ret != -1);
683 
684   char sbuf[] = "abcdefghijkl";
685   struct iovec siovs[2] = {{&sbuf[0], 4}, {&sbuf[4], 4}};
686   struct msghdr smsg = {};
687   smsg.msg_iov = siovs;
688   smsg.msg_iovlen = 2;
689 
690   ssize_t sent = sendmsg(sockfds[0], &smsg, 0);
691   assert(sent > 0);
692 
693   char rbuf[128];
694   struct iovec riovs[2] = {{&rbuf[0], 4}, {&rbuf[4], 4}};
695   struct msghdr rmsg = {};
696   rmsg.msg_iov = riovs;
697   rmsg.msg_iovlen = 2;
698 
699   dfsan_set_label(i_label, rbuf, sizeof(rbuf));
700   dfsan_set_label(i_label, &rmsg, sizeof(rmsg));
701 
702   DEFINE_AND_SAVE_ORIGINS(rmsg)
703 
704   ssize_t received = recvmsg(sockfds[1], &rmsg, 0);
705   assert(received == sent);
706   assert(memcmp(sbuf, rbuf, 8) == 0);
707   ASSERT_ZERO_LABEL(received);
708   ASSERT_READ_ZERO_LABEL(&rmsg, sizeof(rmsg));
709   ASSERT_READ_ZERO_LABEL(&rbuf[0], 8);
710   ASSERT_READ_LABEL(&rbuf[8], 1, i_label);
711 
712   ASSERT_SAVED_ORIGINS(rmsg)
713 
714   close(sockfds[0]);
715   close(sockfds[1]);
716 }
717 
test_read()718 void test_read() {
719   char buf[16];
720   dfsan_set_label(i_label, buf, 1);
721   dfsan_set_label(j_label, buf + 15, 1);
722 
723   DEFINE_AND_SAVE_ORIGINS(buf)
724   ASSERT_LABEL(buf[0], i_label);
725   ASSERT_LABEL(buf[15], j_label);
726 
727   int fd = open("/dev/zero", O_RDONLY);
728   int rv = read(fd, buf, sizeof(buf));
729   assert(rv == sizeof(buf));
730   ASSERT_ZERO_LABEL(rv);
731   ASSERT_ZERO_LABEL(buf[0]);
732   ASSERT_ZERO_LABEL(buf[15]);
733   ASSERT_SAVED_ORIGINS(buf)
734   close(fd);
735 }
736 
test_pread()737 void test_pread() {
738   char buf[16];
739   dfsan_set_label(i_label, buf, 1);
740   dfsan_set_label(j_label, buf + 15, 1);
741 
742   DEFINE_AND_SAVE_ORIGINS(buf)
743   ASSERT_LABEL(buf[0], i_label);
744   ASSERT_LABEL(buf[15], j_label);
745 
746   int fd = open("/bin/sh", O_RDONLY);
747   int rv = pread(fd, buf, sizeof(buf), 0);
748   assert(rv == sizeof(buf));
749   ASSERT_ZERO_LABEL(rv);
750   ASSERT_ZERO_LABEL(buf[0]);
751   ASSERT_ZERO_LABEL(buf[15]);
752   ASSERT_SAVED_ORIGINS(buf)
753   close(fd);
754 }
755 
test_dlopen()756 void test_dlopen() {
757   void *map = dlopen(NULL, RTLD_NOW);
758   assert(map);
759   ASSERT_ZERO_LABEL(map);
760   dlclose(map);
761   map = dlopen("/nonexistent", RTLD_NOW);
762   assert(!map);
763   ASSERT_ZERO_LABEL(map);
764 }
765 
test_clock_gettime()766 void test_clock_gettime() {
767   struct timespec tp;
768   dfsan_set_label(j_label, ((char *)&tp) + 3, 1);
769   dfsan_origin origin = dfsan_get_origin((long)(((char *)&tp)[3]));
770 #ifndef ORIGIN_TRACKING
771   (void)origin;
772 #endif
773   int t = clock_gettime(CLOCK_REALTIME, &tp);
774   assert(t == 0);
775   ASSERT_ZERO_LABEL(t);
776   ASSERT_ZERO_LABEL(((char *)&tp)[3]);
777   ASSERT_ORIGIN(((char *)&tp)[3], origin);
778 }
779 
test_ctime_r()780 void test_ctime_r() {
781   char *buf = (char*) malloc(64);
782   time_t t = 0;
783 
784   DEFINE_AND_SAVE_ORIGINS(buf)
785   dfsan_origin t_o = dfsan_get_origin((long)t);
786 
787   char *ret = ctime_r(&t, buf);
788   ASSERT_ZERO_LABEL(ret);
789   assert(buf == ret);
790   ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1);
791   ASSERT_SAVED_ORIGINS(buf)
792 
793   dfsan_set_label(i_label, &t, sizeof(t));
794   t_o = dfsan_get_origin((long)t);
795   ret = ctime_r(&t, buf);
796   ASSERT_ZERO_LABEL(ret);
797   ASSERT_READ_LABEL(buf, strlen(buf) + 1, i_label);
798   for (int i = 0; i < strlen(buf) + 1; ++i)
799     ASSERT_ORIGIN(buf[i], t_o);
800 
801   t = 0;
802   dfsan_set_label(j_label, &buf, sizeof(&buf));
803   dfsan_origin buf_ptr_o = dfsan_get_origin((long)buf);
804 #ifndef ORIGIN_TRACKING
805   (void)buf_ptr_o;
806 #endif
807   ret = ctime_r(&t, buf);
808   ASSERT_LABEL(ret, j_label);
809   ASSERT_ORIGIN(ret, buf_ptr_o);
810   ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1);
811   for (int i = 0; i < strlen(buf) + 1; ++i)
812     ASSERT_ORIGIN(buf[i], t_o);
813 }
814 
815 static int write_callback_count = 0;
816 static int last_fd;
817 static const unsigned char *last_buf;
818 static size_t last_count;
819 
write_callback(int fd,const void * buf,size_t count)820 void write_callback(int fd, const void *buf, size_t count) {
821   write_callback_count++;
822 
823   last_fd = fd;
824   last_buf = (const unsigned char*) buf;
825   last_count = count;
826 }
827 
test_dfsan_set_write_callback()828 void test_dfsan_set_write_callback() {
829   char buf[] = "Sample chars";
830   int buf_len = strlen(buf);
831 
832   int fd = open("/dev/null", O_WRONLY);
833 
834   dfsan_set_write_callback(write_callback);
835 
836   write_callback_count = 0;
837 
838   DEFINE_AND_SAVE_ORIGINS(buf)
839 
840   // Callback should be invoked on every call to write().
841   int res = write(fd, buf, buf_len);
842   assert(write_callback_count == 1);
843   ASSERT_READ_ZERO_LABEL(&res, sizeof(res));
844   ASSERT_READ_ZERO_LABEL(&last_fd, sizeof(last_fd));
845   ASSERT_READ_ZERO_LABEL(last_buf, sizeof(last_buf));
846   ASSERT_READ_ZERO_LABEL(&last_count, sizeof(last_count));
847 
848   for (int i = 0; i < buf_len; ++i)
849     ASSERT_ORIGIN(last_buf[i], buf_o[i]);
850 
851   ASSERT_ZERO_ORIGINS(&last_count, sizeof(last_count));
852 
853   // Add a label to write() arguments.  Check that the labels are readable from
854   // the values passed to the callback.
855   dfsan_set_label(i_label, &fd, sizeof(fd));
856   dfsan_set_label(j_label, &(buf[3]), 1);
857   dfsan_set_label(k_label, &buf_len, sizeof(buf_len));
858 
859   dfsan_origin fd_o = dfsan_get_origin((long)fd);
860   dfsan_origin buf3_o = dfsan_get_origin((long)(buf[3]));
861   dfsan_origin buf_len_o = dfsan_get_origin((long)buf_len);
862 #ifndef ORIGIN_TRACKING
863   (void)fd_o;
864   (void)buf3_o;
865   (void)buf_len_o;
866 #endif
867 
868   res = write(fd, buf, buf_len);
869   assert(write_callback_count == 2);
870   ASSERT_READ_ZERO_LABEL(&res, sizeof(res));
871   ASSERT_READ_LABEL(&last_fd, sizeof(last_fd), i_label);
872   ASSERT_READ_LABEL(&last_buf[3], sizeof(last_buf[3]), j_label);
873   ASSERT_READ_LABEL(last_buf, sizeof(last_buf), j_label);
874   ASSERT_READ_LABEL(&last_count, sizeof(last_count), k_label);
875   ASSERT_ZERO_ORIGINS(&res, sizeof(res));
876   ASSERT_INIT_ORIGINS(&last_fd, sizeof(last_fd), fd_o);
877   ASSERT_INIT_ORIGINS(&last_buf[3], sizeof(last_buf[3]), buf3_o);
878 
879   // Origins are assigned for every 4 contiguous 4-aligned bytes. After
880   // appending src to dst, origins of src can overwrite origins of dst if their
881   // application adddresses are within an aligned range. Other origins are not
882   // changed.
883   for (int i = 0; i < buf_len; ++i) {
884     size_t i_addr = size_t(&last_buf[i]);
885     if (((size_t(&last_buf[3]) & ~3UL) > i_addr) ||
886         (((size_t(&last_buf[3]) + 4) & ~3UL) <= i_addr))
887       ASSERT_ORIGIN(last_buf[i], buf_o[i]);
888   }
889 
890   ASSERT_INIT_ORIGINS(&last_count, sizeof(last_count), buf_len_o);
891 
892   dfsan_set_write_callback(NULL);
893 }
894 
test_fgets()895 void test_fgets() {
896   char *buf = (char*) malloc(128);
897   FILE *f = fopen("/etc/passwd", "r");
898   dfsan_set_label(j_label, buf, 1);
899   DEFINE_AND_SAVE_N_ORIGINS(buf, 128)
900 
901   char *ret = fgets(buf, sizeof(buf), f);
902   assert(ret == buf);
903   ASSERT_ZERO_LABEL(ret);
904   ASSERT_EQ_ORIGIN(ret, buf);
905   ASSERT_READ_ZERO_LABEL(buf, 128);
906   ASSERT_SAVED_N_ORIGINS(buf, 128)
907 
908   dfsan_set_label(j_label, &buf, sizeof(&buf));
909   ret = fgets(buf, sizeof(buf), f);
910   ASSERT_LABEL(ret, j_label);
911   ASSERT_EQ_ORIGIN(ret, buf);
912   ASSERT_SAVED_N_ORIGINS(buf, 128)
913 
914   fclose(f);
915   free(buf);
916 }
917 
test_getcwd()918 void test_getcwd() {
919   char buf[1024];
920   char *ptr = buf;
921   dfsan_set_label(i_label, buf + 2, 2);
922   DEFINE_AND_SAVE_ORIGINS(buf)
923 
924   char* ret = getcwd(buf, sizeof(buf));
925   assert(ret == buf);
926   assert(ret[0] == '/');
927   ASSERT_ZERO_LABEL(ret);
928   ASSERT_EQ_ORIGIN(ret, buf);
929   ASSERT_READ_ZERO_LABEL(buf + 2, 2);
930   ASSERT_SAVED_ORIGINS(buf)
931 
932   dfsan_set_label(i_label, &ptr, sizeof(ptr));
933   ret = getcwd(ptr, sizeof(buf));
934   ASSERT_LABEL(ret, i_label);
935   ASSERT_EQ_ORIGIN(ret, ptr);
936   ASSERT_SAVED_ORIGINS(buf)
937 }
938 
test_get_current_dir_name()939 void test_get_current_dir_name() {
940   char* ret = get_current_dir_name();
941   assert(ret);
942   assert(ret[0] == '/');
943   ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1);
944   ASSERT_ZERO_LABEL(ret);
945 }
946 
test_gethostname()947 void test_gethostname() {
948   char buf[1024];
949   dfsan_set_label(i_label, buf + 2, 2);
950   DEFINE_AND_SAVE_ORIGINS(buf)
951   int ret = gethostname(buf, sizeof(buf));
952   assert(ret == 0);
953   ASSERT_ZERO_LABEL(ret);
954   ASSERT_READ_ZERO_LABEL(buf + 2, 2);
955   ASSERT_SAVED_ORIGINS(buf)
956 }
957 
test_getrlimit()958 void test_getrlimit() {
959   struct rlimit rlim;
960   dfsan_set_label(i_label, &rlim, sizeof(rlim));
961   DEFINE_AND_SAVE_ORIGINS(rlim);
962   int ret = getrlimit(RLIMIT_CPU, &rlim);
963   assert(ret == 0);
964   ASSERT_ZERO_LABEL(ret);
965   ASSERT_READ_ZERO_LABEL(&rlim, sizeof(rlim));
966   ASSERT_SAVED_ORIGINS(rlim)
967 }
968 
test_getrusage()969 void test_getrusage() {
970   struct rusage usage;
971   dfsan_set_label(i_label, &usage, sizeof(usage));
972   DEFINE_AND_SAVE_ORIGINS(usage);
973   int ret = getrusage(RUSAGE_SELF, &usage);
974   assert(ret == 0);
975   ASSERT_ZERO_LABEL(ret);
976   ASSERT_READ_ZERO_LABEL(&usage, sizeof(usage));
977   ASSERT_SAVED_ORIGINS(usage)
978 }
979 
test_strcpy()980 void test_strcpy() {
981   char src[] = "hello world";
982   char dst[sizeof(src) + 2];
983   char *p_dst = dst;
984   dfsan_set_label(0, src, sizeof(src));
985   dfsan_set_label(0, dst, sizeof(dst));
986   dfsan_set_label(k_label, &p_dst, sizeof(p_dst));
987   dfsan_set_label(i_label, src + 2, 1);
988   dfsan_set_label(j_label, src + 3, 1);
989   dfsan_set_label(j_label, dst + 4, 1);
990   dfsan_set_label(i_label, dst + 12, 1);
991   char *ret = strcpy(p_dst, src);
992   assert(ret == dst);
993   assert(strcmp(src, dst) == 0);
994   ASSERT_LABEL(ret, k_label);
995   ASSERT_EQ_ORIGIN(ret, p_dst);
996   for (int i = 0; i < strlen(src) + 1; ++i) {
997     assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i]));
998     if (dfsan_get_label(dst[i]))
999       assert(dfsan_get_init_origin(&dst[i]) == dfsan_get_origin(src[i]));
1000   }
1001   // Note: if strlen(src) + 1 were used instead to compute the first untouched
1002   // byte of dest, the label would be I|J. This is because strlen() might
1003   // return a non-zero label, and because by default pointer labels are not
1004   // ignored on loads.
1005   ASSERT_LABEL(dst[12], i_label);
1006 }
1007 
test_strtol()1008 void test_strtol() {
1009   char non_number_buf[] = "ab ";
1010   char *endptr = NULL;
1011   long int ret = strtol(non_number_buf, &endptr, 10);
1012   assert(ret == 0);
1013   assert(endptr == non_number_buf);
1014   ASSERT_ZERO_LABEL(ret);
1015 
1016   char buf[] = "1234578910";
1017   int base = 10;
1018   dfsan_set_label(k_label, &base, sizeof(base));
1019   ret = strtol(buf, &endptr, base);
1020   assert(ret == 1234578910);
1021   assert(endptr == buf + 10);
1022   ASSERT_LABEL(ret, k_label);
1023   ASSERT_EQ_ORIGIN(ret, base);
1024 
1025   dfsan_set_label(i_label, buf + 1, 1);
1026   dfsan_set_label(j_label, buf + 10, 1);
1027   ret = strtol(buf, &endptr, 10);
1028   assert(ret == 1234578910);
1029   assert(endptr == buf + 10);
1030   ASSERT_LABEL(ret, i_j_label);
1031   ASSERT_EQ_ORIGIN(ret, buf[1]);
1032 }
1033 
test_strtoll()1034 void test_strtoll() {
1035   char non_number_buf[] = "ab ";
1036   char *endptr = NULL;
1037   long long int ret = strtoll(non_number_buf, &endptr, 10);
1038   assert(ret == 0);
1039   assert(endptr == non_number_buf);
1040   ASSERT_ZERO_LABEL(ret);
1041 
1042   char buf[] = "1234578910 ";
1043   int base = 10;
1044   dfsan_set_label(k_label, &base, sizeof(base));
1045   ret = strtoll(buf, &endptr, base);
1046   assert(ret == 1234578910);
1047   assert(endptr == buf + 10);
1048   ASSERT_LABEL(ret, k_label);
1049   ASSERT_EQ_ORIGIN(ret, base);
1050 
1051   dfsan_set_label(i_label, buf + 1, 1);
1052   dfsan_set_label(j_label, buf + 2, 1);
1053   ret = strtoll(buf, &endptr, 10);
1054   assert(ret == 1234578910);
1055   assert(endptr == buf + 10);
1056   ASSERT_LABEL(ret, i_j_label);
1057   ASSERT_EQ_ORIGIN(ret, buf[1]);
1058 }
1059 
test_strtoul()1060 void test_strtoul() {
1061   char non_number_buf[] = "xy ";
1062   char *endptr = NULL;
1063   long unsigned int ret = strtoul(non_number_buf, &endptr, 16);
1064   assert(ret == 0);
1065   assert(endptr == non_number_buf);
1066   ASSERT_ZERO_LABEL(ret);
1067 
1068   char buf[] = "ffffffffffffaa";
1069   int base = 16;
1070   dfsan_set_label(k_label, &base, sizeof(base));
1071   ret = strtoul(buf, &endptr, base);
1072   assert(ret == 72057594037927850);
1073   assert(endptr == buf + 14);
1074   ASSERT_LABEL(ret, k_label);
1075   ASSERT_EQ_ORIGIN(ret, base);
1076 
1077   dfsan_set_label(i_label, buf + 1, 1);
1078   dfsan_set_label(j_label, buf + 2, 1);
1079   ret = strtoul(buf, &endptr, 16);
1080   assert(ret == 72057594037927850);
1081   assert(endptr == buf + 14);
1082   ASSERT_LABEL(ret, i_j_label);
1083   ASSERT_EQ_ORIGIN(ret, buf[1]);
1084 }
1085 
test_strtoull()1086 void test_strtoull() {
1087   char non_number_buf[] = "xy ";
1088   char *endptr = NULL;
1089   long long unsigned int ret = strtoull(non_number_buf, &endptr, 16);
1090   assert(ret == 0);
1091   assert(endptr == non_number_buf);
1092   ASSERT_ZERO_LABEL(ret);
1093 
1094   char buf[] = "ffffffffffffffaa";
1095   int base = 16;
1096   dfsan_set_label(k_label, &base, sizeof(base));
1097   ret = strtoull(buf, &endptr, base);
1098   assert(ret == 0xffffffffffffffaa);
1099   assert(endptr == buf + 16);
1100   ASSERT_LABEL(ret, k_label);
1101   ASSERT_EQ_ORIGIN(ret, base);
1102 
1103   dfsan_set_label(i_label, buf + 1, 1);
1104   dfsan_set_label(j_label, buf + 2, 1);
1105   ret = strtoull(buf, &endptr, 16);
1106   assert(ret == 0xffffffffffffffaa);
1107   assert(endptr == buf + 16);
1108   ASSERT_LABEL(ret, i_j_label);
1109   ASSERT_EQ_ORIGIN(ret, buf[1]);
1110 }
1111 
test_strtod()1112 void test_strtod() {
1113   char non_number_buf[] = "ab ";
1114   char *endptr = NULL;
1115   double ret = strtod(non_number_buf, &endptr);
1116   assert(ret == 0);
1117   assert(endptr == non_number_buf);
1118   ASSERT_ZERO_LABEL(ret);
1119 
1120   char buf[] = "12345.76 foo";
1121   dfsan_set_label(i_label, buf + 1, 1);
1122   dfsan_set_label(j_label, buf + 6, 1);
1123   ret = strtod(buf, &endptr);
1124   assert(ret == 12345.76);
1125   assert(endptr == buf + 8);
1126   ASSERT_LABEL(ret, i_j_label);
1127   ASSERT_EQ_ORIGIN(ret, buf[1]);
1128 }
1129 
test_time()1130 void test_time() {
1131   time_t t = 0;
1132   dfsan_set_label(i_label, &t, 1);
1133   DEFINE_AND_SAVE_ORIGINS(t)
1134   time_t ret = time(&t);
1135   assert(ret == t);
1136   assert(ret > 0);
1137   ASSERT_ZERO_LABEL(ret);
1138   ASSERT_ZERO_LABEL(t);
1139   ASSERT_SAVED_ORIGINS(t)
1140 }
1141 
test_inet_pton()1142 void test_inet_pton() {
1143   char addr4[] = "127.0.0.1";
1144   dfsan_set_label(i_label, addr4 + 3, 1);
1145   struct in_addr in4;
1146   int ret4 = inet_pton(AF_INET, addr4, &in4);
1147   assert(ret4 == 1);
1148   ASSERT_ZERO_LABEL(ret4);
1149   ASSERT_READ_LABEL(&in4, sizeof(in4), i_label);
1150   ASSERT_ORIGINS(&in4, sizeof(in4), dfsan_get_origin((long)(addr4[3])))
1151   assert(in4.s_addr == htonl(0x7f000001));
1152 
1153   char addr6[] = "::1";
1154   dfsan_set_label(j_label, addr6 + 3, 1);
1155   struct in6_addr in6;
1156   int ret6 = inet_pton(AF_INET6, addr6, &in6);
1157   assert(ret6 == 1);
1158   ASSERT_ZERO_LABEL(ret6);
1159   ASSERT_READ_LABEL(((char *) &in6) + sizeof(in6) - 1, 1, j_label);
1160   ASSERT_ORIGINS(&in6, sizeof(in6), dfsan_get_origin((long)(addr6[3])))
1161 }
1162 
test_localtime_r()1163 void test_localtime_r() {
1164   time_t t0 = 1384800998;
1165   struct tm t1;
1166   dfsan_set_label(i_label, &t0, sizeof(t0));
1167   dfsan_origin t0_o = dfsan_get_origin((long)t0);
1168   struct tm *pt1 = &t1;
1169   dfsan_set_label(j_label, &pt1, sizeof(pt1));
1170   dfsan_origin pt1_o = dfsan_get_origin((long)pt1);
1171 
1172 #ifndef ORIGIN_TRACKING
1173   (void)t0_o;
1174   (void)pt1_o;
1175 #endif
1176 
1177   struct tm *ret = localtime_r(&t0, pt1);
1178   assert(ret == &t1);
1179   assert(t1.tm_min == 56);
1180   ASSERT_LABEL(ret, j_label);
1181   ASSERT_INIT_ORIGIN(&ret, pt1_o);
1182   ASSERT_READ_LABEL(&ret, sizeof(ret), j_label);
1183   ASSERT_LABEL(t1.tm_mon, i_label);
1184   ASSERT_ORIGIN(t1.tm_mon, t0_o);
1185 }
1186 
test_getpwuid_r()1187 void test_getpwuid_r() {
1188   struct passwd pwd;
1189   char buf[1024];
1190   struct passwd *result;
1191 
1192   dfsan_set_label(i_label, &pwd, 4);
1193   DEFINE_AND_SAVE_ORIGINS(pwd)
1194   DEFINE_AND_SAVE_ORIGINS(buf)
1195   int ret = getpwuid_r(0, &pwd, buf, sizeof(buf), &result);
1196   assert(ret == 0);
1197   assert(strcmp(pwd.pw_name, "root") == 0);
1198   assert(result == &pwd);
1199   ASSERT_ZERO_LABEL(ret);
1200   ASSERT_READ_ZERO_LABEL(&pwd, 4);
1201   ASSERT_SAVED_ORIGINS(pwd)
1202   ASSERT_SAVED_ORIGINS(buf)
1203 }
1204 
test_epoll_wait()1205 void test_epoll_wait() {
1206   // Set up a pipe to monitor with epoll.
1207   int pipe_fds[2];
1208   int ret = pipe(pipe_fds);
1209   assert(ret != -1);
1210 
1211   // Configure epoll to monitor the pipe.
1212   int epfd = epoll_create1(0);
1213   assert(epfd != -1);
1214   struct epoll_event event;
1215   event.events = EPOLLIN;
1216   event.data.fd = pipe_fds[0];
1217   ret = epoll_ctl(epfd, EPOLL_CTL_ADD, pipe_fds[0], &event);
1218   assert(ret != -1);
1219 
1220   // Test epoll_wait when no events have occurred.
1221   event = {};
1222   dfsan_set_label(i_label, &event, sizeof(event));
1223   DEFINE_AND_SAVE_ORIGINS(event)
1224   ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);
1225   assert(ret == 0);
1226   assert(event.events == 0);
1227   assert(event.data.fd == 0);
1228   ASSERT_ZERO_LABEL(ret);
1229   ASSERT_READ_LABEL(&event, sizeof(event), i_label);
1230   ASSERT_SAVED_ORIGINS(event)
1231 
1232   // Test epoll_wait when an event occurs.
1233   write(pipe_fds[1], "x", 1);
1234   ret = epoll_wait(epfd, &event, /*maxevents=*/1, /*timeout=*/0);
1235   assert(ret == 1);
1236   assert(event.events == EPOLLIN);
1237   assert(event.data.fd == pipe_fds[0]);
1238   ASSERT_ZERO_LABEL(ret);
1239   ASSERT_READ_ZERO_LABEL(&event, sizeof(event));
1240   ASSERT_SAVED_ORIGINS(event)
1241 
1242   // Clean up.
1243   close(epfd);
1244   close(pipe_fds[0]);
1245   close(pipe_fds[1]);
1246 }
1247 
test_poll()1248 void test_poll() {
1249   struct pollfd fd;
1250   fd.fd = 0;
1251   fd.events = POLLIN;
1252   dfsan_set_label(i_label, &fd.revents, sizeof(fd.revents));
1253   DEFINE_AND_SAVE_ORIGINS(fd)
1254   int ret = poll(&fd, 1, 1);
1255   ASSERT_ZERO_LABEL(ret);
1256   ASSERT_ZERO_LABEL(fd.revents);
1257   ASSERT_SAVED_ORIGINS(fd)
1258   assert(ret >= 0);
1259 }
1260 
test_select()1261 void test_select() {
1262   struct timeval t;
1263   fd_set fds;
1264   t.tv_sec = 2;
1265   FD_SET(0, &fds);
1266   dfsan_set_label(i_label, &fds, sizeof(fds));
1267   dfsan_set_label(j_label, &t, sizeof(t));
1268   DEFINE_AND_SAVE_ORIGINS(fds)
1269   DEFINE_AND_SAVE_ORIGINS(t)
1270   int ret = select(1, &fds, NULL, NULL, &t);
1271   assert(ret >= 0);
1272   ASSERT_ZERO_LABEL(ret);
1273   ASSERT_ZERO_LABEL(t.tv_sec);
1274   ASSERT_READ_ZERO_LABEL(&fds, sizeof(fds));
1275   ASSERT_SAVED_ORIGINS(fds)
1276   ASSERT_SAVED_ORIGINS(t)
1277 }
1278 
test_sched_getaffinity()1279 void test_sched_getaffinity() {
1280   cpu_set_t mask;
1281   dfsan_set_label(j_label, &mask, 1);
1282   DEFINE_AND_SAVE_ORIGINS(mask)
1283   int ret = sched_getaffinity(0, sizeof(mask), &mask);
1284   assert(ret == 0);
1285   ASSERT_ZERO_LABEL(ret);
1286   ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask));
1287   ASSERT_SAVED_ORIGINS(mask)
1288 }
1289 
test_sigemptyset()1290 void test_sigemptyset() {
1291   sigset_t set;
1292   dfsan_set_label(j_label, &set, 1);
1293   DEFINE_AND_SAVE_ORIGINS(set)
1294   int ret = sigemptyset(&set);
1295   assert(ret == 0);
1296   ASSERT_ZERO_LABEL(ret);
1297   ASSERT_READ_ZERO_LABEL(&set, sizeof(set));
1298   ASSERT_SAVED_ORIGINS(set)
1299 }
1300 
SignalHandler(int signo)1301 static void SignalHandler(int signo) {}
1302 
SignalAction(int signo,siginfo_t * si,void * uc)1303 static void SignalAction(int signo, siginfo_t *si, void *uc) {}
1304 
test_sigaction()1305 void test_sigaction() {
1306   struct sigaction newact_with_sigaction = {};
1307   newact_with_sigaction.sa_flags = SA_SIGINFO;
1308   newact_with_sigaction.sa_sigaction = SignalAction;
1309 
1310   // Set sigaction to be SignalAction, save the last one into origin_act
1311   struct sigaction origin_act;
1312   dfsan_set_label(j_label, &origin_act, 1);
1313   DEFINE_AND_SAVE_ORIGINS(origin_act)
1314   int ret = sigaction(SIGUSR1, &newact_with_sigaction, &origin_act);
1315   assert(ret == 0);
1316   ASSERT_ZERO_LABEL(ret);
1317   ASSERT_READ_ZERO_LABEL(&origin_act, sizeof(origin_act));
1318   ASSERT_SAVED_ORIGINS(origin_act)
1319 
1320   struct sigaction newact_with_sighandler = {};
1321   newact_with_sighandler.sa_handler = SignalHandler;
1322 
1323   // Set sigaction to be SignalHandler, check the last one is SignalAction
1324   struct sigaction oldact;
1325   assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));
1326   assert(oldact.sa_sigaction == SignalAction);
1327   assert(oldact.sa_flags & SA_SIGINFO);
1328 
1329   // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1330   newact_with_sighandler.sa_handler = SIG_IGN;
1331   assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));
1332   assert(oldact.sa_handler == SignalHandler);
1333   assert((oldact.sa_flags & SA_SIGINFO) == 0);
1334 
1335   newact_with_sighandler.sa_handler = SIG_DFL;
1336   assert(0 == sigaction(SIGUSR1, &newact_with_sighandler, &oldact));
1337   assert(oldact.sa_handler == SIG_IGN);
1338   assert((oldact.sa_flags & SA_SIGINFO) == 0);
1339 
1340   // Restore sigaction to the orginal setting, check the last one is SignalHandler
1341   assert(0 == sigaction(SIGUSR1, &origin_act, &oldact));
1342   assert(oldact.sa_handler == SIG_DFL);
1343   assert((oldact.sa_flags & SA_SIGINFO) == 0);
1344 }
1345 
test_signal()1346 void test_signal() {
1347   // Set signal to be SignalHandler, save the previous one into
1348   // old_signal_handler.
1349   sighandler_t old_signal_handler = signal(SIGHUP, SignalHandler);
1350   ASSERT_ZERO_LABEL(old_signal_handler);
1351 
1352   // Set SIG_IGN or SIG_DFL, and check the previous one is expected.
1353   assert(SignalHandler == signal(SIGHUP, SIG_DFL));
1354   assert(SIG_DFL == signal(SIGHUP, SIG_IGN));
1355 
1356   // Restore signal to old_signal_handler.
1357   assert(SIG_IGN == signal(SIGHUP, old_signal_handler));
1358 }
1359 
test_sigaltstack()1360 void test_sigaltstack() {
1361   stack_t old_altstack = {};
1362   dfsan_set_label(j_label, &old_altstack, sizeof(old_altstack));
1363   DEFINE_AND_SAVE_ORIGINS(old_altstack)
1364   int ret = sigaltstack(NULL, &old_altstack);
1365   assert(ret == 0);
1366   ASSERT_ZERO_LABEL(ret);
1367   ASSERT_READ_ZERO_LABEL(&old_altstack, sizeof(old_altstack));
1368   ASSERT_SAVED_ORIGINS(old_altstack)
1369 }
1370 
test_gettimeofday()1371 void test_gettimeofday() {
1372   struct timeval tv;
1373   struct timezone tz;
1374   dfsan_set_label(i_label, &tv, sizeof(tv));
1375   dfsan_set_label(j_label, &tz, sizeof(tz));
1376   DEFINE_AND_SAVE_ORIGINS(tv)
1377   DEFINE_AND_SAVE_ORIGINS(tz)
1378   int ret = gettimeofday(&tv, &tz);
1379   assert(ret == 0);
1380   ASSERT_READ_ZERO_LABEL(&tv, sizeof(tv));
1381   ASSERT_READ_ZERO_LABEL(&tz, sizeof(tz));
1382   ASSERT_SAVED_ORIGINS(tv)
1383   ASSERT_SAVED_ORIGINS(tz)
1384 }
1385 
pthread_create_test_cb(void * p)1386 void *pthread_create_test_cb(void *p) {
1387   assert(p == (void *)1);
1388   ASSERT_ZERO_LABEL(p);
1389   return (void *)2;
1390 }
1391 
test_pthread_create()1392 void test_pthread_create() {
1393   pthread_t pt;
1394   int create_ret = pthread_create(&pt, 0, pthread_create_test_cb, (void *)1);
1395   assert(create_ret == 0);
1396   ASSERT_ZERO_LABEL(create_ret);
1397   void *cbrv;
1398   dfsan_set_label(i_label, &cbrv, sizeof(cbrv));
1399   DEFINE_AND_SAVE_ORIGINS(cbrv)
1400   int joint_ret = pthread_join(pt, &cbrv);
1401   assert(joint_ret == 0);
1402   assert(cbrv == (void *)2);
1403   ASSERT_ZERO_LABEL(joint_ret);
1404   ASSERT_ZERO_LABEL(cbrv);
1405   ASSERT_SAVED_ORIGINS(cbrv);
1406 }
1407 
1408 // Tested by test_pthread_create().  This empty function is here to appease the
1409 // check-wrappers script.
test_pthread_join()1410 void test_pthread_join() {}
1411 
dl_iterate_phdr_test_cb(struct dl_phdr_info * info,size_t size,void * data)1412 int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size,
1413                             void *data) {
1414   assert(data == (void *)3);
1415   ASSERT_ZERO_LABEL(info);
1416   ASSERT_ZERO_LABEL(size);
1417   ASSERT_ZERO_LABEL(data);
1418   return 0;
1419 }
1420 
test_dl_iterate_phdr()1421 void test_dl_iterate_phdr() {
1422   dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3);
1423 }
1424 
1425 // On glibc < 2.27, this symbol is not available.  Mark it weak so we can skip
1426 // testing in this case.
1427 __attribute__((weak)) extern "C" void _dl_get_tls_static_info(size_t *sizep,
1428                                                               size_t *alignp);
1429 
test__dl_get_tls_static_info()1430 void test__dl_get_tls_static_info() {
1431   if (!_dl_get_tls_static_info)
1432     return;
1433   size_t sizep = 0, alignp = 0;
1434   dfsan_set_label(i_label, &sizep, sizeof(sizep));
1435   dfsan_set_label(i_label, &alignp, sizeof(alignp));
1436   dfsan_origin sizep_o = dfsan_get_origin(sizep);
1437   dfsan_origin alignp_o = dfsan_get_origin(alignp);
1438 #ifndef ORIGIN_TRACKING
1439   (void)sizep_o;
1440   (void)alignp_o;
1441 #endif
1442   _dl_get_tls_static_info(&sizep, &alignp);
1443   ASSERT_ZERO_LABEL(sizep);
1444   ASSERT_ZERO_LABEL(alignp);
1445   ASSERT_ORIGIN(sizep, sizep_o);
1446   ASSERT_ORIGIN(alignp, alignp_o);
1447 }
1448 
test_strrchr()1449 void test_strrchr() {
1450   char str1[] = "str1str1";
1451 
1452   char *p = str1;
1453   dfsan_set_label(j_label, &p, sizeof(p));
1454 
1455   char *rv = strrchr(p, 'r');
1456   assert(rv == &str1[6]);
1457   ASSERT_LABEL(rv, j_label);
1458   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p);
1459 
1460   char c = 'r';
1461   dfsan_set_label(k_label, &c, sizeof(c));
1462   rv = strrchr(str1, c);
1463   assert(rv == &str1[6]);
1464 #ifdef STRICT_DATA_DEPENDENCIES
1465   ASSERT_ZERO_LABEL(rv);
1466 #else
1467   ASSERT_LABEL(rv, k_label);
1468   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, c);
1469 #endif
1470 
1471   dfsan_set_label(i_label, &str1[7], 1);
1472 
1473   rv = strrchr(str1, 'r');
1474   assert(rv == &str1[6]);
1475 #ifdef STRICT_DATA_DEPENDENCIES
1476   ASSERT_ZERO_LABEL(rv);
1477 #else
1478   ASSERT_LABEL(rv, i_label);
1479   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[7]);
1480 #endif
1481 }
1482 
test_strstr()1483 void test_strstr() {
1484   char str1[] = "str1str1";
1485 
1486   char *p1 = str1;
1487   dfsan_set_label(k_label, &p1, sizeof(p1));
1488   char *rv = strstr(p1, "1s");
1489   assert(rv == &str1[3]);
1490   ASSERT_LABEL(rv, k_label);
1491   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p1);
1492 
1493   char str2[] = "1s";
1494   char *p2 = str2;
1495   dfsan_set_label(m_label, &p2, sizeof(p2));
1496   rv = strstr(str1, p2);
1497   assert(rv == &str1[3]);
1498 #ifdef STRICT_DATA_DEPENDENCIES
1499   ASSERT_ZERO_LABEL(rv);
1500 #else
1501   ASSERT_LABEL(rv, m_label);
1502   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p2);
1503 #endif
1504 
1505   dfsan_set_label(n_label, &str2[0], 1);
1506   rv = strstr(str1, str2);
1507   assert(rv == &str1[3]);
1508 #ifdef STRICT_DATA_DEPENDENCIES
1509   ASSERT_ZERO_LABEL(rv);
1510 #else
1511   ASSERT_LABEL(rv, n_label);
1512   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str2[0]);
1513 #endif
1514 
1515   dfsan_set_label(i_label, &str1[3], 1);
1516   dfsan_set_label(j_label, &str1[5], 1);
1517 
1518   rv = strstr(str1, "1s");
1519   assert(rv == &str1[3]);
1520 #ifdef STRICT_DATA_DEPENDENCIES
1521   ASSERT_ZERO_LABEL(rv);
1522 #else
1523   ASSERT_LABEL(rv, i_label);
1524   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);
1525 #endif
1526 
1527   rv = strstr(str1, "2s");
1528   assert(rv == NULL);
1529 #ifdef STRICT_DATA_DEPENDENCIES
1530   ASSERT_ZERO_LABEL(rv);
1531 #else
1532   ASSERT_LABEL(rv, i_j_label);
1533   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, str1[3]);
1534 #endif
1535 }
1536 
test_strpbrk()1537 void test_strpbrk() {
1538   char s[] = "abcdefg";
1539   char accept[] = "123fd";
1540 
1541   char *p_s = s;
1542   char *p_accept = accept;
1543 
1544   dfsan_set_label(n_label, &p_accept, sizeof(p_accept));
1545 
1546   char *rv = strpbrk(p_s, p_accept);
1547   assert(rv == &s[3]);
1548 #ifdef STRICT_DATA_DEPENDENCIES
1549   ASSERT_ZERO_LABEL(rv);
1550 #else
1551   ASSERT_LABEL(rv, n_label);
1552   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_accept);
1553 #endif
1554 
1555   dfsan_set_label(m_label, &p_s, sizeof(p_s));
1556 
1557   rv = strpbrk(p_s, p_accept);
1558   assert(rv == &s[3]);
1559 #ifdef STRICT_DATA_DEPENDENCIES
1560   ASSERT_LABEL(rv, m_label);
1561   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
1562 #else
1563   ASSERT_LABEL(rv, dfsan_union(m_label, n_label));
1564   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
1565 #endif
1566 
1567   dfsan_set_label(i_label, &s[5], 1);
1568   dfsan_set_label(j_label, &accept[1], 1);
1569 
1570   rv = strpbrk(s, accept);
1571   assert(rv == &s[3]);
1572 #ifdef STRICT_DATA_DEPENDENCIES
1573   ASSERT_ZERO_LABEL(rv);
1574 #else
1575   ASSERT_LABEL(rv, j_label);
1576   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, accept[1]);
1577 #endif
1578 
1579   char *ps = s;
1580   dfsan_set_label(j_label, &ps, sizeof(ps));
1581 
1582   rv = strpbrk(ps, "123gf");
1583   assert(rv == &s[5]);
1584 #ifdef STRICT_DATA_DEPENDENCIES
1585   ASSERT_LABEL(rv, j_label);
1586 #else
1587   ASSERT_LABEL(rv, i_j_label);
1588   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
1589 #endif
1590 
1591   rv = strpbrk(ps, "123");
1592   assert(rv == NULL);
1593 #ifdef STRICT_DATA_DEPENDENCIES
1594   ASSERT_ZERO_LABEL(rv);
1595 #else
1596   ASSERT_LABEL(rv, i_j_label);
1597   ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
1598 #endif
1599 }
1600 
test_memchr()1601 void test_memchr() {
1602   char str1[] = "str1";
1603   dfsan_set_label(i_label, &str1[3], 1);
1604   dfsan_set_label(j_label, &str1[4], 1);
1605 
1606   char *crv = (char *) memchr(str1, 'r', sizeof(str1));
1607   assert(crv == &str1[2]);
1608   ASSERT_ZERO_LABEL(crv);
1609 
1610   char c = 'r';
1611   dfsan_set_label(k_label, &c, sizeof(c));
1612   crv = (char *)memchr(str1, c, sizeof(str1));
1613   assert(crv == &str1[2]);
1614 #ifdef STRICT_DATA_DEPENDENCIES
1615   ASSERT_ZERO_LABEL(crv);
1616 #else
1617   ASSERT_LABEL(crv, k_label);
1618   ASSERT_EQ_ORIGIN(crv, c);
1619 #endif
1620 
1621   char *ptr = str1;
1622   dfsan_set_label(k_label, &ptr, sizeof(ptr));
1623   crv = (char *)memchr(ptr, 'r', sizeof(str1));
1624   assert(crv == &str1[2]);
1625   ASSERT_LABEL(crv, k_label);
1626   ASSERT_EQ_ORIGIN(crv, ptr);
1627 
1628   crv = (char *) memchr(str1, '1', sizeof(str1));
1629   assert(crv == &str1[3]);
1630 #ifdef STRICT_DATA_DEPENDENCIES
1631   ASSERT_ZERO_LABEL(crv);
1632 #else
1633   ASSERT_LABEL(crv, i_label);
1634   ASSERT_EQ_ORIGIN(crv, str1[3]);
1635 #endif
1636 
1637   crv = (char *) memchr(str1, 'x', sizeof(str1));
1638   assert(!crv);
1639 #ifdef STRICT_DATA_DEPENDENCIES
1640   ASSERT_ZERO_LABEL(crv);
1641 #else
1642   ASSERT_LABEL(crv, i_j_label);
1643   ASSERT_EQ_ORIGIN(crv, str1[3]);
1644 #endif
1645 }
1646 
alarm_handler(int unused)1647 void alarm_handler(int unused) {
1648   ;
1649 }
1650 
test_nanosleep()1651 void test_nanosleep() {
1652   struct timespec req, rem;
1653   req.tv_sec = 1;
1654   req.tv_nsec = 0;
1655   dfsan_set_label(i_label, &rem, sizeof(rem));
1656   DEFINE_AND_SAVE_ORIGINS(rem)
1657 
1658   // non interrupted
1659   int rv = nanosleep(&req, &rem);
1660   assert(rv == 0);
1661   ASSERT_ZERO_LABEL(rv);
1662   ASSERT_READ_LABEL(&rem, 1, i_label);
1663   ASSERT_SAVED_ORIGINS(rem)
1664 
1665   // interrupted by an alarm
1666   signal(SIGALRM, alarm_handler);
1667   req.tv_sec = 3;
1668   alarm(1);
1669   rv = nanosleep(&req, &rem);
1670   assert(rv == -1);
1671   ASSERT_ZERO_LABEL(rv);
1672   ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem));
1673   ASSERT_SAVED_ORIGINS(rem)
1674 }
1675 
test_socketpair()1676 void test_socketpair() {
1677   int fd[2];
1678   dfsan_origin fd_o[2];
1679 
1680   dfsan_set_label(i_label, fd, sizeof(fd));
1681   fd_o[0] = dfsan_get_origin((long)(fd[0]));
1682   fd_o[1] = dfsan_get_origin((long)(fd[1]));
1683   int rv = socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);
1684   assert(rv == 0);
1685   ASSERT_ZERO_LABEL(rv);
1686   ASSERT_READ_ZERO_LABEL(fd, sizeof(fd));
1687   ASSERT_ORIGIN(fd[0], fd_o[0]);
1688   ASSERT_ORIGIN(fd[1], fd_o[1]);
1689 }
1690 
test_getpeername()1691 void test_getpeername() {
1692   int sockfds[2];
1693   int ret = socketpair(AF_UNIX, SOCK_DGRAM, 0, sockfds);
1694   assert(ret != -1);
1695 
1696   struct sockaddr addr = {};
1697   socklen_t addrlen = sizeof(addr);
1698   dfsan_set_label(i_label, &addr, addrlen);
1699   dfsan_set_label(i_label, &addrlen, sizeof(addrlen));
1700   DEFINE_AND_SAVE_ORIGINS(addr)
1701   DEFINE_AND_SAVE_ORIGINS(addrlen)
1702 
1703   ret = getpeername(sockfds[0], &addr, &addrlen);
1704   assert(ret != -1);
1705   ASSERT_ZERO_LABEL(ret);
1706   ASSERT_ZERO_LABEL(addrlen);
1707   assert(addrlen < sizeof(addr));
1708   ASSERT_READ_ZERO_LABEL(&addr, addrlen);
1709   ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label);
1710   ASSERT_SAVED_ORIGINS(addr)
1711   ASSERT_SAVED_ORIGINS(addrlen)
1712 
1713   close(sockfds[0]);
1714   close(sockfds[1]);
1715 }
1716 
test_getsockname()1717 void test_getsockname() {
1718   int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
1719   assert(sockfd != -1);
1720 
1721   struct sockaddr addr = {};
1722   socklen_t addrlen = sizeof(addr);
1723   dfsan_set_label(i_label, &addr, addrlen);
1724   dfsan_set_label(i_label, &addrlen, sizeof(addrlen));
1725   DEFINE_AND_SAVE_ORIGINS(addr)
1726   DEFINE_AND_SAVE_ORIGINS(addrlen)
1727   int ret = getsockname(sockfd, &addr, &addrlen);
1728   assert(ret != -1);
1729   ASSERT_ZERO_LABEL(ret);
1730   ASSERT_ZERO_LABEL(addrlen);
1731   assert(addrlen < sizeof(addr));
1732   ASSERT_READ_ZERO_LABEL(&addr, addrlen);
1733   ASSERT_READ_LABEL(((char *)&addr) + addrlen, 1, i_label);
1734   ASSERT_SAVED_ORIGINS(addr)
1735   ASSERT_SAVED_ORIGINS(addrlen)
1736 
1737   close(sockfd);
1738 }
1739 
test_getsockopt()1740 void test_getsockopt() {
1741   int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
1742   assert(sockfd != -1);
1743 
1744   int optval[2] = {-1, -1};
1745   socklen_t optlen = sizeof(optval);
1746   dfsan_set_label(i_label, &optval, sizeof(optval));
1747   dfsan_set_label(i_label, &optlen, sizeof(optlen));
1748   DEFINE_AND_SAVE_ORIGINS(optval)
1749   DEFINE_AND_SAVE_ORIGINS(optlen)
1750   int ret = getsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen);
1751   assert(ret != -1);
1752   assert(optlen == sizeof(int));
1753   assert(optval[0] == 0);
1754   assert(optval[1] == -1);
1755   ASSERT_ZERO_LABEL(ret);
1756   ASSERT_ZERO_LABEL(optlen);
1757   ASSERT_ZERO_LABEL(optval[0]);
1758   ASSERT_LABEL(optval[1], i_label);
1759   ASSERT_SAVED_ORIGINS(optval)
1760   ASSERT_SAVED_ORIGINS(optlen)
1761 
1762   close(sockfd);
1763 }
1764 
test_write()1765 void test_write() {
1766   int fd = open("/dev/null", O_WRONLY);
1767 
1768   char buf[] = "a string";
1769   int len = strlen(buf);
1770 
1771   // The result of a write always unlabeled.
1772   int res = write(fd, buf, len);
1773   assert(res > 0);
1774   ASSERT_ZERO_LABEL(res);
1775 
1776   // Label all arguments to write().
1777   dfsan_set_label(i_label, &(buf[3]), 1);
1778   dfsan_set_label(j_label, &fd, sizeof(fd));
1779   dfsan_set_label(i_label, &len, sizeof(len));
1780 
1781   // The value returned by write() should have no label.
1782   res = write(fd, buf, len);
1783   ASSERT_ZERO_LABEL(res);
1784 
1785   close(fd);
1786 }
1787 
1788 template <class T>
test_sprintf_chunk(const char * expected,const char * format,T arg)1789 void test_sprintf_chunk(const char* expected, const char* format, T arg) {
1790   char buf[512];
1791   memset(buf, 'a', sizeof(buf));
1792 
1793   char padded_expected[512];
1794   strcpy(padded_expected, "foo ");
1795   strcat(padded_expected, expected);
1796   strcat(padded_expected, " bar");
1797 
1798   char padded_format[512];
1799   strcpy(padded_format, "foo ");
1800   strcat(padded_format, format);
1801   strcat(padded_format, " bar");
1802 
1803   // Non labelled arg.
1804   assert(sprintf(buf, padded_format,  arg) == strlen(padded_expected));
1805   assert(strcmp(buf, padded_expected) == 0);
1806   ASSERT_READ_LABEL(buf, strlen(padded_expected), 0);
1807   memset(buf, 'a', sizeof(buf));
1808 
1809   // Labelled arg.
1810   dfsan_set_label(i_label, &arg, sizeof(arg));
1811   dfsan_origin a_o = dfsan_get_origin((long)(arg));
1812 #ifndef ORIGIN_TRACKING
1813   (void)a_o;
1814 #endif
1815   assert(sprintf(buf, padded_format,  arg) == strlen(padded_expected));
1816   assert(strcmp(buf, padded_expected) == 0);
1817   ASSERT_READ_LABEL(buf, 4, 0);
1818   ASSERT_READ_LABEL(buf + 4, strlen(padded_expected) - 8, i_label);
1819   ASSERT_INIT_ORIGINS(buf + 4, strlen(padded_expected) - 8, a_o);
1820   ASSERT_READ_LABEL(buf + (strlen(padded_expected) - 4), 4, 0);
1821 }
1822 
test_sprintf()1823 void test_sprintf() {
1824   char buf[2048];
1825   memset(buf, 'a', sizeof(buf));
1826 
1827   // Test formatting (no conversion specifier).
1828   assert(sprintf(buf, "Hello world!") == 12);
1829   assert(strcmp(buf, "Hello world!") == 0);
1830   ASSERT_READ_LABEL(buf, sizeof(buf), 0);
1831 
1832   // Test for extra arguments.
1833   assert(sprintf(buf, "Hello world!", 42, "hello") == 12);
1834   assert(strcmp(buf, "Hello world!") == 0);
1835   ASSERT_READ_LABEL(buf, sizeof(buf), 0);
1836 
1837   // Test formatting & label propagation (multiple conversion specifiers): %s,
1838   // %d, %n, %f, and %%.
1839   const char* s = "world";
1840   int m = 8;
1841   int d = 27;
1842   dfsan_set_label(k_label, (void *) (s + 1), 2);
1843   dfsan_origin s_o = dfsan_get_origin((long)(s[1]));
1844   dfsan_set_label(i_label, &m, sizeof(m));
1845   dfsan_origin m_o = dfsan_get_origin((long)m);
1846   dfsan_set_label(j_label, &d, sizeof(d));
1847   dfsan_origin d_o = dfsan_get_origin((long)d);
1848 #ifndef ORIGIN_TRACKING
1849   (void)s_o;
1850   (void)m_o;
1851   (void)d_o;
1852 #endif
1853   int n;
1854   int r = sprintf(buf, "hello %s, %-d/%d/%d %f %% %n%d", s, 2014, m, d,
1855                   12345.6781234, &n, 1000);
1856   assert(r == 42);
1857   assert(strcmp(buf, "hello world, 2014/8/27 12345.678123 % 1000") == 0);
1858   ASSERT_READ_LABEL(buf, 7, 0);
1859   ASSERT_READ_LABEL(buf + 7, 2, k_label);
1860   ASSERT_INIT_ORIGINS(buf + 7, 2, s_o);
1861   ASSERT_READ_LABEL(buf + 9, 9, 0);
1862   ASSERT_READ_LABEL(buf + 18, 1, i_label);
1863   ASSERT_INIT_ORIGINS(buf + 18, 1, m_o);
1864   ASSERT_READ_LABEL(buf + 19, 1, 0);
1865   ASSERT_READ_LABEL(buf + 20, 2, j_label);
1866   ASSERT_INIT_ORIGINS(buf + 20, 2, d_o);
1867   ASSERT_READ_LABEL(buf + 22, 15, 0);
1868   ASSERT_LABEL(r, 0);
1869   assert(n == 38);
1870 
1871   // Test formatting & label propagation (single conversion specifier, with
1872   // additional length and precision modifiers).
1873   test_sprintf_chunk("-559038737", "%d", 0xdeadbeef);
1874   test_sprintf_chunk("3735928559", "%u", 0xdeadbeef);
1875   test_sprintf_chunk("12345", "%i", 12345);
1876   test_sprintf_chunk("751", "%o", 0751);
1877   test_sprintf_chunk("babe", "%x", 0xbabe);
1878   test_sprintf_chunk("0000BABE", "%.8X", 0xbabe);
1879   test_sprintf_chunk("-17", "%hhd", 0xdeadbeef);
1880   test_sprintf_chunk("-16657", "%hd", 0xdeadbeef);
1881   test_sprintf_chunk("deadbeefdeadbeef", "%lx", 0xdeadbeefdeadbeef);
1882   test_sprintf_chunk("0xdeadbeefdeadbeef", "%p",
1883                  (void *)  0xdeadbeefdeadbeef);
1884   test_sprintf_chunk("18446744073709551615", "%ju", (intmax_t) -1);
1885   test_sprintf_chunk("18446744073709551615", "%zu", (size_t) -1);
1886   test_sprintf_chunk("18446744073709551615", "%tu", (size_t) -1);
1887 
1888   test_sprintf_chunk("0x1.f9acffa7eb6bfp-4", "%a", 0.123456);
1889   test_sprintf_chunk("0X1.F9ACFFA7EB6BFP-4", "%A", 0.123456);
1890   test_sprintf_chunk("0.12346", "%.5f", 0.123456);
1891   test_sprintf_chunk("0.123456", "%g", 0.123456);
1892   test_sprintf_chunk("1.234560e-01", "%e", 0.123456);
1893   test_sprintf_chunk("1.234560E-01", "%E", 0.123456);
1894   test_sprintf_chunk("0.1234567891234560", "%.16Lf",
1895                      (long double) 0.123456789123456);
1896 
1897   test_sprintf_chunk("z", "%c", 'z');
1898 
1899   // %n, %s, %d, %f, and %% already tested
1900 
1901   // Test formatting with width passed as an argument.
1902   r = sprintf(buf, "hi %*d my %*s friend %.*f", 3, 1, 6, "dear", 4, 3.14159265359);
1903   assert(r == 30);
1904   assert(strcmp(buf, "hi   1 my   dear friend 3.1416") == 0);
1905 }
1906 
test_snprintf()1907 void test_snprintf() {
1908   char buf[2048];
1909   memset(buf, 'a', sizeof(buf));
1910   dfsan_set_label(0, buf, sizeof(buf));
1911   const char* s = "world";
1912   int y = 2014;
1913   int m = 8;
1914   int d = 27;
1915   dfsan_set_label(k_label, (void *) (s + 1), 2);
1916   dfsan_origin s_o = dfsan_get_origin((long)(s[1]));
1917   dfsan_set_label(i_label, &y, sizeof(y));
1918   dfsan_origin y_o = dfsan_get_origin((long)y);
1919   dfsan_set_label(j_label, &m, sizeof(m));
1920   dfsan_origin m_o = dfsan_get_origin((long)m);
1921 #ifndef ORIGIN_TRACKING
1922   (void)s_o;
1923   (void)y_o;
1924   (void)m_o;
1925 #endif
1926   int r = snprintf(buf, 19, "hello %s, %-d/   %d/%d %f", s, y, m, d,
1927                    12345.6781234);
1928   // The return value is the number of bytes that would have been written to
1929   // the final string if enough space had been available.
1930   assert(r == 38);
1931   assert(memcmp(buf, "hello world, 2014/", 19) == 0);
1932   ASSERT_READ_LABEL(buf, 7, 0);
1933   ASSERT_READ_LABEL(buf + 7, 2, k_label);
1934   ASSERT_INIT_ORIGINS(buf + 7, 2, s_o);
1935   ASSERT_READ_LABEL(buf + 9, 4, 0);
1936   ASSERT_READ_LABEL(buf + 13, 4, i_label);
1937   ASSERT_INIT_ORIGINS(buf + 13, 4, y_o);
1938   ASSERT_READ_LABEL(buf + 17, 2, 0);
1939   ASSERT_LABEL(r, 0);
1940 }
1941 
1942 // Tested by a seperate source file.  This empty function is here to appease the
1943 // check-wrappers script.
test_fork()1944 void test_fork() {}
1945 
main(void)1946 int main(void) {
1947   i_label = 1;
1948   j_label = 2;
1949   k_label = 4;
1950   m_label = 8;
1951   n_label = 16;
1952   i_j_label = dfsan_union(i_label, j_label);
1953   assert(i_j_label != i_label);
1954   assert(i_j_label != j_label);
1955   assert(i_j_label != k_label);
1956 
1957   test__dl_get_tls_static_info();
1958   test_bcmp();
1959   test_clock_gettime();
1960   test_ctime_r();
1961   test_dfsan_set_write_callback();
1962   test_dl_iterate_phdr();
1963   test_dlopen();
1964   test_epoll_wait();
1965   test_fgets();
1966   test_fork();
1967   test_fstat();
1968   test_get_current_dir_name();
1969   test_getcwd();
1970   test_gethostname();
1971   test_getpeername();
1972   test_getpwuid_r();
1973   test_getrlimit();
1974   test_getrusage();
1975   test_getsockname();
1976   test_getsockopt();
1977   test_gettimeofday();
1978   test_inet_pton();
1979   test_localtime_r();
1980   test_memchr();
1981   test_memcmp();
1982   test_memcpy();
1983   test_memmove();
1984   test_memset();
1985   test_nanosleep();
1986   test_poll();
1987   test_pread();
1988   test_pthread_create();
1989   test_pthread_join();
1990   test_read();
1991   test_recvmmsg();
1992   test_recvmsg();
1993   test_sched_getaffinity();
1994   test_select();
1995   test_sigaction();
1996   test_signal();
1997   test_sigaltstack();
1998   test_sigemptyset();
1999   test_snprintf();
2000   test_socketpair();
2001   test_sprintf();
2002   test_stat();
2003   test_strcasecmp();
2004   test_strchr();
2005   test_strcmp();
2006   test_strcat();
2007   test_strcpy();
2008   test_strdup();
2009   test_strlen();
2010   test_strncasecmp();
2011   test_strncmp();
2012   test_strncpy();
2013   test_strpbrk();
2014   test_strrchr();
2015   test_strstr();
2016   test_strtod();
2017   test_strtol();
2018   test_strtoll();
2019   test_strtoul();
2020   test_strtoull();
2021   test_time();
2022   test_write();
2023 }
2024