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