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