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