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