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