1 // RUN: %clang_dfsan -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t 2 // RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t 3 // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -m64 %s -o %t && %run %t 4 // RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t 5 6 // Tests custom implementations of various glibc functions. 7 8 #define _GNU_SOURCE 9 #include <sanitizer/dfsan_interface.h> 10 11 #include <arpa/inet.h> 12 #include <assert.h> 13 #include <fcntl.h> 14 #include <link.h> 15 #include <poll.h> 16 #include <pthread.h> 17 #include <pwd.h> 18 #include <sched.h> 19 #include <signal.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <sys/select.h> 24 #include <sys/resource.h> 25 #include <sys/stat.h> 26 #include <sys/time.h> 27 #include <sys/types.h> 28 #include <time.h> 29 #include <unistd.h> 30 31 dfsan_label i_label = 0; 32 dfsan_label j_label = 0; 33 dfsan_label k_label = 0; 34 dfsan_label i_j_label = 0; 35 36 #define ASSERT_ZERO_LABEL(data) \ 37 assert(0 == dfsan_get_label((long) (data))) 38 39 #define ASSERT_READ_ZERO_LABEL(ptr, size) \ 40 assert(0 == dfsan_read_label(ptr, size)) 41 42 #define ASSERT_LABEL(data, label) \ 43 assert(label == dfsan_get_label((long) (data))) 44 45 #define ASSERT_READ_LABEL(ptr, size, label) \ 46 assert(label == dfsan_read_label(ptr, size)) 47 48 void test_stat() { 49 int i = 1; 50 dfsan_set_label(i_label, &i, sizeof(i)); 51 52 struct stat s; 53 s.st_dev = i; 54 assert(0 == stat("/", &s)); 55 ASSERT_ZERO_LABEL(s.st_dev); 56 57 s.st_dev = i; 58 assert(-1 == stat("/nonexistent", &s)); 59 ASSERT_LABEL(s.st_dev, i_label); 60 } 61 62 void test_fstat() { 63 int i = 1; 64 dfsan_set_label(i_label, &i, sizeof(i)); 65 66 struct stat s; 67 int fd = open("/dev/zero", O_RDONLY); 68 s.st_dev = i; 69 int rv = fstat(fd, &s); 70 assert(0 == rv); 71 ASSERT_ZERO_LABEL(s.st_dev); 72 } 73 74 void test_memcmp() { 75 char str1[] = "str1", str2[] = "str2"; 76 dfsan_set_label(i_label, &str1[3], 1); 77 dfsan_set_label(j_label, &str2[3], 1); 78 79 int rv = memcmp(str1, str2, sizeof(str1)); 80 assert(rv < 0); 81 #ifdef STRICT_DATA_DEPENDENCIES 82 ASSERT_ZERO_LABEL(rv); 83 #else 84 ASSERT_LABEL(rv, i_j_label); 85 #endif 86 } 87 88 void test_memcpy() { 89 char str1[] = "str1"; 90 char str2[sizeof(str1)]; 91 dfsan_set_label(i_label, &str1[3], 1); 92 93 ASSERT_ZERO_LABEL(memcpy(str2, str1, sizeof(str1))); 94 assert(0 == memcmp(str2, str1, sizeof(str1))); 95 ASSERT_ZERO_LABEL(str2[0]); 96 ASSERT_LABEL(str2[3], i_label); 97 } 98 99 void test_memset() { 100 char buf[8]; 101 int j = 'a'; 102 dfsan_set_label(j_label, &j, sizeof(j)); 103 104 ASSERT_ZERO_LABEL(memset(&buf, j, sizeof(buf))); 105 for (int i = 0; i < 8; ++i) { 106 ASSERT_LABEL(buf[i], j_label); 107 assert(buf[i] == 'a'); 108 } 109 } 110 111 void test_strcmp() { 112 char str1[] = "str1", str2[] = "str2"; 113 dfsan_set_label(i_label, &str1[3], 1); 114 dfsan_set_label(j_label, &str2[3], 1); 115 116 int rv = strcmp(str1, str2); 117 assert(rv < 0); 118 #ifdef STRICT_DATA_DEPENDENCIES 119 ASSERT_ZERO_LABEL(rv); 120 #else 121 ASSERT_LABEL(rv, i_j_label); 122 #endif 123 } 124 125 void test_strlen() { 126 char str1[] = "str1"; 127 dfsan_set_label(i_label, &str1[3], 1); 128 129 int rv = strlen(str1); 130 assert(rv == 4); 131 #ifdef STRICT_DATA_DEPENDENCIES 132 ASSERT_ZERO_LABEL(rv); 133 #else 134 ASSERT_LABEL(rv, i_label); 135 #endif 136 } 137 138 void test_strdup() { 139 char str1[] = "str1"; 140 dfsan_set_label(i_label, &str1[3], 1); 141 142 char *strd = strdup(str1); 143 ASSERT_ZERO_LABEL(strd[0]); 144 ASSERT_LABEL(strd[3], i_label); 145 free(strd); 146 } 147 148 void test_strncpy() { 149 char str1[] = "str1"; 150 char str2[sizeof(str1)]; 151 dfsan_set_label(i_label, &str1[3], 1); 152 153 char *strd = strncpy(str2, str1, 5); 154 assert(strd == str2); 155 assert(strcmp(str1, str2) == 0); 156 ASSERT_ZERO_LABEL(strd); 157 ASSERT_ZERO_LABEL(strd[0]); 158 ASSERT_ZERO_LABEL(strd[1]); 159 ASSERT_ZERO_LABEL(strd[2]); 160 ASSERT_LABEL(strd[3], i_label); 161 162 strd = strncpy(str2, str1, 3); 163 assert(strd == str2); 164 assert(strncmp(str1, str2, 3) == 0); 165 ASSERT_ZERO_LABEL(strd); 166 ASSERT_ZERO_LABEL(strd[0]); 167 ASSERT_ZERO_LABEL(strd[1]); 168 ASSERT_ZERO_LABEL(strd[2]); 169 } 170 171 void test_strncmp() { 172 char str1[] = "str1", str2[] = "str2"; 173 dfsan_set_label(i_label, &str1[3], 1); 174 dfsan_set_label(j_label, &str2[3], 1); 175 176 int rv = strncmp(str1, str2, sizeof(str1)); 177 assert(rv < 0); 178 #ifdef STRICT_DATA_DEPENDENCIES 179 ASSERT_ZERO_LABEL(rv); 180 #else 181 ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); 182 #endif 183 184 rv = strncmp(str1, str2, 3); 185 assert(rv == 0); 186 ASSERT_ZERO_LABEL(rv); 187 } 188 189 void test_strcasecmp() { 190 char str1[] = "str1", str2[] = "str2", str3[] = "Str1"; 191 dfsan_set_label(i_label, &str1[3], 1); 192 dfsan_set_label(j_label, &str2[3], 1); 193 dfsan_set_label(j_label, &str3[2], 1); 194 195 int rv = strcasecmp(str1, str2); 196 assert(rv < 0); 197 #ifdef STRICT_DATA_DEPENDENCIES 198 ASSERT_ZERO_LABEL(rv); 199 #else 200 ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); 201 #endif 202 203 rv = strcasecmp(str1, str3); 204 assert(rv == 0); 205 #ifdef STRICT_DATA_DEPENDENCIES 206 ASSERT_ZERO_LABEL(rv); 207 #else 208 ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); 209 #endif 210 } 211 212 void test_strncasecmp() { 213 char str1[] = "Str1", str2[] = "str2"; 214 dfsan_set_label(i_label, &str1[3], 1); 215 dfsan_set_label(j_label, &str2[3], 1); 216 217 int rv = strncasecmp(str1, str2, sizeof(str1)); 218 assert(rv < 0); 219 #ifdef STRICT_DATA_DEPENDENCIES 220 ASSERT_ZERO_LABEL(rv); 221 #else 222 ASSERT_LABEL(rv, dfsan_union(i_label, j_label)); 223 #endif 224 225 rv = strncasecmp(str1, str2, 3); 226 assert(rv == 0); 227 ASSERT_ZERO_LABEL(rv); 228 } 229 230 void test_strchr() { 231 char str1[] = "str1"; 232 dfsan_set_label(i_label, &str1[3], 1); 233 234 char *crv = strchr(str1, 'r'); 235 assert(crv == &str1[2]); 236 ASSERT_ZERO_LABEL(crv); 237 238 crv = strchr(str1, '1'); 239 assert(crv == &str1[3]); 240 #ifdef STRICT_DATA_DEPENDENCIES 241 ASSERT_ZERO_LABEL(crv); 242 #else 243 ASSERT_LABEL(crv, i_label); 244 #endif 245 246 crv = strchr(str1, 'x'); 247 assert(!crv); 248 #ifdef STRICT_DATA_DEPENDENCIES 249 ASSERT_ZERO_LABEL(crv); 250 #else 251 ASSERT_LABEL(crv, i_label); 252 #endif 253 } 254 255 void test_calloc() { 256 // With any luck this sequence of calls will cause calloc to return the same 257 // pointer both times. This is probably the best we can do to test this 258 // function. 259 char *crv = calloc(4096, 1); 260 ASSERT_ZERO_LABEL(crv[0]); 261 dfsan_set_label(i_label, crv, 100); 262 free(crv); 263 264 crv = calloc(4096, 1); 265 ASSERT_ZERO_LABEL(crv[0]); 266 free(crv); 267 } 268 269 void test_read() { 270 char buf[16]; 271 dfsan_set_label(i_label, buf, 1); 272 dfsan_set_label(j_label, buf + 15, 1); 273 274 ASSERT_LABEL(buf[0], i_label); 275 ASSERT_LABEL(buf[15], j_label); 276 277 int fd = open("/dev/zero", O_RDONLY); 278 int rv = read(fd, buf, sizeof(buf)); 279 assert(rv == sizeof(buf)); 280 ASSERT_ZERO_LABEL(rv); 281 ASSERT_ZERO_LABEL(buf[0]); 282 ASSERT_ZERO_LABEL(buf[15]); 283 close(fd); 284 } 285 286 void test_pread() { 287 char buf[16]; 288 dfsan_set_label(i_label, buf, 1); 289 dfsan_set_label(j_label, buf + 15, 1); 290 291 ASSERT_LABEL(buf[0], i_label); 292 ASSERT_LABEL(buf[15], j_label); 293 294 int fd = open("/bin/sh", O_RDONLY); 295 int rv = pread(fd, buf, sizeof(buf), 0); 296 assert(rv == sizeof(buf)); 297 ASSERT_ZERO_LABEL(rv); 298 ASSERT_ZERO_LABEL(buf[0]); 299 ASSERT_ZERO_LABEL(buf[15]); 300 close(fd); 301 } 302 303 void test_dlopen() { 304 void *map = dlopen(NULL, RTLD_NOW); 305 assert(map); 306 ASSERT_ZERO_LABEL(map); 307 dlclose(map); 308 map = dlopen("/nonexistent", RTLD_NOW); 309 assert(!map); 310 ASSERT_ZERO_LABEL(map); 311 } 312 313 void test_clock_gettime() { 314 struct timespec tp; 315 dfsan_set_label(j_label, ((char *)&tp) + 3, 1); 316 int t = clock_gettime(CLOCK_REALTIME, &tp); 317 assert(t == 0); 318 ASSERT_ZERO_LABEL(t); 319 ASSERT_ZERO_LABEL(((char *)&tp)[3]); 320 } 321 322 void test_ctime_r() { 323 char *buf = (char*) malloc(64); 324 time_t t = 0; 325 326 char *ret = ctime_r(&t, buf); 327 ASSERT_ZERO_LABEL(ret); 328 assert(buf == ret); 329 ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); 330 331 dfsan_set_label(i_label, &t, sizeof(t)); 332 ret = ctime_r(&t, buf); 333 ASSERT_ZERO_LABEL(ret); 334 ASSERT_READ_LABEL(buf, strlen(buf) + 1, i_label); 335 336 t = 0; 337 dfsan_set_label(j_label, &buf, sizeof(&buf)); 338 ret = ctime_r(&t, buf); 339 ASSERT_LABEL(ret, j_label); 340 ASSERT_READ_ZERO_LABEL(buf, strlen(buf) + 1); 341 } 342 343 static int write_callback_count = 0; 344 static int last_fd; 345 static const void *last_buf; 346 static size_t last_count; 347 348 void write_callback(int fd, const void *buf, size_t count) { 349 write_callback_count++; 350 351 last_fd = fd; 352 last_buf = buf; 353 last_count = count; 354 } 355 356 void test_dfsan_set_write_callback() { 357 char buf[] = "Sample chars"; 358 int buf_len = strlen(buf); 359 360 int fd = open("/dev/null", O_WRONLY); 361 362 dfsan_set_write_callback(write_callback); 363 364 write_callback_count = 0; 365 366 // Callback should be invoked on every call to write(). 367 int res = write(fd, buf, buf_len); 368 assert(write_callback_count == 1); 369 ASSERT_READ_ZERO_LABEL(&res, sizeof(res)); 370 ASSERT_READ_ZERO_LABEL(&last_fd, sizeof(last_fd)); 371 ASSERT_READ_ZERO_LABEL(last_buf, sizeof(last_buf)); 372 ASSERT_READ_ZERO_LABEL(&last_count, sizeof(last_count)); 373 374 // Add a label to write() arguments. Check that the labels are readable from 375 // the values passed to the callback. 376 dfsan_set_label(i_label, &fd, sizeof(fd)); 377 dfsan_set_label(j_label, &(buf[3]), 1); 378 dfsan_set_label(k_label, &buf_len, sizeof(buf_len)); 379 380 res = write(fd, buf, buf_len); 381 assert(write_callback_count == 2); 382 ASSERT_READ_ZERO_LABEL(&res, sizeof(res)); 383 ASSERT_READ_LABEL(&last_fd, sizeof(last_fd), i_label); 384 ASSERT_READ_LABEL(&last_buf[3], sizeof(last_buf[3]), j_label); 385 ASSERT_READ_LABEL(last_buf, sizeof(last_buf), j_label); 386 ASSERT_READ_LABEL(&last_count, sizeof(last_count), k_label); 387 388 dfsan_set_write_callback(NULL); 389 } 390 391 void test_fgets() { 392 char *buf = (char*) malloc(128); 393 FILE *f = fopen("/etc/passwd", "r"); 394 dfsan_set_label(j_label, buf, 1); 395 char *ret = fgets(buf, sizeof(buf), f); 396 assert(ret == buf); 397 ASSERT_ZERO_LABEL(ret); 398 ASSERT_READ_ZERO_LABEL(buf, 128); 399 dfsan_set_label(j_label, &buf, sizeof(&buf)); 400 ret = fgets(buf, sizeof(buf), f); 401 ASSERT_LABEL(ret, j_label); 402 fclose(f); 403 } 404 405 void test_getcwd() { 406 char buf[1024]; 407 char *ptr = buf; 408 dfsan_set_label(i_label, buf + 2, 2); 409 char* ret = getcwd(buf, sizeof(buf)); 410 assert(ret == buf); 411 assert(ret[0] == '/'); 412 ASSERT_READ_ZERO_LABEL(buf + 2, 2); 413 dfsan_set_label(i_label, &ptr, sizeof(ptr)); 414 ret = getcwd(ptr, sizeof(buf)); 415 ASSERT_LABEL(ret, i_label); 416 } 417 418 void test_get_current_dir_name() { 419 char* ret = get_current_dir_name(); 420 assert(ret); 421 assert(ret[0] == '/'); 422 ASSERT_READ_ZERO_LABEL(ret, strlen(ret) + 1); 423 } 424 425 void test_gethostname() { 426 char buf[1024]; 427 dfsan_set_label(i_label, buf + 2, 2); 428 assert(gethostname(buf, sizeof(buf)) == 0); 429 ASSERT_READ_ZERO_LABEL(buf + 2, 2); 430 } 431 432 void test_getrlimit() { 433 struct rlimit rlim; 434 dfsan_set_label(i_label, &rlim, sizeof(rlim)); 435 assert(getrlimit(RLIMIT_CPU, &rlim) == 0); 436 ASSERT_READ_ZERO_LABEL(&rlim, sizeof(rlim)); 437 } 438 439 void test_getrusage() { 440 struct rusage usage; 441 dfsan_set_label(i_label, &usage, sizeof(usage)); 442 assert(getrusage(RUSAGE_SELF, &usage) == 0); 443 ASSERT_READ_ZERO_LABEL(&usage, sizeof(usage)); 444 } 445 446 void test_strcpy() { 447 char src[] = "hello world"; 448 char dst[sizeof(src) + 2]; 449 dfsan_set_label(0, src, sizeof(src)); 450 dfsan_set_label(0, dst, sizeof(dst)); 451 dfsan_set_label(i_label, src + 2, 1); 452 dfsan_set_label(j_label, src + 3, 1); 453 dfsan_set_label(j_label, dst + 4, 1); 454 dfsan_set_label(i_label, dst + 12, 1); 455 char *ret = strcpy(dst, src); 456 assert(ret == dst); 457 assert(strcmp(src, dst) == 0); 458 for (int i = 0; i < strlen(src) + 1; ++i) { 459 assert(dfsan_get_label(dst[i]) == dfsan_get_label(src[i])); 460 } 461 // Note: if strlen(src) + 1 were used instead to compute the first untouched 462 // byte of dest, the label would be I|J. This is because strlen() might 463 // return a non-zero label, and because by default pointer labels are not 464 // ignored on loads. 465 ASSERT_LABEL(dst[12], i_label); 466 } 467 468 void test_strtol() { 469 char buf[] = "1234578910"; 470 char *endptr = NULL; 471 dfsan_set_label(i_label, buf + 1, 1); 472 dfsan_set_label(j_label, buf + 10, 1); 473 long int ret = strtol(buf, &endptr, 10); 474 assert(ret == 1234578910); 475 assert(endptr == buf + 10); 476 ASSERT_LABEL(ret, i_j_label); 477 } 478 479 void test_strtoll() { 480 char buf[] = "1234578910 "; 481 char *endptr = NULL; 482 dfsan_set_label(i_label, buf + 1, 1); 483 dfsan_set_label(j_label, buf + 2, 1); 484 long long int ret = strtoll(buf, &endptr, 10); 485 assert(ret == 1234578910); 486 assert(endptr == buf + 10); 487 ASSERT_LABEL(ret, i_j_label); 488 } 489 490 void test_strtoul() { 491 char buf[] = "0xffffffffffffaa"; 492 char *endptr = NULL; 493 dfsan_set_label(i_label, buf + 1, 1); 494 dfsan_set_label(j_label, buf + 2, 1); 495 long unsigned int ret = strtol(buf, &endptr, 16); 496 assert(ret == 72057594037927850); 497 assert(endptr == buf + 16); 498 ASSERT_LABEL(ret, i_j_label); 499 } 500 501 void test_strtoull() { 502 char buf[] = "0xffffffffffffffaa"; 503 char *endptr = NULL; 504 dfsan_set_label(i_label, buf + 1, 1); 505 dfsan_set_label(j_label, buf + 2, 1); 506 long long unsigned int ret = strtoull(buf, &endptr, 16); 507 assert(ret == 0xffffffffffffffaa); 508 assert(endptr == buf + 18); 509 ASSERT_LABEL(ret, i_j_label); 510 } 511 512 void test_strtod() { 513 char buf[] = "12345.76 foo"; 514 char *endptr = NULL; 515 dfsan_set_label(i_label, buf + 1, 1); 516 dfsan_set_label(j_label, buf + 6, 1); 517 double ret = strtod(buf, &endptr); 518 assert(ret == 12345.76); 519 assert(endptr == buf + 8); 520 ASSERT_LABEL(ret, i_j_label); 521 } 522 523 void test_time() { 524 time_t t = 0; 525 dfsan_set_label(i_label, &t, 1); 526 time_t ret = time(&t); 527 assert(ret == t); 528 assert(ret > 0); 529 ASSERT_ZERO_LABEL(t); 530 } 531 532 void test_inet_pton() { 533 char addr4[] = "127.0.0.1"; 534 dfsan_set_label(i_label, addr4 + 3, 1); 535 struct in_addr in4; 536 int ret4 = inet_pton(AF_INET, addr4, &in4); 537 assert(ret4 == 1); 538 ASSERT_READ_LABEL(&in4, sizeof(in4), i_label); 539 assert(in4.s_addr == 0x0100007f); 540 541 char addr6[] = "::1"; 542 dfsan_set_label(j_label, addr6 + 3, 1); 543 struct in6_addr in6; 544 int ret6 = inet_pton(AF_INET6, addr6, &in6); 545 assert(ret6 == 1); 546 ASSERT_READ_LABEL(((char *) &in6) + sizeof(in6) - 1, 1, j_label); 547 } 548 549 void test_localtime_r() { 550 time_t t0 = 1384800998; 551 struct tm t1; 552 dfsan_set_label(i_label, &t0, sizeof(t0)); 553 struct tm* ret = localtime_r(&t0, &t1); 554 assert(ret == &t1); 555 assert(t1.tm_min == 56); 556 ASSERT_LABEL(t1.tm_mon, i_label); 557 } 558 559 void test_getpwuid_r() { 560 struct passwd pwd; 561 char buf[1024]; 562 struct passwd *result; 563 564 dfsan_set_label(i_label, &pwd, 4); 565 int ret = getpwuid_r(0, &pwd, buf, sizeof(buf), &result); 566 assert(ret == 0); 567 assert(strcmp(pwd.pw_name, "root") == 0); 568 assert(result == &pwd); 569 ASSERT_READ_ZERO_LABEL(&pwd, 4); 570 } 571 572 void test_poll() { 573 struct pollfd fd; 574 fd.fd = 0; 575 fd.events = POLLIN; 576 dfsan_set_label(i_label, &fd.revents, sizeof(fd.revents)); 577 int ret = poll(&fd, 1, 1); 578 ASSERT_ZERO_LABEL(fd.revents); 579 assert(ret >= 0); 580 } 581 582 void test_select() { 583 struct timeval t; 584 fd_set fds; 585 t.tv_sec = 2; 586 FD_SET(0, &fds); 587 dfsan_set_label(i_label, &fds, sizeof(fds)); 588 dfsan_set_label(j_label, &t, sizeof(t)); 589 int ret = select(1, &fds, NULL, NULL, &t); 590 assert(ret >= 0); 591 ASSERT_ZERO_LABEL(t.tv_sec); 592 ASSERT_READ_ZERO_LABEL(&fds, sizeof(fds)); 593 } 594 595 void test_sched_getaffinity() { 596 cpu_set_t mask; 597 dfsan_set_label(j_label, &mask, 1); 598 int ret = sched_getaffinity(0, sizeof(mask), &mask); 599 assert(ret == 0); 600 ASSERT_READ_ZERO_LABEL(&mask, sizeof(mask)); 601 } 602 603 void test_sigemptyset() { 604 sigset_t set; 605 dfsan_set_label(j_label, &set, 1); 606 int ret = sigemptyset(&set); 607 assert(ret == 0); 608 ASSERT_READ_ZERO_LABEL(&set, sizeof(set)); 609 } 610 611 void test_sigaction() { 612 struct sigaction oldact; 613 dfsan_set_label(j_label, &oldact, 1); 614 int ret = sigaction(SIGUSR1, NULL, &oldact); 615 assert(ret == 0); 616 ASSERT_READ_ZERO_LABEL(&oldact, sizeof(oldact)); 617 } 618 619 void test_gettimeofday() { 620 struct timeval tv; 621 struct timezone tz; 622 dfsan_set_label(i_label, &tv, sizeof(tv)); 623 dfsan_set_label(j_label, &tz, sizeof(tz)); 624 int ret = gettimeofday(&tv, &tz); 625 assert(ret == 0); 626 ASSERT_READ_ZERO_LABEL(&tv, sizeof(tv)); 627 ASSERT_READ_ZERO_LABEL(&tz, sizeof(tz)); 628 } 629 630 void *pthread_create_test_cb(void *p) { 631 assert(p == (void *)1); 632 ASSERT_ZERO_LABEL(p); 633 return (void *)2; 634 } 635 636 void test_pthread_create() { 637 pthread_t pt; 638 pthread_create(&pt, 0, pthread_create_test_cb, (void *)1); 639 void *cbrv; 640 pthread_join(pt, &cbrv); 641 assert(cbrv == (void *)2); 642 } 643 644 int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size, 645 void *data) { 646 assert(data == (void *)3); 647 ASSERT_ZERO_LABEL(info); 648 ASSERT_ZERO_LABEL(size); 649 ASSERT_ZERO_LABEL(data); 650 return 0; 651 } 652 653 void test_dl_iterate_phdr() { 654 dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3); 655 } 656 657 void test_strrchr() { 658 char str1[] = "str1str1"; 659 dfsan_set_label(i_label, &str1[7], 1); 660 661 char *rv = strrchr(str1, 'r'); 662 assert(rv == &str1[6]); 663 #ifdef STRICT_DATA_DEPENDENCIES 664 ASSERT_ZERO_LABEL(rv); 665 #else 666 ASSERT_LABEL(rv, i_label); 667 #endif 668 } 669 670 void test_strstr() { 671 char str1[] = "str1str1"; 672 dfsan_set_label(i_label, &str1[3], 1); 673 dfsan_set_label(j_label, &str1[5], 1); 674 675 char *rv = strstr(str1, "1s"); 676 assert(rv == &str1[3]); 677 #ifdef STRICT_DATA_DEPENDENCIES 678 ASSERT_ZERO_LABEL(rv); 679 #else 680 ASSERT_LABEL(rv, i_label); 681 #endif 682 683 rv = strstr(str1, "2s"); 684 assert(rv == NULL); 685 #ifdef STRICT_DATA_DEPENDENCIES 686 ASSERT_ZERO_LABEL(rv); 687 #else 688 ASSERT_LABEL(rv, i_j_label); 689 #endif 690 } 691 692 void test_memchr() { 693 char str1[] = "str1"; 694 dfsan_set_label(i_label, &str1[3], 1); 695 dfsan_set_label(j_label, &str1[4], 1); 696 697 char *crv = memchr(str1, 'r', sizeof(str1)); 698 assert(crv == &str1[2]); 699 ASSERT_ZERO_LABEL(crv); 700 701 crv = memchr(str1, '1', sizeof(str1)); 702 assert(crv == &str1[3]); 703 #ifdef STRICT_DATA_DEPENDENCIES 704 ASSERT_ZERO_LABEL(crv); 705 #else 706 ASSERT_LABEL(crv, i_label); 707 #endif 708 709 crv = memchr(str1, 'x', sizeof(str1)); 710 assert(!crv); 711 #ifdef STRICT_DATA_DEPENDENCIES 712 ASSERT_ZERO_LABEL(crv); 713 #else 714 ASSERT_LABEL(crv, i_j_label); 715 #endif 716 } 717 718 void alarm_handler(int unused) { 719 ; 720 } 721 722 void test_nanosleep() { 723 struct timespec req, rem; 724 req.tv_sec = 1; 725 req.tv_nsec = 0; 726 dfsan_set_label(i_label, &rem, sizeof(rem)); 727 728 // non interrupted 729 int rv = nanosleep(&req, &rem); 730 assert(rv == 0); 731 ASSERT_ZERO_LABEL(rv); 732 ASSERT_READ_LABEL(&rem, 1, i_label); 733 734 // interrupted by an alarm 735 signal(SIGALRM, alarm_handler); 736 req.tv_sec = 3; 737 alarm(1); 738 rv = nanosleep(&req, &rem); 739 assert(rv == -1); 740 ASSERT_ZERO_LABEL(rv); 741 ASSERT_READ_ZERO_LABEL(&rem, sizeof(rem)); 742 } 743 744 void test_socketpair() { 745 int fd[2]; 746 747 dfsan_set_label(i_label, fd, sizeof(fd)); 748 int rv = socketpair(PF_LOCAL, SOCK_STREAM, 0, fd); 749 assert(rv == 0); 750 ASSERT_ZERO_LABEL(rv); 751 ASSERT_READ_ZERO_LABEL(fd, sizeof(fd)); 752 } 753 754 void test_write() { 755 int fd = open("/dev/null", O_WRONLY); 756 757 char buf[] = "a string"; 758 int len = strlen(buf); 759 760 // The result of a write always unlabeled. 761 int res = write(fd, buf, len); 762 assert(res > 0); 763 ASSERT_ZERO_LABEL(res); 764 765 // Label all arguments to write(). 766 dfsan_set_label(i_label, &(buf[3]), 1); 767 dfsan_set_label(j_label, &fd, sizeof(fd)); 768 dfsan_set_label(i_label, &len, sizeof(len)); 769 770 // The value returned by write() should have no label. 771 res = write(fd, buf, len); 772 ASSERT_ZERO_LABEL(res); 773 774 close(fd); 775 } 776 777 int main(void) { 778 i_label = dfsan_create_label("i", 0); 779 j_label = dfsan_create_label("j", 0); 780 k_label = dfsan_create_label("k", 0); 781 i_j_label = dfsan_union(i_label, j_label); 782 783 test_calloc(); 784 test_clock_gettime(); 785 test_ctime_r(); 786 test_dfsan_set_write_callback(); 787 test_dl_iterate_phdr(); 788 test_dlopen(); 789 test_fgets(); 790 test_fstat(); 791 test_get_current_dir_name(); 792 test_getcwd(); 793 test_gethostname(); 794 test_getpwuid_r(); 795 test_getrlimit(); 796 test_getrusage(); 797 test_gettimeofday(); 798 test_inet_pton(); 799 test_localtime_r(); 800 test_memchr(); 801 test_memcmp(); 802 test_memcpy(); 803 test_memset(); 804 test_nanosleep(); 805 test_poll(); 806 test_pread(); 807 test_pthread_create(); 808 test_read(); 809 test_sched_getaffinity(); 810 test_select(); 811 test_sigaction(); 812 test_sigemptyset(); 813 test_socketpair(); 814 test_stat(); 815 test_strcasecmp(); 816 test_strchr(); 817 test_strcmp(); 818 test_strcpy(); 819 test_strdup(); 820 test_strlen(); 821 test_strncasecmp(); 822 test_strncmp(); 823 test_strncpy(); 824 test_strrchr(); 825 test_strstr(); 826 test_strtod(); 827 test_strtol(); 828 test_strtoll(); 829 test_strtoul(); 830 test_strtoull(); 831 test_time(); 832 test_write(); 833 } 834