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