custom.c revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
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 31dfsan_label i_label = 0; 32dfsan_label j_label = 0; 33dfsan_label k_label = 0; 34dfsan_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 48void 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 62void 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 74void 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 88void 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 99void 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 111void 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 125void 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 138void 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 148void 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 171void 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 189void 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 212void 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 230void 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 255void 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 269void 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 286void 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 303void 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 313void 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 322void 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 343static int write_callback_count = 0; 344static int last_fd; 345static const void *last_buf; 346static size_t last_count; 347 348void 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 356void 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 391void 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 405void 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 418void 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 425void 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 432void 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 439void 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 446void 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 468void 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 479void 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 490void 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 501void 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 512void 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 523void 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 532void 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 549void 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 559void 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 572void 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 582void 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 595void 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 603void 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 611void 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 619void 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 630void *pthread_create_test_cb(void *p) { 631 assert(p == (void *)1); 632 ASSERT_ZERO_LABEL(p); 633 return (void *)2; 634} 635 636void 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 644int 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 653void test_dl_iterate_phdr() { 654 dl_iterate_phdr(dl_iterate_phdr_test_cb, (void *)3); 655} 656 657void 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 670void 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 692void 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 718void alarm_handler(int unused) { 719 ; 720} 721 722void 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 744void 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 754void 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 777int 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