1 //===-- dfsan.cc ----------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of DataFlowSanitizer. 11 // 12 // This file defines the custom functions listed in done_abilist.txt. 13 //===----------------------------------------------------------------------===// 14 15 #include "sanitizer_common/sanitizer_internal_defs.h" 16 #include "sanitizer_common/sanitizer_linux.h" 17 18 #include "dfsan/dfsan.h" 19 20 #include <arpa/inet.h> 21 #include <ctype.h> 22 #include <dlfcn.h> 23 #include <link.h> 24 #include <poll.h> 25 #include <pthread.h> 26 #include <pwd.h> 27 #include <sched.h> 28 #include <signal.h> 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <sys/resource.h> 33 #include <sys/select.h> 34 #include <sys/stat.h> 35 #include <sys/time.h> 36 #include <sys/types.h> 37 #include <time.h> 38 #include <unistd.h> 39 40 using namespace __dfsan; 41 42 extern "C" { 43 SANITIZER_INTERFACE_ATTRIBUTE int 44 __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label, 45 dfsan_label buf_label, dfsan_label *ret_label) { 46 int ret = stat(path, buf); 47 if (ret == 0) 48 dfsan_set_label(0, buf, sizeof(struct stat)); 49 *ret_label = 0; 50 return ret; 51 } 52 53 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf, 54 dfsan_label fd_label, 55 dfsan_label buf_label, 56 dfsan_label *ret_label) { 57 int ret = fstat(fd, buf); 58 if (ret == 0) 59 dfsan_set_label(0, buf, sizeof(struct stat)); 60 *ret_label = 0; 61 return ret; 62 } 63 64 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, 65 dfsan_label s_label, 66 dfsan_label c_label, 67 dfsan_label *ret_label) { 68 for (size_t i = 0;; ++i) { 69 if (s[i] == c || s[i] == 0) { 70 if (flags().strict_data_dependencies) { 71 *ret_label = s_label; 72 } else { 73 *ret_label = dfsan_union(dfsan_read_label(s, i + 1), 74 dfsan_union(s_label, c_label)); 75 } 76 return s[i] == 0 ? 0 : const_cast<char *>(s+i); 77 } 78 } 79 } 80 81 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, 82 size_t n, dfsan_label s1_label, 83 dfsan_label s2_label, 84 dfsan_label n_label, 85 dfsan_label *ret_label) { 86 const char *cs1 = (const char *) s1, *cs2 = (const char *) s2; 87 for (size_t i = 0; i != n; ++i) { 88 if (cs1[i] != cs2[i]) { 89 if (flags().strict_data_dependencies) { 90 *ret_label = 0; 91 } else { 92 *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1), 93 dfsan_read_label(cs2, i + 1)); 94 } 95 return cs1[i] - cs2[i]; 96 } 97 } 98 99 if (flags().strict_data_dependencies) { 100 *ret_label = 0; 101 } else { 102 *ret_label = dfsan_union(dfsan_read_label(cs1, n), 103 dfsan_read_label(cs2, n)); 104 } 105 return 0; 106 } 107 108 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2, 109 dfsan_label s1_label, 110 dfsan_label s2_label, 111 dfsan_label *ret_label) { 112 for (size_t i = 0;; ++i) { 113 if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) { 114 if (flags().strict_data_dependencies) { 115 *ret_label = 0; 116 } else { 117 *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), 118 dfsan_read_label(s2, i + 1)); 119 } 120 return s1[i] - s2[i]; 121 } 122 } 123 return 0; 124 } 125 126 SANITIZER_INTERFACE_ATTRIBUTE int 127 __dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label, 128 dfsan_label s2_label, dfsan_label *ret_label) { 129 for (size_t i = 0;; ++i) { 130 if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0) { 131 if (flags().strict_data_dependencies) { 132 *ret_label = 0; 133 } else { 134 *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), 135 dfsan_read_label(s2, i + 1)); 136 } 137 return s1[i] - s2[i]; 138 } 139 } 140 return 0; 141 } 142 143 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, 144 size_t n, dfsan_label s1_label, 145 dfsan_label s2_label, 146 dfsan_label n_label, 147 dfsan_label *ret_label) { 148 if (n == 0) { 149 *ret_label = 0; 150 return 0; 151 } 152 153 for (size_t i = 0;; ++i) { 154 if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) { 155 if (flags().strict_data_dependencies) { 156 *ret_label = 0; 157 } else { 158 *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), 159 dfsan_read_label(s2, i + 1)); 160 } 161 return s1[i] - s2[i]; 162 } 163 } 164 return 0; 165 } 166 167 SANITIZER_INTERFACE_ATTRIBUTE int 168 __dfsw_strncasecmp(const char *s1, const char *s2, size_t n, 169 dfsan_label s1_label, dfsan_label s2_label, 170 dfsan_label n_label, dfsan_label *ret_label) { 171 if (n == 0) { 172 *ret_label = 0; 173 return 0; 174 } 175 176 for (size_t i = 0;; ++i) { 177 if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 || 178 i == n - 1) { 179 if (flags().strict_data_dependencies) { 180 *ret_label = 0; 181 } else { 182 *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), 183 dfsan_read_label(s2, i + 1)); 184 } 185 return s1[i] - s2[i]; 186 } 187 } 188 return 0; 189 } 190 191 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size, 192 dfsan_label nmemb_label, 193 dfsan_label size_label, 194 dfsan_label *ret_label) { 195 void *p = calloc(nmemb, size); 196 dfsan_set_label(0, p, nmemb * size); 197 *ret_label = 0; 198 return p; 199 } 200 201 SANITIZER_INTERFACE_ATTRIBUTE size_t 202 __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 203 size_t ret = strlen(s); 204 if (flags().strict_data_dependencies) { 205 *ret_label = 0; 206 } else { 207 *ret_label = dfsan_read_label(s, ret + 1); 208 } 209 return ret; 210 } 211 212 213 static void *dfsan_memcpy(void *dest, const void *src, size_t n) { 214 dfsan_label *sdest = shadow_for(dest), *ssrc = shadow_for((void *)src); 215 internal_memcpy((void *)sdest, (void *)ssrc, n * sizeof(dfsan_label)); 216 return internal_memcpy(dest, src, n); 217 } 218 219 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) { 220 internal_memset(s, c, n); 221 dfsan_set_label(c_label, s, n); 222 } 223 224 SANITIZER_INTERFACE_ATTRIBUTE 225 void *__dfsw_memcpy(void *dest, const void *src, size_t n, 226 dfsan_label dest_label, dfsan_label src_label, 227 dfsan_label n_label, dfsan_label *ret_label) { 228 *ret_label = dest_label; 229 return dfsan_memcpy(dest, src, n); 230 } 231 232 SANITIZER_INTERFACE_ATTRIBUTE 233 void *__dfsw_memset(void *s, int c, size_t n, 234 dfsan_label s_label, dfsan_label c_label, 235 dfsan_label n_label, dfsan_label *ret_label) { 236 dfsan_memset(s, c, c_label, n); 237 *ret_label = s_label; 238 return s; 239 } 240 241 SANITIZER_INTERFACE_ATTRIBUTE char * 242 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 243 size_t len = strlen(s); 244 void *p = malloc(len+1); 245 dfsan_memcpy(p, s, len+1); 246 *ret_label = 0; 247 return static_cast<char *>(p); 248 } 249 250 SANITIZER_INTERFACE_ATTRIBUTE char * 251 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, 252 dfsan_label s2_label, dfsan_label n_label, 253 dfsan_label *ret_label) { 254 size_t len = strlen(s2); 255 if (len < n) { 256 dfsan_memcpy(s1, s2, len+1); 257 dfsan_memset(s1+len+1, 0, 0, n-len-1); 258 } else { 259 dfsan_memcpy(s1, s2, n); 260 } 261 262 *ret_label = s1_label; 263 return s1; 264 } 265 266 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 267 __dfsw_pread(int fd, void *buf, size_t count, off_t offset, 268 dfsan_label fd_label, dfsan_label buf_label, 269 dfsan_label count_label, dfsan_label offset_label, 270 dfsan_label *ret_label) { 271 ssize_t ret = pread(fd, buf, count, offset); 272 if (ret > 0) 273 dfsan_set_label(0, buf, ret); 274 *ret_label = 0; 275 return ret; 276 } 277 278 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 279 __dfsw_read(int fd, void *buf, size_t count, 280 dfsan_label fd_label, dfsan_label buf_label, 281 dfsan_label count_label, 282 dfsan_label *ret_label) { 283 ssize_t ret = read(fd, buf, count); 284 if (ret > 0) 285 dfsan_set_label(0, buf, ret); 286 *ret_label = 0; 287 return ret; 288 } 289 290 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, 291 struct timespec *tp, 292 dfsan_label clk_id_label, 293 dfsan_label tp_label, 294 dfsan_label *ret_label) { 295 int ret = clock_gettime(clk_id, tp); 296 if (ret == 0) 297 dfsan_set_label(0, tp, sizeof(struct timespec)); 298 *ret_label = 0; 299 return ret; 300 } 301 302 static void unpoison(const void *ptr, uptr size) { 303 dfsan_set_label(0, const_cast<void *>(ptr), size); 304 } 305 306 // dlopen() ultimately calls mmap() down inside the loader, which generally 307 // doesn't participate in dynamic symbol resolution. Therefore we won't 308 // intercept its calls to mmap, and we have to hook it here. 309 SANITIZER_INTERFACE_ATTRIBUTE void * 310 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label, 311 dfsan_label flag_label, dfsan_label *ret_label) { 312 link_map *map = (link_map *)dlopen(filename, flag); 313 if (map) 314 ForEachMappedRegion(map, unpoison); 315 *ret_label = 0; 316 return (void *)map; 317 } 318 319 struct pthread_create_info { 320 void *(*start_routine_trampoline)(void *, void *, dfsan_label, dfsan_label *); 321 void *start_routine; 322 void *arg; 323 }; 324 325 static void *pthread_create_cb(void *p) { 326 pthread_create_info pci(*(pthread_create_info *)p); 327 free(p); 328 dfsan_label ret_label; 329 return pci.start_routine_trampoline(pci.start_routine, pci.arg, 0, 330 &ret_label); 331 } 332 333 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( 334 pthread_t *thread, const pthread_attr_t *attr, 335 void *(*start_routine_trampoline)(void *, void *, dfsan_label, 336 dfsan_label *), 337 void *start_routine, void *arg, dfsan_label thread_label, 338 dfsan_label attr_label, dfsan_label start_routine_label, 339 dfsan_label arg_label, dfsan_label *ret_label) { 340 pthread_create_info *pci = 341 (pthread_create_info *)malloc(sizeof(pthread_create_info)); 342 pci->start_routine_trampoline = start_routine_trampoline; 343 pci->start_routine = start_routine; 344 pci->arg = arg; 345 int rv = pthread_create(thread, attr, pthread_create_cb, (void *)pci); 346 if (rv != 0) 347 free(pci); 348 *ret_label = 0; 349 return rv; 350 } 351 352 struct dl_iterate_phdr_info { 353 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 354 size_t size, void *data, dfsan_label info_label, 355 dfsan_label size_label, dfsan_label data_label, 356 dfsan_label *ret_label); 357 void *callback; 358 void *data; 359 }; 360 361 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { 362 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data; 363 dfsan_set_label(0, *info); 364 dfsan_set_label(0, (void *)info->dlpi_name, strlen(info->dlpi_name) + 1); 365 dfsan_set_label(0, (void *)info->dlpi_phdr, 366 sizeof(*info->dlpi_phdr) * info->dlpi_phnum); 367 dfsan_label ret_label; 368 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, 369 0, &ret_label); 370 } 371 372 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( 373 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 374 size_t size, void *data, dfsan_label info_label, 375 dfsan_label size_label, dfsan_label data_label, 376 dfsan_label *ret_label), 377 void *callback, void *data, dfsan_label callback_label, 378 dfsan_label data_label, dfsan_label *ret_label) { 379 dl_iterate_phdr_info dipi = { callback_trampoline, callback, data }; 380 *ret_label = 0; 381 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); 382 } 383 384 SANITIZER_INTERFACE_ATTRIBUTE 385 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 386 dfsan_label buf_label, dfsan_label *ret_label) { 387 char *ret = ctime_r(timep, buf); 388 if (ret) { 389 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf, 390 strlen(buf) + 1); 391 *ret_label = buf_label; 392 } else { 393 *ret_label = 0; 394 } 395 return ret; 396 } 397 398 SANITIZER_INTERFACE_ATTRIBUTE 399 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 400 dfsan_label size_label, dfsan_label stream_label, 401 dfsan_label *ret_label) { 402 char *ret = fgets(s, size, stream); 403 if (ret) { 404 dfsan_set_label(0, ret, strlen(ret) + 1); 405 *ret_label = s_label; 406 } else { 407 *ret_label = 0; 408 } 409 return ret; 410 } 411 412 SANITIZER_INTERFACE_ATTRIBUTE 413 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, 414 dfsan_label size_label, dfsan_label *ret_label) { 415 char *ret = getcwd(buf, size); 416 if (ret) { 417 dfsan_set_label(0, ret, strlen(ret) + 1); 418 *ret_label = buf_label; 419 } else { 420 *ret_label = 0; 421 } 422 return ret; 423 } 424 425 SANITIZER_INTERFACE_ATTRIBUTE 426 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { 427 char *ret = get_current_dir_name(); 428 if (ret) { 429 dfsan_set_label(0, ret, strlen(ret) + 1); 430 } 431 *ret_label = 0; 432 return ret; 433 } 434 435 SANITIZER_INTERFACE_ATTRIBUTE 436 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, 437 dfsan_label len_label, dfsan_label *ret_label) { 438 int ret = gethostname(name, len); 439 if (ret == 0) { 440 dfsan_set_label(0, name, strlen(name) + 1); 441 } 442 *ret_label = 0; 443 return ret; 444 } 445 446 SANITIZER_INTERFACE_ATTRIBUTE 447 int __dfsw_getrlimit(int resource, struct rlimit *rlim, 448 dfsan_label resource_label, dfsan_label rlim_label, 449 dfsan_label *ret_label) { 450 int ret = getrlimit(resource, rlim); 451 if (ret == 0) { 452 dfsan_set_label(0, rlim, sizeof(struct rlimit)); 453 } 454 *ret_label = 0; 455 return ret; 456 } 457 458 SANITIZER_INTERFACE_ATTRIBUTE 459 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, 460 dfsan_label usage_label, dfsan_label *ret_label) { 461 int ret = getrusage(who, usage); 462 if (ret == 0) { 463 dfsan_set_label(0, usage, sizeof(struct rusage)); 464 } 465 *ret_label = 0; 466 return ret; 467 } 468 469 SANITIZER_INTERFACE_ATTRIBUTE 470 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, 471 dfsan_label src_label, dfsan_label *ret_label) { 472 char *ret = strcpy(dest, src); 473 if (ret) { 474 internal_memcpy(shadow_for(dest), shadow_for(src), 475 sizeof(dfsan_label) * (strlen(src) + 1)); 476 } 477 *ret_label = dst_label; 478 return ret; 479 } 480 481 SANITIZER_INTERFACE_ATTRIBUTE 482 long int __dfsw_strtol(const char *nptr, char **endptr, int base, 483 dfsan_label nptr_label, dfsan_label endptr_label, 484 dfsan_label base_label, dfsan_label *ret_label) { 485 char *tmp_endptr; 486 long int ret = strtol(nptr, &tmp_endptr, base); 487 if (endptr) { 488 *endptr = tmp_endptr; 489 } 490 if (tmp_endptr > nptr) { 491 // If *tmp_endptr is '\0' include its label as well. 492 *ret_label = dfsan_union( 493 base_label, 494 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 495 } else { 496 *ret_label = 0; 497 } 498 return ret; 499 } 500 501 SANITIZER_INTERFACE_ATTRIBUTE 502 double __dfsw_strtod(const char *nptr, char **endptr, 503 dfsan_label nptr_label, dfsan_label endptr_label, 504 dfsan_label *ret_label) { 505 char *tmp_endptr; 506 double ret = strtod(nptr, &tmp_endptr); 507 if (endptr) { 508 *endptr = tmp_endptr; 509 } 510 if (tmp_endptr > nptr) { 511 // If *tmp_endptr is '\0' include its label as well. 512 *ret_label = dfsan_read_label( 513 nptr, 514 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 515 } else { 516 *ret_label = 0; 517 } 518 return ret; 519 } 520 521 SANITIZER_INTERFACE_ATTRIBUTE 522 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, 523 dfsan_label nptr_label, dfsan_label endptr_label, 524 dfsan_label base_label, dfsan_label *ret_label) { 525 char *tmp_endptr; 526 long long int ret = strtoll(nptr, &tmp_endptr, base); 527 if (endptr) { 528 *endptr = tmp_endptr; 529 } 530 if (tmp_endptr > nptr) { 531 // If *tmp_endptr is '\0' include its label as well. 532 *ret_label = dfsan_union( 533 base_label, 534 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 535 } else { 536 *ret_label = 0; 537 } 538 return ret; 539 } 540 541 SANITIZER_INTERFACE_ATTRIBUTE 542 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base, 543 dfsan_label nptr_label, dfsan_label endptr_label, 544 dfsan_label base_label, dfsan_label *ret_label) { 545 char *tmp_endptr; 546 unsigned long int ret = strtoul(nptr, &tmp_endptr, base); 547 if (endptr) { 548 *endptr = tmp_endptr; 549 } 550 if (tmp_endptr > nptr) { 551 // If *tmp_endptr is '\0' include its label as well. 552 *ret_label = dfsan_union( 553 base_label, 554 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 555 } else { 556 *ret_label = 0; 557 } 558 return ret; 559 } 560 561 SANITIZER_INTERFACE_ATTRIBUTE 562 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, 563 dfsan_label nptr_label, 564 int base, dfsan_label endptr_label, 565 dfsan_label base_label, 566 dfsan_label *ret_label) { 567 char *tmp_endptr; 568 long long unsigned int ret = strtoull(nptr, &tmp_endptr, base); 569 if (endptr) { 570 *endptr = tmp_endptr; 571 } 572 if (tmp_endptr > nptr) { 573 // If *tmp_endptr is '\0' include its label as well. 574 *ret_label = dfsan_union( 575 base_label, 576 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 577 } else { 578 *ret_label = 0; 579 } 580 return ret; 581 } 582 583 SANITIZER_INTERFACE_ATTRIBUTE 584 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { 585 time_t ret = time(t); 586 if (ret != (time_t) -1 && t) { 587 dfsan_set_label(0, t, sizeof(time_t)); 588 } 589 *ret_label = 0; 590 return ret; 591 } 592 593 SANITIZER_INTERFACE_ATTRIBUTE 594 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 595 dfsan_label src_label, dfsan_label dst_label, 596 dfsan_label *ret_label) { 597 int ret = inet_pton(af, src, dst); 598 if (ret == 1) { 599 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst, 600 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 601 } 602 *ret_label = 0; 603 return ret; 604 } 605 606 SANITIZER_INTERFACE_ATTRIBUTE 607 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, 608 dfsan_label timep_label, dfsan_label result_label, 609 dfsan_label *ret_label) { 610 struct tm *ret = localtime_r(timep, result); 611 if (ret) { 612 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result, 613 sizeof(struct tm)); 614 *ret_label = result_label; 615 } else { 616 *ret_label = 0; 617 } 618 return ret; 619 } 620 621 SANITIZER_INTERFACE_ATTRIBUTE 622 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, 623 char *buf, size_t buflen, struct passwd **result, 624 dfsan_label uid_label, dfsan_label pwd_label, 625 dfsan_label buf_label, dfsan_label buflen_label, 626 dfsan_label result_label, dfsan_label *ret_label) { 627 // Store the data in pwd, the strings referenced from pwd in buf, and the 628 // address of pwd in *result. On failure, NULL is stored in *result. 629 int ret = getpwuid_r(uid, pwd, buf, buflen, result); 630 if (ret == 0) { 631 dfsan_set_label(0, pwd, sizeof(struct passwd)); 632 dfsan_set_label(0, buf, strlen(buf) + 1); 633 } 634 *ret_label = 0; 635 dfsan_set_label(0, result, sizeof(struct passwd*)); 636 return ret; 637 } 638 639 SANITIZER_INTERFACE_ATTRIBUTE 640 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, 641 dfsan_label dfs_label, dfsan_label nfds_label, 642 dfsan_label timeout_label, dfsan_label *ret_label) { 643 int ret = poll(fds, nfds, timeout); 644 if (ret >= 0) { 645 for (; nfds > 0; --nfds) { 646 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents)); 647 } 648 } 649 *ret_label = 0; 650 return ret; 651 } 652 653 SANITIZER_INTERFACE_ATTRIBUTE 654 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, 655 fd_set *exceptfds, struct timeval *timeout, 656 dfsan_label nfds_label, dfsan_label readfds_label, 657 dfsan_label writefds_label, dfsan_label exceptfds_label, 658 dfsan_label timeout_label, dfsan_label *ret_label) { 659 int ret = select(nfds, readfds, writefds, exceptfds, timeout); 660 // Clear everything (also on error) since their content is either set or 661 // undefined. 662 if (readfds) { 663 dfsan_set_label(0, readfds, sizeof(fd_set)); 664 } 665 if (writefds) { 666 dfsan_set_label(0, writefds, sizeof(fd_set)); 667 } 668 if (exceptfds) { 669 dfsan_set_label(0, exceptfds, sizeof(fd_set)); 670 } 671 dfsan_set_label(0, timeout, sizeof(struct timeval)); 672 *ret_label = 0; 673 return ret; 674 } 675 676 SANITIZER_INTERFACE_ATTRIBUTE 677 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 678 dfsan_label pid_label, 679 dfsan_label cpusetsize_label, 680 dfsan_label mask_label, dfsan_label *ret_label) { 681 int ret = sched_getaffinity(pid, cpusetsize, mask); 682 if (ret == 0) { 683 dfsan_set_label(0, mask, cpusetsize); 684 } 685 *ret_label = 0; 686 return ret; 687 } 688 689 SANITIZER_INTERFACE_ATTRIBUTE 690 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, 691 dfsan_label *ret_label) { 692 int ret = sigemptyset(set); 693 dfsan_set_label(0, set, sizeof(sigset_t)); 694 return ret; 695 } 696 697 SANITIZER_INTERFACE_ATTRIBUTE 698 int __dfsw_sigaction(int signum, const struct sigaction *act, 699 struct sigaction *oldact, dfsan_label signum_label, 700 dfsan_label act_label, dfsan_label oldact_label, 701 dfsan_label *ret_label) { 702 int ret = sigaction(signum, act, oldact); 703 if (oldact) { 704 dfsan_set_label(0, oldact, sizeof(struct sigaction)); 705 } 706 *ret_label = 0; 707 return ret; 708 } 709 710 SANITIZER_INTERFACE_ATTRIBUTE 711 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, 712 dfsan_label tv_label, dfsan_label tz_label, 713 dfsan_label *ret_label) { 714 int ret = gettimeofday(tv, tz); 715 if (tv) { 716 dfsan_set_label(0, tv, sizeof(struct timeval)); 717 } 718 if (tz) { 719 dfsan_set_label(0, tz, sizeof(struct timezone)); 720 } 721 *ret_label = 0; 722 return ret; 723 } 724 725 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, 726 dfsan_label s_label, 727 dfsan_label c_label, 728 dfsan_label n_label, 729 dfsan_label *ret_label) { 730 void *ret = memchr(s, c, n); 731 if (flags().strict_data_dependencies) { 732 *ret_label = ret ? s_label : 0; 733 } else { 734 size_t len = 735 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 736 : n; 737 *ret_label = 738 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); 739 } 740 return ret; 741 } 742 743 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, 744 dfsan_label s_label, 745 dfsan_label c_label, 746 dfsan_label *ret_label) { 747 char *ret = strrchr(s, c); 748 if (flags().strict_data_dependencies) { 749 *ret_label = ret ? s_label : 0; 750 } else { 751 *ret_label = 752 dfsan_union(dfsan_read_label(s, strlen(s) + 1), 753 dfsan_union(s_label, c_label)); 754 } 755 756 return ret; 757 } 758 759 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, 760 dfsan_label haystack_label, 761 dfsan_label needle_label, 762 dfsan_label *ret_label) { 763 char *ret = strstr(haystack, needle); 764 if (flags().strict_data_dependencies) { 765 *ret_label = ret ? haystack_label : 0; 766 } else { 767 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1; 768 *ret_label = 769 dfsan_union(dfsan_read_label(haystack, len), 770 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1), 771 dfsan_union(haystack_label, needle_label))); 772 } 773 774 return ret; 775 } 776 777 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, 778 struct timespec *rem, 779 dfsan_label req_label, 780 dfsan_label rem_label, 781 dfsan_label *ret_label) { 782 int ret = nanosleep(req, rem); 783 *ret_label = 0; 784 if (ret == -1) { 785 // Interrupted by a signal, rem is filled with the remaining time. 786 dfsan_set_label(0, rem, sizeof(struct timespec)); 787 } 788 return ret; 789 } 790 791 SANITIZER_INTERFACE_ATTRIBUTE int 792 __dfsw_socketpair(int domain, int type, int protocol, int sv[2], 793 dfsan_label domain_label, dfsan_label type_label, 794 dfsan_label protocol_label, dfsan_label sv_label, 795 dfsan_label *ret_label) { 796 int ret = socketpair(domain, type, protocol, sv); 797 *ret_label = 0; 798 if (ret == 0) { 799 dfsan_set_label(0, sv, sizeof(*sv) * 2); 800 } 801 return ret; 802 } 803 804 // Type of the trampoline function passed to the custom version of 805 // dfsan_set_write_callback. 806 typedef void (*write_trampoline_t)( 807 void *callback, 808 int fd, const void *buf, ssize_t count, 809 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label); 810 811 // Calls to dfsan_set_write_callback() set the values in this struct. 812 // Calls to the custom version of write() read (and invoke) them. 813 static struct { 814 write_trampoline_t write_callback_trampoline = NULL; 815 void *write_callback = NULL; 816 } write_callback_info; 817 818 SANITIZER_INTERFACE_ATTRIBUTE void 819 __dfsw_dfsan_set_write_callback( 820 write_trampoline_t write_callback_trampoline, 821 void *write_callback, 822 dfsan_label write_callback_label, 823 dfsan_label *ret_label) { 824 write_callback_info.write_callback_trampoline = write_callback_trampoline; 825 write_callback_info.write_callback = write_callback; 826 } 827 828 SANITIZER_INTERFACE_ATTRIBUTE int 829 __dfsw_write(int fd, const void *buf, size_t count, 830 dfsan_label fd_label, dfsan_label buf_label, 831 dfsan_label count_label, dfsan_label *ret_label) { 832 if (write_callback_info.write_callback != NULL) { 833 write_callback_info.write_callback_trampoline( 834 write_callback_info.write_callback, 835 fd, buf, count, 836 fd_label, buf_label, count_label); 837 } 838 839 *ret_label = 0; 840 return write(fd, buf, count); 841 } 842 } 843