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