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