1 //===-- dfsan_custom.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of DataFlowSanitizer. 10 // 11 // This file defines the custom functions listed in done_abilist.txt. 12 //===----------------------------------------------------------------------===// 13 14 #include <arpa/inet.h> 15 #include <assert.h> 16 #include <ctype.h> 17 #include <dlfcn.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 <stdarg.h> 25 #include <stdint.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.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 #include "dfsan/dfsan.h" 40 #include "dfsan/dfsan_chained_origin_depot.h" 41 #include "dfsan/dfsan_flags.h" 42 #include "dfsan/dfsan_thread.h" 43 #include "sanitizer_common/sanitizer_common.h" 44 #include "sanitizer_common/sanitizer_internal_defs.h" 45 #include "sanitizer_common/sanitizer_linux.h" 46 #include "sanitizer_common/sanitizer_stackdepot.h" 47 48 using namespace __dfsan; 49 50 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \ 51 do { \ 52 if (f) \ 53 f(__VA_ARGS__); \ 54 } while (false) 55 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \ 56 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__); 57 58 // Async-safe, non-reentrant spin lock. 59 class SignalSpinLocker { 60 public: 61 SignalSpinLocker() { 62 sigset_t all_set; 63 sigfillset(&all_set); 64 pthread_sigmask(SIG_SETMASK, &all_set, &saved_thread_mask_); 65 sigactions_mu.Lock(); 66 } 67 ~SignalSpinLocker() { 68 sigactions_mu.Unlock(); 69 pthread_sigmask(SIG_SETMASK, &saved_thread_mask_, nullptr); 70 } 71 72 private: 73 static StaticSpinMutex sigactions_mu; 74 sigset_t saved_thread_mask_; 75 76 SignalSpinLocker(const SignalSpinLocker &) = delete; 77 SignalSpinLocker &operator=(const SignalSpinLocker &) = delete; 78 }; 79 80 StaticSpinMutex SignalSpinLocker::sigactions_mu; 81 82 extern "C" { 83 SANITIZER_INTERFACE_ATTRIBUTE int 84 __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label, 85 dfsan_label buf_label, dfsan_label *ret_label) { 86 int ret = stat(path, buf); 87 if (ret == 0) 88 dfsan_set_label(0, buf, sizeof(struct stat)); 89 *ret_label = 0; 90 return ret; 91 } 92 93 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat( 94 const char *path, struct stat *buf, dfsan_label path_label, 95 dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin, 96 dfsan_origin buf_origin, dfsan_origin *ret_origin) { 97 int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label); 98 return ret; 99 } 100 101 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf, 102 dfsan_label fd_label, 103 dfsan_label buf_label, 104 dfsan_label *ret_label) { 105 int ret = fstat(fd, buf); 106 if (ret == 0) 107 dfsan_set_label(0, buf, sizeof(struct stat)); 108 *ret_label = 0; 109 return ret; 110 } 111 112 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat( 113 int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label, 114 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, 115 dfsan_origin *ret_origin) { 116 int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label); 117 return ret; 118 } 119 120 static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read, 121 dfsan_label s_label, dfsan_label c_label, 122 dfsan_label *ret_label) { 123 char *match_pos = nullptr; 124 for (size_t i = 0;; ++i) { 125 if (s[i] == c || s[i] == 0) { 126 // If s[i] is the \0 at the end of the string, and \0 is not the 127 // character we are searching for, then return null. 128 *bytes_read = i + 1; 129 match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast<char *>(s + i); 130 break; 131 } 132 } 133 if (flags().strict_data_dependencies) 134 *ret_label = s_label; 135 else 136 *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read), 137 dfsan_union(s_label, c_label)); 138 return match_pos; 139 } 140 141 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, 142 dfsan_label s_label, 143 dfsan_label c_label, 144 dfsan_label *ret_label) { 145 size_t bytes_read; 146 return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, 147 ret_label); 148 } 149 150 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr( 151 const char *s, int c, dfsan_label s_label, dfsan_label c_label, 152 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, 153 dfsan_origin *ret_origin) { 154 size_t bytes_read; 155 char *r = 156 dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label); 157 if (flags().strict_data_dependencies) { 158 *ret_origin = s_origin; 159 } else if (*ret_label) { 160 dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read); 161 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 162 } 163 return r; 164 } 165 166 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s, 167 const char *accept, 168 dfsan_label s_label, 169 dfsan_label accept_label, 170 dfsan_label *ret_label) { 171 const char *ret = strpbrk(s, accept); 172 if (flags().strict_data_dependencies) { 173 *ret_label = ret ? s_label : 0; 174 } else { 175 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1; 176 *ret_label = 177 dfsan_union(dfsan_read_label(s, s_bytes_read), 178 dfsan_union(dfsan_read_label(accept, strlen(accept) + 1), 179 dfsan_union(s_label, accept_label))); 180 } 181 return const_cast<char *>(ret); 182 } 183 184 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk( 185 const char *s, const char *accept, dfsan_label s_label, 186 dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin, 187 dfsan_origin accept_origin, dfsan_origin *ret_origin) { 188 const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label); 189 if (flags().strict_data_dependencies) { 190 if (ret) 191 *ret_origin = s_origin; 192 } else { 193 if (*ret_label) { 194 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1; 195 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read); 196 if (o) { 197 *ret_origin = o; 198 } else { 199 o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1); 200 *ret_origin = o ? o : (s_label ? s_origin : accept_origin); 201 } 202 } 203 } 204 return const_cast<char *>(ret); 205 } 206 207 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strsep(char **s, const char *delim, 208 dfsan_label s_label, 209 dfsan_label delim_label, 210 dfsan_label *ret_label) { 211 dfsan_label base_label = dfsan_read_label(s, sizeof(*s)); 212 char *base = *s; 213 char *res = strsep(s, delim); 214 if (res != *s) { 215 char *token_start = res; 216 int token_length = strlen(res); 217 // the delimiter byte has been set to NULL 218 dfsan_set_label(0, token_start + token_length, 1); 219 } 220 221 if (flags().strict_data_dependencies) { 222 *ret_label = res ? base_label : 0; 223 } else { 224 size_t s_bytes_read = (res ? strlen(res) : strlen(base)) + 1; 225 *ret_label = dfsan_union( 226 dfsan_union(base_label, dfsan_read_label(base, sizeof(s_bytes_read))), 227 dfsan_union(dfsan_read_label(delim, strlen(delim) + 1), 228 dfsan_union(s_label, delim_label))); 229 } 230 231 return res; 232 } 233 234 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strsep( 235 char **s, const char *delim, dfsan_label s_label, dfsan_label delim_label, 236 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin delim_origin, 237 dfsan_origin *ret_origin) { 238 dfsan_origin base_origin = dfsan_read_origin_of_first_taint(s, sizeof(*s)); 239 char *res = __dfsw_strsep(s, delim, s_label, delim_label, ret_label); 240 if (flags().strict_data_dependencies) { 241 if (res) 242 *ret_origin = base_origin; 243 } else { 244 if (*ret_label) { 245 if (base_origin) { 246 *ret_origin = base_origin; 247 } else { 248 dfsan_origin o = 249 dfsan_read_origin_of_first_taint(delim, strlen(delim) + 1); 250 *ret_origin = o ? o : (s_label ? s_origin : delim_origin); 251 } 252 } 253 } 254 255 return res; 256 } 257 258 static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n, 259 size_t *bytes_read) { 260 const char *cs1 = (const char *) s1, *cs2 = (const char *) s2; 261 for (size_t i = 0; i != n; ++i) { 262 if (cs1[i] != cs2[i]) { 263 *bytes_read = i + 1; 264 return cs1[i] - cs2[i]; 265 } 266 } 267 *bytes_read = n; 268 return 0; 269 } 270 271 static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2, 272 size_t pos) { 273 if (flags().strict_data_dependencies) 274 return 0; 275 return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos)); 276 } 277 278 static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos, 279 dfsan_label *ret_label, 280 dfsan_origin *ret_origin) { 281 *ret_label = dfsan_get_memcmp_label(s1, s2, pos); 282 if (*ret_label == 0) 283 return; 284 dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos); 285 *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos); 286 } 287 288 static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n, 289 dfsan_label *ret_label) { 290 size_t bytes_read; 291 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); 292 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 293 return r; 294 } 295 296 static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n, 297 dfsan_label *ret_label, 298 dfsan_origin *ret_origin) { 299 size_t bytes_read; 300 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); 301 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 302 return r; 303 } 304 305 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc, 306 const void *s1, const void *s2, size_t n, 307 dfsan_label s1_label, dfsan_label s2_label, 308 dfsan_label n_label) 309 310 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc, 311 const void *s1, const void *s2, size_t n, 312 dfsan_label s1_label, dfsan_label s2_label, 313 dfsan_label n_label, dfsan_origin s1_origin, 314 dfsan_origin s2_origin, dfsan_origin n_origin) 315 316 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, 317 size_t n, dfsan_label s1_label, 318 dfsan_label s2_label, 319 dfsan_label n_label, 320 dfsan_label *ret_label) { 321 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n, 322 s1_label, s2_label, n_label); 323 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); 324 } 325 326 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp( 327 const void *s1, const void *s2, size_t n, dfsan_label s1_label, 328 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 329 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 330 dfsan_origin *ret_origin) { 331 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1, 332 s2, n, s1_label, s2_label, n_label, s1_origin, 333 s2_origin, n_origin); 334 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); 335 } 336 337 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2, 338 size_t n, dfsan_label s1_label, 339 dfsan_label s2_label, 340 dfsan_label n_label, 341 dfsan_label *ret_label) { 342 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); 343 } 344 345 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp( 346 const void *s1, const void *s2, size_t n, dfsan_label s1_label, 347 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 348 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 349 dfsan_origin *ret_origin) { 350 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); 351 } 352 353 // When n == 0, compare strings without byte limit. 354 // When n > 0, compare the first (at most) n bytes of s1 and s2. 355 static int dfsan_strncmp(const char *s1, const char *s2, size_t n, 356 size_t *bytes_read) { 357 for (size_t i = 0;; ++i) { 358 if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) { 359 *bytes_read = i + 1; 360 return s1[i] - s2[i]; 361 } 362 } 363 } 364 365 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc, 366 const char *s1, const char *s2, 367 dfsan_label s1_label, dfsan_label s2_label) 368 369 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc, 370 const char *s1, const char *s2, 371 dfsan_label s1_label, dfsan_label s2_label, 372 dfsan_origin s1_origin, dfsan_origin s2_origin) 373 374 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2, 375 dfsan_label s1_label, 376 dfsan_label s2_label, 377 dfsan_label *ret_label) { 378 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2, 379 s1_label, s2_label); 380 size_t bytes_read; 381 int r = dfsan_strncmp(s1, s2, 0, &bytes_read); 382 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 383 return r; 384 } 385 386 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp( 387 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, 388 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, 389 dfsan_origin *ret_origin) { 390 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1, 391 s2, s1_label, s2_label, s1_origin, s2_origin); 392 size_t bytes_read; 393 int r = dfsan_strncmp(s1, s2, 0, &bytes_read); 394 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 395 return r; 396 } 397 398 // When n == 0, compare strings without byte limit. 399 // When n > 0, compare the first (at most) n bytes of s1 and s2. 400 static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n, 401 size_t *bytes_read) { 402 for (size_t i = 0;; ++i) { 403 char s1_lower = tolower(s1[i]); 404 char s2_lower = tolower(s2[i]); 405 406 if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || 407 (n > 0 && i == n - 1)) { 408 *bytes_read = i + 1; 409 return s1_lower - s2_lower; 410 } 411 } 412 } 413 414 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1, 415 const char *s2, 416 dfsan_label s1_label, 417 dfsan_label s2_label, 418 dfsan_label *ret_label) { 419 size_t bytes_read; 420 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); 421 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 422 return r; 423 } 424 425 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp( 426 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, 427 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, 428 dfsan_origin *ret_origin) { 429 size_t bytes_read; 430 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); 431 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 432 return r; 433 } 434 435 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc, 436 const char *s1, const char *s2, size_t n, 437 dfsan_label s1_label, dfsan_label s2_label, 438 dfsan_label n_label) 439 440 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc, 441 const char *s1, const char *s2, size_t n, 442 dfsan_label s1_label, dfsan_label s2_label, 443 dfsan_label n_label, dfsan_origin s1_origin, 444 dfsan_origin s2_origin, dfsan_origin n_origin) 445 446 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, 447 size_t n, dfsan_label s1_label, 448 dfsan_label s2_label, 449 dfsan_label n_label, 450 dfsan_label *ret_label) { 451 if (n == 0) { 452 *ret_label = 0; 453 return 0; 454 } 455 456 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2, 457 n, s1_label, s2_label, n_label); 458 459 size_t bytes_read; 460 int r = dfsan_strncmp(s1, s2, n, &bytes_read); 461 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 462 return r; 463 } 464 465 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp( 466 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 467 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 468 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 469 dfsan_origin *ret_origin) { 470 if (n == 0) { 471 *ret_label = 0; 472 return 0; 473 } 474 475 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(), 476 s1, s2, n, s1_label, s2_label, n_label, s1_origin, 477 s2_origin, n_origin); 478 479 size_t bytes_read; 480 int r = dfsan_strncmp(s1, s2, n, &bytes_read); 481 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 482 return r; 483 } 484 485 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp( 486 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 487 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) { 488 if (n == 0) { 489 *ret_label = 0; 490 return 0; 491 } 492 493 size_t bytes_read; 494 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); 495 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 496 return r; 497 } 498 499 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp( 500 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 501 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 502 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 503 dfsan_origin *ret_origin) { 504 if (n == 0) { 505 *ret_label = 0; 506 return 0; 507 } 508 509 size_t bytes_read; 510 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); 511 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 512 return r; 513 } 514 515 516 SANITIZER_INTERFACE_ATTRIBUTE size_t 517 __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 518 size_t ret = strlen(s); 519 if (flags().strict_data_dependencies) { 520 *ret_label = 0; 521 } else { 522 *ret_label = dfsan_read_label(s, ret + 1); 523 } 524 return ret; 525 } 526 527 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s, 528 dfsan_label s_label, 529 dfsan_label *ret_label, 530 dfsan_origin s_origin, 531 dfsan_origin *ret_origin) { 532 size_t ret = __dfsw_strlen(s, s_label, ret_label); 533 if (!flags().strict_data_dependencies) 534 *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1); 535 return ret; 536 } 537 538 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfsw_strnlen(const char *s, 539 size_t maxlen, 540 dfsan_label s_label, 541 dfsan_label maxlen_label, 542 dfsan_label *ret_label) { 543 size_t ret = strnlen(s, maxlen); 544 if (flags().strict_data_dependencies) { 545 *ret_label = 0; 546 } else { 547 size_t full_len = strlen(s); 548 size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen; 549 *ret_label = dfsan_union(maxlen_label, dfsan_read_label(s, covered_len)); 550 } 551 return ret; 552 } 553 554 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strnlen( 555 const char *s, size_t maxlen, dfsan_label s_label, dfsan_label maxlen_label, 556 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin maxlen_origin, 557 dfsan_origin *ret_origin) { 558 size_t ret = __dfsw_strnlen(s, maxlen, s_label, maxlen_label, ret_label); 559 if (!flags().strict_data_dependencies) { 560 size_t full_len = strlen(s); 561 size_t covered_len = maxlen > (full_len + 1) ? (full_len + 1) : maxlen; 562 dfsan_origin o = dfsan_read_origin_of_first_taint(s, covered_len); 563 *ret_origin = o ? o : maxlen_origin; 564 } 565 return ret; 566 } 567 568 static void *dfsan_memmove(void *dest, const void *src, size_t n) { 569 dfsan_label *sdest = shadow_for(dest); 570 const dfsan_label *ssrc = shadow_for(src); 571 internal_memmove((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); 572 return internal_memmove(dest, src, n); 573 } 574 575 static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) { 576 dfsan_mem_origin_transfer(dest, src, n); 577 return dfsan_memmove(dest, src, n); 578 } 579 580 static void *dfsan_memcpy(void *dest, const void *src, size_t n) { 581 dfsan_mem_shadow_transfer(dest, src, n); 582 return internal_memcpy(dest, src, n); 583 } 584 585 static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) { 586 dfsan_mem_origin_transfer(dest, src, n); 587 return dfsan_memcpy(dest, src, n); 588 } 589 590 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) { 591 internal_memset(s, c, n); 592 dfsan_set_label(c_label, s, n); 593 } 594 595 static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label, 596 dfsan_origin c_origin, size_t n) { 597 internal_memset(s, c, n); 598 dfsan_set_label_origin(c_label, c_origin, s, n); 599 } 600 601 SANITIZER_INTERFACE_ATTRIBUTE 602 void *__dfsw_memcpy(void *dest, const void *src, size_t n, 603 dfsan_label dest_label, dfsan_label src_label, 604 dfsan_label n_label, dfsan_label *ret_label) { 605 *ret_label = dest_label; 606 return dfsan_memcpy(dest, src, n); 607 } 608 609 SANITIZER_INTERFACE_ATTRIBUTE 610 void *__dfso_memcpy(void *dest, const void *src, size_t n, 611 dfsan_label dest_label, dfsan_label src_label, 612 dfsan_label n_label, dfsan_label *ret_label, 613 dfsan_origin dest_origin, dfsan_origin src_origin, 614 dfsan_origin n_origin, dfsan_origin *ret_origin) { 615 *ret_label = dest_label; 616 *ret_origin = dest_origin; 617 return dfsan_memcpy_with_origin(dest, src, n); 618 } 619 620 SANITIZER_INTERFACE_ATTRIBUTE 621 void *__dfsw_memmove(void *dest, const void *src, size_t n, 622 dfsan_label dest_label, dfsan_label src_label, 623 dfsan_label n_label, dfsan_label *ret_label) { 624 *ret_label = dest_label; 625 return dfsan_memmove(dest, src, n); 626 } 627 628 SANITIZER_INTERFACE_ATTRIBUTE 629 void *__dfso_memmove(void *dest, const void *src, size_t n, 630 dfsan_label dest_label, dfsan_label src_label, 631 dfsan_label n_label, dfsan_label *ret_label, 632 dfsan_origin dest_origin, dfsan_origin src_origin, 633 dfsan_origin n_origin, dfsan_origin *ret_origin) { 634 *ret_label = dest_label; 635 *ret_origin = dest_origin; 636 return dfsan_memmove_with_origin(dest, src, n); 637 } 638 639 SANITIZER_INTERFACE_ATTRIBUTE 640 void *__dfsw_memset(void *s, int c, size_t n, 641 dfsan_label s_label, dfsan_label c_label, 642 dfsan_label n_label, dfsan_label *ret_label) { 643 dfsan_memset(s, c, c_label, n); 644 *ret_label = s_label; 645 return s; 646 } 647 648 SANITIZER_INTERFACE_ATTRIBUTE 649 void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label, 650 dfsan_label c_label, dfsan_label n_label, 651 dfsan_label *ret_label, dfsan_origin s_origin, 652 dfsan_origin c_origin, dfsan_origin n_origin, 653 dfsan_origin *ret_origin) { 654 dfsan_memset_with_origin(s, c, c_label, c_origin, n); 655 *ret_label = s_label; 656 *ret_origin = s_origin; 657 return s; 658 } 659 660 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, 661 dfsan_label dest_label, 662 dfsan_label src_label, 663 dfsan_label *ret_label) { 664 size_t dest_len = strlen(dest); 665 char *ret = strcat(dest, src); 666 dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src)); 667 *ret_label = dest_label; 668 return ret; 669 } 670 671 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat( 672 char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label, 673 dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin, 674 dfsan_origin *ret_origin) { 675 size_t dest_len = strlen(dest); 676 char *ret = strcat(dest, src); 677 size_t src_len = strlen(src); 678 dfsan_mem_origin_transfer(dest + dest_len, src, src_len); 679 dfsan_mem_shadow_transfer(dest + dest_len, src, src_len); 680 *ret_label = dest_label; 681 *ret_origin = dest_origin; 682 return ret; 683 } 684 685 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strncat( 686 char *dest, const char *src, size_t num, dfsan_label dest_label, 687 dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label) { 688 size_t src_len = strlen(src); 689 src_len = src_len < num ? src_len : num; 690 size_t dest_len = strlen(dest); 691 692 char *ret = strncat(dest, src, num); 693 dfsan_mem_shadow_transfer(dest + dest_len, src, src_len); 694 *ret_label = dest_label; 695 return ret; 696 } 697 698 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncat( 699 char *dest, const char *src, size_t num, dfsan_label dest_label, 700 dfsan_label src_label, dfsan_label num_label, dfsan_label *ret_label, 701 dfsan_origin dest_origin, dfsan_origin src_origin, dfsan_origin num_origin, 702 dfsan_origin *ret_origin) { 703 size_t src_len = strlen(src); 704 src_len = src_len < num ? src_len : num; 705 size_t dest_len = strlen(dest); 706 707 char *ret = strncat(dest, src, num); 708 709 dfsan_mem_origin_transfer(dest + dest_len, src, src_len); 710 dfsan_mem_shadow_transfer(dest + dest_len, src, src_len); 711 *ret_label = dest_label; 712 *ret_origin = dest_origin; 713 return ret; 714 } 715 716 SANITIZER_INTERFACE_ATTRIBUTE char * 717 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 718 size_t len = strlen(s); 719 void *p = malloc(len+1); 720 dfsan_memcpy(p, s, len+1); 721 *ret_label = 0; 722 return static_cast<char *>(p); 723 } 724 725 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s, 726 dfsan_label s_label, 727 dfsan_label *ret_label, 728 dfsan_origin s_origin, 729 dfsan_origin *ret_origin) { 730 size_t len = strlen(s); 731 void *p = malloc(len + 1); 732 dfsan_memcpy_with_origin(p, s, len + 1); 733 *ret_label = 0; 734 return static_cast<char *>(p); 735 } 736 737 SANITIZER_INTERFACE_ATTRIBUTE char * 738 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, 739 dfsan_label s2_label, dfsan_label n_label, 740 dfsan_label *ret_label) { 741 size_t len = strlen(s2); 742 if (len < n) { 743 dfsan_memcpy(s1, s2, len+1); 744 dfsan_memset(s1+len+1, 0, 0, n-len-1); 745 } else { 746 dfsan_memcpy(s1, s2, n); 747 } 748 749 *ret_label = s1_label; 750 return s1; 751 } 752 753 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy( 754 char *s1, const char *s2, size_t n, dfsan_label s1_label, 755 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 756 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 757 dfsan_origin *ret_origin) { 758 size_t len = strlen(s2); 759 if (len < n) { 760 dfsan_memcpy_with_origin(s1, s2, len + 1); 761 dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1); 762 } else { 763 dfsan_memcpy_with_origin(s1, s2, n); 764 } 765 766 *ret_label = s1_label; 767 *ret_origin = s1_origin; 768 return s1; 769 } 770 771 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 772 __dfsw_pread(int fd, void *buf, size_t count, off_t offset, 773 dfsan_label fd_label, dfsan_label buf_label, 774 dfsan_label count_label, dfsan_label offset_label, 775 dfsan_label *ret_label) { 776 ssize_t ret = pread(fd, buf, count, offset); 777 if (ret > 0) 778 dfsan_set_label(0, buf, ret); 779 *ret_label = 0; 780 return ret; 781 } 782 783 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread( 784 int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label, 785 dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label, 786 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, 787 dfsan_origin count_origin, dfsan_label offset_origin, 788 dfsan_origin *ret_origin) { 789 return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label, 790 offset_label, ret_label); 791 } 792 793 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 794 __dfsw_read(int fd, void *buf, size_t count, 795 dfsan_label fd_label, dfsan_label buf_label, 796 dfsan_label count_label, 797 dfsan_label *ret_label) { 798 ssize_t ret = read(fd, buf, count); 799 if (ret > 0) 800 dfsan_set_label(0, buf, ret); 801 *ret_label = 0; 802 return ret; 803 } 804 805 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read( 806 int fd, void *buf, size_t count, dfsan_label fd_label, 807 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, 808 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, 809 dfsan_origin *ret_origin) { 810 return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label, 811 ret_label); 812 } 813 814 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, 815 struct timespec *tp, 816 dfsan_label clk_id_label, 817 dfsan_label tp_label, 818 dfsan_label *ret_label) { 819 int ret = clock_gettime(clk_id, tp); 820 if (ret == 0) 821 dfsan_set_label(0, tp, sizeof(struct timespec)); 822 *ret_label = 0; 823 return ret; 824 } 825 826 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime( 827 clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label, 828 dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin, 829 dfsan_origin tp_origin, dfsan_origin *ret_origin) { 830 return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label); 831 } 832 833 static void dfsan_set_zero_label(const void *ptr, uptr size) { 834 dfsan_set_label(0, const_cast<void *>(ptr), size); 835 } 836 837 // dlopen() ultimately calls mmap() down inside the loader, which generally 838 // doesn't participate in dynamic symbol resolution. Therefore we won't 839 // intercept its calls to mmap, and we have to hook it here. 840 SANITIZER_INTERFACE_ATTRIBUTE void * 841 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label, 842 dfsan_label flag_label, dfsan_label *ret_label) { 843 void *handle = dlopen(filename, flag); 844 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle); 845 if (map) 846 ForEachMappedRegion(map, dfsan_set_zero_label); 847 *ret_label = 0; 848 return handle; 849 } 850 851 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen( 852 const char *filename, int flag, dfsan_label filename_label, 853 dfsan_label flag_label, dfsan_label *ret_label, 854 dfsan_origin filename_origin, dfsan_origin flag_origin, 855 dfsan_origin *ret_origin) { 856 return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label); 857 } 858 859 static void *DFsanThreadStartFunc(void *arg) { 860 DFsanThread *t = (DFsanThread *)arg; 861 SetCurrentThread(t); 862 t->Init(); 863 SetSigProcMask(&t->starting_sigset_, nullptr); 864 return t->ThreadStart(); 865 } 866 867 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, 868 void *start_routine, void *arg, 869 dfsan_label *ret_label, 870 bool track_origins = false) { 871 pthread_attr_t myattr; 872 if (!attr) { 873 pthread_attr_init(&myattr); 874 attr = &myattr; 875 } 876 877 // Ensure that the thread stack is large enough to hold all TLS data. 878 AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr))); 879 880 DFsanThread *t = 881 DFsanThread::Create((thread_callback_t)start_routine, arg, track_origins); 882 ScopedBlockSignals block(&t->starting_sigset_); 883 int res = pthread_create(thread, attr, DFsanThreadStartFunc, t); 884 885 if (attr == &myattr) 886 pthread_attr_destroy(&myattr); 887 *ret_label = 0; 888 return res; 889 } 890 891 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( 892 pthread_t *thread, const pthread_attr_t *attr, void *start_routine, 893 void *arg, dfsan_label thread_label, dfsan_label attr_label, 894 dfsan_label start_routine_label, dfsan_label arg_label, 895 dfsan_label *ret_label) { 896 return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label); 897 } 898 899 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create( 900 pthread_t *thread, const pthread_attr_t *attr, void *start_routine, 901 void *arg, dfsan_label thread_label, dfsan_label attr_label, 902 dfsan_label start_routine_label, dfsan_label arg_label, 903 dfsan_label *ret_label, dfsan_origin thread_origin, 904 dfsan_origin attr_origin, dfsan_origin start_routine_origin, 905 dfsan_origin arg_origin, dfsan_origin *ret_origin) { 906 return dfsan_pthread_create(thread, attr, start_routine, arg, ret_label, 907 true); 908 } 909 910 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, 911 void **retval, 912 dfsan_label thread_label, 913 dfsan_label retval_label, 914 dfsan_label *ret_label) { 915 int ret = pthread_join(thread, retval); 916 if (ret == 0 && retval) 917 dfsan_set_label(0, retval, sizeof(*retval)); 918 *ret_label = 0; 919 return ret; 920 } 921 922 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join( 923 pthread_t thread, void **retval, dfsan_label thread_label, 924 dfsan_label retval_label, dfsan_label *ret_label, 925 dfsan_origin thread_origin, dfsan_origin retval_origin, 926 dfsan_origin *ret_origin) { 927 return __dfsw_pthread_join(thread, retval, thread_label, retval_label, 928 ret_label); 929 } 930 931 struct dl_iterate_phdr_info { 932 int (*callback)(struct dl_phdr_info *info, size_t size, void *data); 933 void *data; 934 }; 935 936 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { 937 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data; 938 dfsan_set_label(0, *info); 939 dfsan_set_label(0, const_cast<char *>(info->dlpi_name), 940 strlen(info->dlpi_name) + 1); 941 dfsan_set_label( 942 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), 943 sizeof(*info->dlpi_phdr) * info->dlpi_phnum); 944 945 dfsan_clear_thread_local_state(); 946 return dipi->callback(info, size, dipi->data); 947 } 948 949 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( 950 int (*callback)(struct dl_phdr_info *info, size_t size, void *data), 951 void *data, dfsan_label callback_label, dfsan_label data_label, 952 dfsan_label *ret_label) { 953 dl_iterate_phdr_info dipi = {callback, data}; 954 *ret_label = 0; 955 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); 956 } 957 958 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr( 959 int (*callback)(struct dl_phdr_info *info, size_t size, void *data), 960 void *data, dfsan_label callback_label, dfsan_label data_label, 961 dfsan_label *ret_label, dfsan_origin callback_origin, 962 dfsan_origin data_origin, dfsan_origin *ret_origin) { 963 dl_iterate_phdr_info dipi = {callback, data}; 964 *ret_label = 0; 965 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); 966 } 967 968 // This function is only available for glibc 2.27 or newer. Mark it weak so 969 // linking succeeds with older glibcs. 970 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep, 971 size_t *alignp); 972 973 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info( 974 size_t *sizep, size_t *alignp, dfsan_label sizep_label, 975 dfsan_label alignp_label) { 976 assert(_dl_get_tls_static_info); 977 _dl_get_tls_static_info(sizep, alignp); 978 dfsan_set_label(0, sizep, sizeof(*sizep)); 979 dfsan_set_label(0, alignp, sizeof(*alignp)); 980 } 981 982 SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info( 983 size_t *sizep, size_t *alignp, dfsan_label sizep_label, 984 dfsan_label alignp_label, dfsan_origin sizep_origin, 985 dfsan_origin alignp_origin) { 986 __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label); 987 } 988 989 SANITIZER_INTERFACE_ATTRIBUTE 990 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 991 dfsan_label buf_label, dfsan_label *ret_label) { 992 char *ret = ctime_r(timep, buf); 993 if (ret) { 994 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf, 995 strlen(buf) + 1); 996 *ret_label = buf_label; 997 } else { 998 *ret_label = 0; 999 } 1000 return ret; 1001 } 1002 1003 SANITIZER_INTERFACE_ATTRIBUTE 1004 char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 1005 dfsan_label buf_label, dfsan_label *ret_label, 1006 dfsan_origin timep_origin, dfsan_origin buf_origin, 1007 dfsan_origin *ret_origin) { 1008 char *ret = ctime_r(timep, buf); 1009 if (ret) { 1010 dfsan_set_label_origin( 1011 dfsan_read_label(timep, sizeof(time_t)), 1012 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf, 1013 strlen(buf) + 1); 1014 *ret_label = buf_label; 1015 *ret_origin = buf_origin; 1016 } else { 1017 *ret_label = 0; 1018 } 1019 return ret; 1020 } 1021 1022 SANITIZER_INTERFACE_ATTRIBUTE 1023 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 1024 dfsan_label size_label, dfsan_label stream_label, 1025 dfsan_label *ret_label) { 1026 char *ret = fgets(s, size, stream); 1027 if (ret) { 1028 dfsan_set_label(0, ret, strlen(ret) + 1); 1029 *ret_label = s_label; 1030 } else { 1031 *ret_label = 0; 1032 } 1033 return ret; 1034 } 1035 1036 SANITIZER_INTERFACE_ATTRIBUTE 1037 char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 1038 dfsan_label size_label, dfsan_label stream_label, 1039 dfsan_label *ret_label, dfsan_origin s_origin, 1040 dfsan_origin size_origin, dfsan_origin stream_origin, 1041 dfsan_origin *ret_origin) { 1042 char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label, 1043 ret_label); 1044 if (ret) 1045 *ret_origin = s_origin; 1046 return ret; 1047 } 1048 1049 SANITIZER_INTERFACE_ATTRIBUTE 1050 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, 1051 dfsan_label size_label, dfsan_label *ret_label) { 1052 char *ret = getcwd(buf, size); 1053 if (ret) { 1054 dfsan_set_label(0, ret, strlen(ret) + 1); 1055 *ret_label = buf_label; 1056 } else { 1057 *ret_label = 0; 1058 } 1059 return ret; 1060 } 1061 1062 SANITIZER_INTERFACE_ATTRIBUTE 1063 char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label, 1064 dfsan_label size_label, dfsan_label *ret_label, 1065 dfsan_origin buf_origin, dfsan_origin size_origin, 1066 dfsan_origin *ret_origin) { 1067 char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label); 1068 if (ret) 1069 *ret_origin = buf_origin; 1070 return ret; 1071 } 1072 1073 SANITIZER_INTERFACE_ATTRIBUTE 1074 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { 1075 char *ret = get_current_dir_name(); 1076 if (ret) 1077 dfsan_set_label(0, ret, strlen(ret) + 1); 1078 *ret_label = 0; 1079 return ret; 1080 } 1081 1082 SANITIZER_INTERFACE_ATTRIBUTE 1083 char *__dfso_get_current_dir_name(dfsan_label *ret_label, 1084 dfsan_origin *ret_origin) { 1085 return __dfsw_get_current_dir_name(ret_label); 1086 } 1087 1088 // This function is only available for glibc 2.25 or newer. Mark it weak so 1089 // linking succeeds with older glibcs. 1090 SANITIZER_WEAK_ATTRIBUTE int getentropy(void *buffer, size_t length); 1091 1092 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getentropy(void *buffer, size_t length, 1093 dfsan_label buffer_label, 1094 dfsan_label length_label, 1095 dfsan_label *ret_label) { 1096 int ret = getentropy(buffer, length); 1097 if (ret == 0) { 1098 dfsan_set_label(0, buffer, length); 1099 } 1100 *ret_label = 0; 1101 return ret; 1102 } 1103 1104 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getentropy(void *buffer, size_t length, 1105 dfsan_label buffer_label, 1106 dfsan_label length_label, 1107 dfsan_label *ret_label, 1108 dfsan_origin buffer_origin, 1109 dfsan_origin length_origin, 1110 dfsan_origin *ret_origin) { 1111 return __dfsw_getentropy(buffer, length, buffer_label, length_label, 1112 ret_label); 1113 } 1114 1115 SANITIZER_INTERFACE_ATTRIBUTE 1116 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, 1117 dfsan_label len_label, dfsan_label *ret_label) { 1118 int ret = gethostname(name, len); 1119 if (ret == 0) { 1120 dfsan_set_label(0, name, strlen(name) + 1); 1121 } 1122 *ret_label = 0; 1123 return ret; 1124 } 1125 1126 SANITIZER_INTERFACE_ATTRIBUTE 1127 int __dfso_gethostname(char *name, size_t len, dfsan_label name_label, 1128 dfsan_label len_label, dfsan_label *ret_label, 1129 dfsan_origin name_origin, dfsan_origin len_origin, 1130 dfsan_label *ret_origin) { 1131 return __dfsw_gethostname(name, len, name_label, len_label, ret_label); 1132 } 1133 1134 SANITIZER_INTERFACE_ATTRIBUTE 1135 int __dfsw_getrlimit(int resource, struct rlimit *rlim, 1136 dfsan_label resource_label, dfsan_label rlim_label, 1137 dfsan_label *ret_label) { 1138 int ret = getrlimit(resource, rlim); 1139 if (ret == 0) { 1140 dfsan_set_label(0, rlim, sizeof(struct rlimit)); 1141 } 1142 *ret_label = 0; 1143 return ret; 1144 } 1145 1146 SANITIZER_INTERFACE_ATTRIBUTE 1147 int __dfso_getrlimit(int resource, struct rlimit *rlim, 1148 dfsan_label resource_label, dfsan_label rlim_label, 1149 dfsan_label *ret_label, dfsan_origin resource_origin, 1150 dfsan_origin rlim_origin, dfsan_origin *ret_origin) { 1151 return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label, 1152 ret_label); 1153 } 1154 1155 SANITIZER_INTERFACE_ATTRIBUTE 1156 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, 1157 dfsan_label usage_label, dfsan_label *ret_label) { 1158 int ret = getrusage(who, usage); 1159 if (ret == 0) { 1160 dfsan_set_label(0, usage, sizeof(struct rusage)); 1161 } 1162 *ret_label = 0; 1163 return ret; 1164 } 1165 1166 SANITIZER_INTERFACE_ATTRIBUTE 1167 int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label, 1168 dfsan_label usage_label, dfsan_label *ret_label, 1169 dfsan_origin who_origin, dfsan_origin usage_origin, 1170 dfsan_label *ret_origin) { 1171 return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label); 1172 } 1173 1174 SANITIZER_INTERFACE_ATTRIBUTE 1175 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, 1176 dfsan_label src_label, dfsan_label *ret_label) { 1177 char *ret = strcpy(dest, src); 1178 if (ret) { 1179 dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1); 1180 } 1181 *ret_label = dst_label; 1182 return ret; 1183 } 1184 1185 SANITIZER_INTERFACE_ATTRIBUTE 1186 char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label, 1187 dfsan_label src_label, dfsan_label *ret_label, 1188 dfsan_origin dst_origin, dfsan_origin src_origin, 1189 dfsan_origin *ret_origin) { 1190 char *ret = strcpy(dest, src); 1191 if (ret) { 1192 size_t str_len = strlen(src) + 1; 1193 dfsan_mem_origin_transfer(dest, src, str_len); 1194 dfsan_mem_shadow_transfer(dest, src, str_len); 1195 } 1196 *ret_label = dst_label; 1197 *ret_origin = dst_origin; 1198 return ret; 1199 } 1200 1201 static long int dfsan_strtol(const char *nptr, char **endptr, int base, 1202 char **tmp_endptr) { 1203 assert(tmp_endptr); 1204 long int ret = strtol(nptr, tmp_endptr, base); 1205 if (endptr) 1206 *endptr = *tmp_endptr; 1207 return ret; 1208 } 1209 1210 static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr, 1211 dfsan_label base_label, 1212 dfsan_label *ret_label) { 1213 if (tmp_endptr > nptr) { 1214 // If *tmp_endptr is '\0' include its label as well. 1215 *ret_label = dfsan_union( 1216 base_label, 1217 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 1218 } else { 1219 *ret_label = 0; 1220 } 1221 } 1222 1223 static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr, 1224 dfsan_label base_label, 1225 dfsan_label *ret_label, 1226 dfsan_origin base_origin, 1227 dfsan_origin *ret_origin) { 1228 if (tmp_endptr > nptr) { 1229 // When multiple inputs are tainted, we propagate one of its origins. 1230 // Because checking if base_label is tainted does not need additional 1231 // computation, we prefer to propagating base_origin. 1232 *ret_origin = base_label 1233 ? base_origin 1234 : dfsan_read_origin_of_first_taint( 1235 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1236 } 1237 } 1238 1239 SANITIZER_INTERFACE_ATTRIBUTE 1240 long int __dfsw_strtol(const char *nptr, char **endptr, int base, 1241 dfsan_label nptr_label, dfsan_label endptr_label, 1242 dfsan_label base_label, dfsan_label *ret_label) { 1243 char *tmp_endptr; 1244 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); 1245 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1246 return ret; 1247 } 1248 1249 SANITIZER_INTERFACE_ATTRIBUTE 1250 long int __dfso_strtol(const char *nptr, char **endptr, int base, 1251 dfsan_label nptr_label, dfsan_label endptr_label, 1252 dfsan_label base_label, dfsan_label *ret_label, 1253 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1254 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1255 char *tmp_endptr; 1256 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); 1257 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1258 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1259 ret_origin); 1260 return ret; 1261 } 1262 1263 static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) { 1264 assert(tmp_endptr); 1265 double ret = strtod(nptr, tmp_endptr); 1266 if (endptr) 1267 *endptr = *tmp_endptr; 1268 return ret; 1269 } 1270 1271 static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr, 1272 dfsan_label *ret_label) { 1273 if (tmp_endptr > nptr) { 1274 // If *tmp_endptr is '\0' include its label as well. 1275 *ret_label = dfsan_read_label( 1276 nptr, 1277 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1278 } else { 1279 *ret_label = 0; 1280 } 1281 } 1282 1283 SANITIZER_INTERFACE_ATTRIBUTE 1284 double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, 1285 dfsan_label endptr_label, dfsan_label *ret_label) { 1286 char *tmp_endptr; 1287 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); 1288 dfsan_strtod_label(nptr, tmp_endptr, ret_label); 1289 return ret; 1290 } 1291 1292 SANITIZER_INTERFACE_ATTRIBUTE 1293 double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, 1294 dfsan_label endptr_label, dfsan_label *ret_label, 1295 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1296 dfsan_origin *ret_origin) { 1297 char *tmp_endptr; 1298 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); 1299 dfsan_strtod_label(nptr, tmp_endptr, ret_label); 1300 if (tmp_endptr > nptr) { 1301 // If *tmp_endptr is '\0' include its label as well. 1302 *ret_origin = dfsan_read_origin_of_first_taint( 1303 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1304 } else { 1305 *ret_origin = 0; 1306 } 1307 return ret; 1308 } 1309 1310 static long long int dfsan_strtoll(const char *nptr, char **endptr, int base, 1311 char **tmp_endptr) { 1312 assert(tmp_endptr); 1313 long long int ret = strtoll(nptr, tmp_endptr, base); 1314 if (endptr) 1315 *endptr = *tmp_endptr; 1316 return ret; 1317 } 1318 1319 SANITIZER_INTERFACE_ATTRIBUTE 1320 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, 1321 dfsan_label nptr_label, dfsan_label endptr_label, 1322 dfsan_label base_label, dfsan_label *ret_label) { 1323 char *tmp_endptr; 1324 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); 1325 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1326 return ret; 1327 } 1328 1329 SANITIZER_INTERFACE_ATTRIBUTE 1330 long long int __dfso_strtoll(const char *nptr, char **endptr, int base, 1331 dfsan_label nptr_label, dfsan_label endptr_label, 1332 dfsan_label base_label, dfsan_label *ret_label, 1333 dfsan_origin nptr_origin, 1334 dfsan_origin endptr_origin, 1335 dfsan_origin base_origin, 1336 dfsan_origin *ret_origin) { 1337 char *tmp_endptr; 1338 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); 1339 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1340 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1341 ret_origin); 1342 return ret; 1343 } 1344 1345 static unsigned long int dfsan_strtoul(const char *nptr, char **endptr, 1346 int base, char **tmp_endptr) { 1347 assert(tmp_endptr); 1348 unsigned long int ret = strtoul(nptr, tmp_endptr, base); 1349 if (endptr) 1350 *endptr = *tmp_endptr; 1351 return ret; 1352 } 1353 1354 SANITIZER_INTERFACE_ATTRIBUTE 1355 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base, 1356 dfsan_label nptr_label, dfsan_label endptr_label, 1357 dfsan_label base_label, dfsan_label *ret_label) { 1358 char *tmp_endptr; 1359 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); 1360 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1361 return ret; 1362 } 1363 1364 SANITIZER_INTERFACE_ATTRIBUTE 1365 unsigned long int __dfso_strtoul( 1366 const char *nptr, char **endptr, int base, dfsan_label nptr_label, 1367 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, 1368 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1369 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1370 char *tmp_endptr; 1371 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); 1372 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1373 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1374 ret_origin); 1375 return ret; 1376 } 1377 1378 static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr, 1379 int base, char **tmp_endptr) { 1380 assert(tmp_endptr); 1381 long long unsigned int ret = strtoull(nptr, tmp_endptr, base); 1382 if (endptr) 1383 *endptr = *tmp_endptr; 1384 return ret; 1385 } 1386 1387 SANITIZER_INTERFACE_ATTRIBUTE 1388 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, 1389 int base, dfsan_label nptr_label, 1390 dfsan_label endptr_label, 1391 dfsan_label base_label, 1392 dfsan_label *ret_label) { 1393 char *tmp_endptr; 1394 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); 1395 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1396 return ret; 1397 } 1398 1399 SANITIZER_INTERFACE_ATTRIBUTE 1400 long long unsigned int __dfso_strtoull( 1401 const char *nptr, char **endptr, int base, dfsan_label nptr_label, 1402 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, 1403 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1404 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1405 char *tmp_endptr; 1406 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); 1407 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1408 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1409 ret_origin); 1410 return ret; 1411 } 1412 1413 SANITIZER_INTERFACE_ATTRIBUTE 1414 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { 1415 time_t ret = time(t); 1416 if (ret != (time_t) -1 && t) { 1417 dfsan_set_label(0, t, sizeof(time_t)); 1418 } 1419 *ret_label = 0; 1420 return ret; 1421 } 1422 1423 SANITIZER_INTERFACE_ATTRIBUTE 1424 time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label, 1425 dfsan_origin t_origin, dfsan_origin *ret_origin) { 1426 return __dfsw_time(t, t_label, ret_label); 1427 } 1428 1429 SANITIZER_INTERFACE_ATTRIBUTE 1430 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 1431 dfsan_label src_label, dfsan_label dst_label, 1432 dfsan_label *ret_label) { 1433 int ret = inet_pton(af, src, dst); 1434 if (ret == 1) { 1435 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst, 1436 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 1437 } 1438 *ret_label = 0; 1439 return ret; 1440 } 1441 1442 SANITIZER_INTERFACE_ATTRIBUTE 1443 int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 1444 dfsan_label src_label, dfsan_label dst_label, 1445 dfsan_label *ret_label, dfsan_origin af_origin, 1446 dfsan_origin src_origin, dfsan_origin dst_origin, 1447 dfsan_origin *ret_origin) { 1448 int ret = inet_pton(af, src, dst); 1449 if (ret == 1) { 1450 int src_len = strlen(src) + 1; 1451 dfsan_set_label_origin( 1452 dfsan_read_label(src, src_len), 1453 dfsan_read_origin_of_first_taint(src, src_len), dst, 1454 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 1455 } 1456 *ret_label = 0; 1457 return ret; 1458 } 1459 1460 SANITIZER_INTERFACE_ATTRIBUTE 1461 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, 1462 dfsan_label timep_label, dfsan_label result_label, 1463 dfsan_label *ret_label) { 1464 struct tm *ret = localtime_r(timep, result); 1465 if (ret) { 1466 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result, 1467 sizeof(struct tm)); 1468 *ret_label = result_label; 1469 } else { 1470 *ret_label = 0; 1471 } 1472 return ret; 1473 } 1474 1475 SANITIZER_INTERFACE_ATTRIBUTE 1476 struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result, 1477 dfsan_label timep_label, dfsan_label result_label, 1478 dfsan_label *ret_label, dfsan_origin timep_origin, 1479 dfsan_origin result_origin, 1480 dfsan_origin *ret_origin) { 1481 struct tm *ret = localtime_r(timep, result); 1482 if (ret) { 1483 dfsan_set_label_origin( 1484 dfsan_read_label(timep, sizeof(time_t)), 1485 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result, 1486 sizeof(struct tm)); 1487 *ret_label = result_label; 1488 *ret_origin = result_origin; 1489 } else { 1490 *ret_label = 0; 1491 } 1492 return ret; 1493 } 1494 1495 SANITIZER_INTERFACE_ATTRIBUTE 1496 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, 1497 char *buf, size_t buflen, struct passwd **result, 1498 dfsan_label uid_label, dfsan_label pwd_label, 1499 dfsan_label buf_label, dfsan_label buflen_label, 1500 dfsan_label result_label, dfsan_label *ret_label) { 1501 // Store the data in pwd, the strings referenced from pwd in buf, and the 1502 // address of pwd in *result. On failure, NULL is stored in *result. 1503 int ret = getpwuid_r(uid, pwd, buf, buflen, result); 1504 if (ret == 0) { 1505 dfsan_set_label(0, pwd, sizeof(struct passwd)); 1506 dfsan_set_label(0, buf, strlen(buf) + 1); 1507 } 1508 *ret_label = 0; 1509 dfsan_set_label(0, result, sizeof(struct passwd*)); 1510 return ret; 1511 } 1512 1513 SANITIZER_INTERFACE_ATTRIBUTE 1514 int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, 1515 struct passwd **result, dfsan_label uid_label, 1516 dfsan_label pwd_label, dfsan_label buf_label, 1517 dfsan_label buflen_label, dfsan_label result_label, 1518 dfsan_label *ret_label, dfsan_origin uid_origin, 1519 dfsan_origin pwd_origin, dfsan_origin buf_origin, 1520 dfsan_origin buflen_origin, dfsan_origin result_origin, 1521 dfsan_origin *ret_origin) { 1522 return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label, 1523 buf_label, buflen_label, result_label, ret_label); 1524 } 1525 1526 SANITIZER_INTERFACE_ATTRIBUTE 1527 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, 1528 int timeout, dfsan_label epfd_label, 1529 dfsan_label events_label, dfsan_label maxevents_label, 1530 dfsan_label timeout_label, dfsan_label *ret_label) { 1531 int ret = epoll_wait(epfd, events, maxevents, timeout); 1532 if (ret > 0) 1533 dfsan_set_label(0, events, ret * sizeof(*events)); 1534 *ret_label = 0; 1535 return ret; 1536 } 1537 1538 SANITIZER_INTERFACE_ATTRIBUTE 1539 int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents, 1540 int timeout, dfsan_label epfd_label, 1541 dfsan_label events_label, dfsan_label maxevents_label, 1542 dfsan_label timeout_label, dfsan_label *ret_label, 1543 dfsan_origin epfd_origin, dfsan_origin events_origin, 1544 dfsan_origin maxevents_origin, 1545 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1546 return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label, 1547 events_label, maxevents_label, timeout_label, 1548 ret_label); 1549 } 1550 1551 SANITIZER_INTERFACE_ATTRIBUTE 1552 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, 1553 dfsan_label dfs_label, dfsan_label nfds_label, 1554 dfsan_label timeout_label, dfsan_label *ret_label) { 1555 int ret = poll(fds, nfds, timeout); 1556 if (ret >= 0) { 1557 for (; nfds > 0; --nfds) { 1558 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents)); 1559 } 1560 } 1561 *ret_label = 0; 1562 return ret; 1563 } 1564 1565 SANITIZER_INTERFACE_ATTRIBUTE 1566 int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout, 1567 dfsan_label dfs_label, dfsan_label nfds_label, 1568 dfsan_label timeout_label, dfsan_label *ret_label, 1569 dfsan_origin dfs_origin, dfsan_origin nfds_origin, 1570 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1571 return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label, 1572 ret_label); 1573 } 1574 1575 SANITIZER_INTERFACE_ATTRIBUTE 1576 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, 1577 fd_set *exceptfds, struct timeval *timeout, 1578 dfsan_label nfds_label, dfsan_label readfds_label, 1579 dfsan_label writefds_label, dfsan_label exceptfds_label, 1580 dfsan_label timeout_label, dfsan_label *ret_label) { 1581 int ret = select(nfds, readfds, writefds, exceptfds, timeout); 1582 // Clear everything (also on error) since their content is either set or 1583 // undefined. 1584 if (readfds) { 1585 dfsan_set_label(0, readfds, sizeof(fd_set)); 1586 } 1587 if (writefds) { 1588 dfsan_set_label(0, writefds, sizeof(fd_set)); 1589 } 1590 if (exceptfds) { 1591 dfsan_set_label(0, exceptfds, sizeof(fd_set)); 1592 } 1593 dfsan_set_label(0, timeout, sizeof(struct timeval)); 1594 *ret_label = 0; 1595 return ret; 1596 } 1597 1598 SANITIZER_INTERFACE_ATTRIBUTE 1599 int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds, 1600 fd_set *exceptfds, struct timeval *timeout, 1601 dfsan_label nfds_label, dfsan_label readfds_label, 1602 dfsan_label writefds_label, dfsan_label exceptfds_label, 1603 dfsan_label timeout_label, dfsan_label *ret_label, 1604 dfsan_origin nfds_origin, dfsan_origin readfds_origin, 1605 dfsan_origin writefds_origin, dfsan_origin exceptfds_origin, 1606 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1607 return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label, 1608 readfds_label, writefds_label, exceptfds_label, 1609 timeout_label, ret_label); 1610 } 1611 1612 SANITIZER_INTERFACE_ATTRIBUTE 1613 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 1614 dfsan_label pid_label, 1615 dfsan_label cpusetsize_label, 1616 dfsan_label mask_label, dfsan_label *ret_label) { 1617 int ret = sched_getaffinity(pid, cpusetsize, mask); 1618 if (ret == 0) { 1619 dfsan_set_label(0, mask, cpusetsize); 1620 } 1621 *ret_label = 0; 1622 return ret; 1623 } 1624 1625 SANITIZER_INTERFACE_ATTRIBUTE 1626 int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 1627 dfsan_label pid_label, 1628 dfsan_label cpusetsize_label, 1629 dfsan_label mask_label, dfsan_label *ret_label, 1630 dfsan_origin pid_origin, 1631 dfsan_origin cpusetsize_origin, 1632 dfsan_origin mask_origin, 1633 dfsan_origin *ret_origin) { 1634 return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label, 1635 cpusetsize_label, mask_label, ret_label); 1636 } 1637 1638 SANITIZER_INTERFACE_ATTRIBUTE 1639 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, 1640 dfsan_label *ret_label) { 1641 int ret = sigemptyset(set); 1642 dfsan_set_label(0, set, sizeof(sigset_t)); 1643 *ret_label = 0; 1644 return ret; 1645 } 1646 1647 SANITIZER_INTERFACE_ATTRIBUTE 1648 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label, 1649 dfsan_label *ret_label, dfsan_origin set_origin, 1650 dfsan_origin *ret_origin) { 1651 return __dfsw_sigemptyset(set, set_label, ret_label); 1652 } 1653 1654 class SignalHandlerScope { 1655 public: 1656 SignalHandlerScope() { 1657 if (DFsanThread *t = GetCurrentThread()) 1658 t->EnterSignalHandler(); 1659 } 1660 ~SignalHandlerScope() { 1661 if (DFsanThread *t = GetCurrentThread()) 1662 t->LeaveSignalHandler(); 1663 } 1664 }; 1665 1666 // Clear DFSan runtime TLS state at the end of a scope. 1667 // 1668 // Implementation must be async-signal-safe and use small data size, because 1669 // instances of this class may live on the signal handler stack. 1670 // 1671 // DFSan uses TLS to pass metadata of arguments and return values. When an 1672 // instrumented function accesses the TLS, if a signal callback happens, and the 1673 // callback calls other instrumented functions with updating the same TLS, the 1674 // TLS is in an inconsistent state after the callback ends. This may cause 1675 // either under-tainting or over-tainting. 1676 // 1677 // The current implementation simply resets TLS at restore. This prevents from 1678 // over-tainting. Although under-tainting may still happen, a taint flow can be 1679 // found eventually if we run a DFSan-instrumented program multiple times. The 1680 // alternative option is saving the entire TLS. However the TLS storage takes 1681 // 2k bytes, and signal calls could be nested. So it does not seem worth. 1682 class ScopedClearThreadLocalState { 1683 public: 1684 ScopedClearThreadLocalState() {} 1685 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); } 1686 }; 1687 1688 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls. 1689 const int kMaxSignals = 1024; 1690 static atomic_uintptr_t sigactions[kMaxSignals]; 1691 1692 static void SignalHandler(int signo) { 1693 SignalHandlerScope signal_handler_scope; 1694 ScopedClearThreadLocalState scoped_clear_tls; 1695 1696 // Clear shadows for all inputs provided by system. 1697 dfsan_clear_arg_tls(0, sizeof(dfsan_label)); 1698 1699 typedef void (*signal_cb)(int x); 1700 signal_cb cb = 1701 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1702 cb(signo); 1703 } 1704 1705 static void SignalAction(int signo, siginfo_t *si, void *uc) { 1706 SignalHandlerScope signal_handler_scope; 1707 ScopedClearThreadLocalState scoped_clear_tls; 1708 1709 // Clear shadows for all inputs provided by system. Similar to SignalHandler. 1710 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label)); 1711 dfsan_set_label(0, si, sizeof(*si)); 1712 dfsan_set_label(0, uc, sizeof(ucontext_t)); 1713 1714 typedef void (*sigaction_cb)(int, siginfo_t *, void *); 1715 sigaction_cb cb = 1716 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1717 cb(signo, si, uc); 1718 } 1719 1720 SANITIZER_INTERFACE_ATTRIBUTE 1721 int __dfsw_sigaction(int signum, const struct sigaction *act, 1722 struct sigaction *oldact, dfsan_label signum_label, 1723 dfsan_label act_label, dfsan_label oldact_label, 1724 dfsan_label *ret_label) { 1725 CHECK_LT(signum, kMaxSignals); 1726 SignalSpinLocker lock; 1727 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1728 struct sigaction new_act; 1729 struct sigaction *pnew_act = act ? &new_act : nullptr; 1730 if (act) { 1731 internal_memcpy(pnew_act, act, sizeof(struct sigaction)); 1732 if (pnew_act->sa_flags & SA_SIGINFO) { 1733 uptr cb = (uptr)(pnew_act->sa_sigaction); 1734 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1735 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1736 pnew_act->sa_sigaction = SignalAction; 1737 } 1738 } else { 1739 uptr cb = (uptr)(pnew_act->sa_handler); 1740 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1741 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1742 pnew_act->sa_handler = SignalHandler; 1743 } 1744 } 1745 } 1746 1747 int ret = sigaction(signum, pnew_act, oldact); 1748 1749 if (ret == 0 && oldact) { 1750 if (oldact->sa_flags & SA_SIGINFO) { 1751 if (oldact->sa_sigaction == SignalAction) 1752 oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb; 1753 } else { 1754 if (oldact->sa_handler == SignalHandler) 1755 oldact->sa_handler = (decltype(oldact->sa_handler))old_cb; 1756 } 1757 } 1758 1759 if (oldact) { 1760 dfsan_set_label(0, oldact, sizeof(struct sigaction)); 1761 } 1762 *ret_label = 0; 1763 return ret; 1764 } 1765 1766 SANITIZER_INTERFACE_ATTRIBUTE 1767 int __dfso_sigaction(int signum, const struct sigaction *act, 1768 struct sigaction *oldact, dfsan_label signum_label, 1769 dfsan_label act_label, dfsan_label oldact_label, 1770 dfsan_label *ret_label, dfsan_origin signum_origin, 1771 dfsan_origin act_origin, dfsan_origin oldact_origin, 1772 dfsan_origin *ret_origin) { 1773 return __dfsw_sigaction(signum, act, oldact, signum_label, act_label, 1774 oldact_label, ret_label); 1775 } 1776 1777 static sighandler_t dfsan_signal(int signum, sighandler_t handler, 1778 dfsan_label *ret_label) { 1779 CHECK_LT(signum, kMaxSignals); 1780 SignalSpinLocker lock; 1781 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1782 if (handler != SIG_IGN && handler != SIG_DFL) { 1783 atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed); 1784 handler = &SignalHandler; 1785 } 1786 1787 sighandler_t ret = signal(signum, handler); 1788 1789 if (ret == SignalHandler) 1790 ret = (sighandler_t)old_cb; 1791 1792 *ret_label = 0; 1793 return ret; 1794 } 1795 1796 SANITIZER_INTERFACE_ATTRIBUTE 1797 sighandler_t __dfsw_signal(int signum, sighandler_t handler, 1798 dfsan_label signum_label, dfsan_label handler_label, 1799 dfsan_label *ret_label) { 1800 return dfsan_signal(signum, handler, ret_label); 1801 } 1802 1803 SANITIZER_INTERFACE_ATTRIBUTE 1804 sighandler_t __dfso_signal(int signum, sighandler_t handler, 1805 dfsan_label signum_label, dfsan_label handler_label, 1806 dfsan_label *ret_label, dfsan_origin signum_origin, 1807 dfsan_origin handler_origin, 1808 dfsan_origin *ret_origin) { 1809 return dfsan_signal(signum, handler, ret_label); 1810 } 1811 1812 SANITIZER_INTERFACE_ATTRIBUTE 1813 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1814 dfsan_label old_ss_label, dfsan_label *ret_label) { 1815 int ret = sigaltstack(ss, old_ss); 1816 if (ret != -1 && old_ss) 1817 dfsan_set_label(0, old_ss, sizeof(*old_ss)); 1818 *ret_label = 0; 1819 return ret; 1820 } 1821 1822 SANITIZER_INTERFACE_ATTRIBUTE 1823 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1824 dfsan_label old_ss_label, dfsan_label *ret_label, 1825 dfsan_origin ss_origin, dfsan_origin old_ss_origin, 1826 dfsan_origin *ret_origin) { 1827 return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label); 1828 } 1829 1830 SANITIZER_INTERFACE_ATTRIBUTE 1831 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, 1832 dfsan_label tv_label, dfsan_label tz_label, 1833 dfsan_label *ret_label) { 1834 int ret = gettimeofday(tv, tz); 1835 if (tv) { 1836 dfsan_set_label(0, tv, sizeof(struct timeval)); 1837 } 1838 if (tz) { 1839 dfsan_set_label(0, tz, sizeof(struct timezone)); 1840 } 1841 *ret_label = 0; 1842 return ret; 1843 } 1844 1845 SANITIZER_INTERFACE_ATTRIBUTE 1846 int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz, 1847 dfsan_label tv_label, dfsan_label tz_label, 1848 dfsan_label *ret_label, dfsan_origin tv_origin, 1849 dfsan_origin tz_origin, dfsan_origin *ret_origin) { 1850 return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label); 1851 } 1852 1853 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, 1854 dfsan_label s_label, 1855 dfsan_label c_label, 1856 dfsan_label n_label, 1857 dfsan_label *ret_label) { 1858 void *ret = memchr(s, c, n); 1859 if (flags().strict_data_dependencies) { 1860 *ret_label = ret ? s_label : 0; 1861 } else { 1862 size_t len = 1863 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 1864 : n; 1865 *ret_label = 1866 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); 1867 } 1868 return ret; 1869 } 1870 1871 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr( 1872 void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label, 1873 dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin, 1874 dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) { 1875 void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label); 1876 if (flags().strict_data_dependencies) { 1877 if (ret) 1878 *ret_origin = s_origin; 1879 } else { 1880 size_t len = 1881 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 1882 : n; 1883 dfsan_origin o = dfsan_read_origin_of_first_taint(s, len); 1884 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 1885 } 1886 return ret; 1887 } 1888 1889 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, 1890 dfsan_label s_label, 1891 dfsan_label c_label, 1892 dfsan_label *ret_label) { 1893 char *ret = strrchr(s, c); 1894 if (flags().strict_data_dependencies) { 1895 *ret_label = ret ? s_label : 0; 1896 } else { 1897 *ret_label = 1898 dfsan_union(dfsan_read_label(s, strlen(s) + 1), 1899 dfsan_union(s_label, c_label)); 1900 } 1901 1902 return ret; 1903 } 1904 1905 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr( 1906 char *s, int c, dfsan_label s_label, dfsan_label c_label, 1907 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, 1908 dfsan_origin *ret_origin) { 1909 char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label); 1910 if (flags().strict_data_dependencies) { 1911 if (ret) 1912 *ret_origin = s_origin; 1913 } else { 1914 size_t s_len = strlen(s) + 1; 1915 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len); 1916 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 1917 } 1918 1919 return ret; 1920 } 1921 1922 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, 1923 dfsan_label haystack_label, 1924 dfsan_label needle_label, 1925 dfsan_label *ret_label) { 1926 char *ret = strstr(haystack, needle); 1927 if (flags().strict_data_dependencies) { 1928 *ret_label = ret ? haystack_label : 0; 1929 } else { 1930 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1; 1931 *ret_label = 1932 dfsan_union(dfsan_read_label(haystack, len), 1933 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1), 1934 dfsan_union(haystack_label, needle_label))); 1935 } 1936 1937 return ret; 1938 } 1939 1940 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle, 1941 dfsan_label haystack_label, 1942 dfsan_label needle_label, 1943 dfsan_label *ret_label, 1944 dfsan_origin haystack_origin, 1945 dfsan_origin needle_origin, 1946 dfsan_origin *ret_origin) { 1947 char *ret = 1948 __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label); 1949 if (flags().strict_data_dependencies) { 1950 if (ret) 1951 *ret_origin = haystack_origin; 1952 } else { 1953 size_t needle_len = strlen(needle); 1954 size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1; 1955 dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len); 1956 if (o) { 1957 *ret_origin = o; 1958 } else { 1959 o = dfsan_read_origin_of_first_taint(needle, needle_len + 1); 1960 *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin); 1961 } 1962 } 1963 1964 return ret; 1965 } 1966 1967 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, 1968 struct timespec *rem, 1969 dfsan_label req_label, 1970 dfsan_label rem_label, 1971 dfsan_label *ret_label) { 1972 int ret = nanosleep(req, rem); 1973 *ret_label = 0; 1974 if (ret == -1) { 1975 // Interrupted by a signal, rem is filled with the remaining time. 1976 dfsan_set_label(0, rem, sizeof(struct timespec)); 1977 } 1978 return ret; 1979 } 1980 1981 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep( 1982 const struct timespec *req, struct timespec *rem, dfsan_label req_label, 1983 dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin, 1984 dfsan_origin rem_origin, dfsan_origin *ret_origin) { 1985 return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label); 1986 } 1987 1988 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) { 1989 dfsan_set_label(0, msg, sizeof(*msg)); 1990 dfsan_set_label(0, msg->msg_name, msg->msg_namelen); 1991 dfsan_set_label(0, msg->msg_control, msg->msg_controllen); 1992 for (size_t i = 0; bytes_written > 0; ++i) { 1993 assert(i < msg->msg_iovlen); 1994 struct iovec *iov = &msg->msg_iov[i]; 1995 size_t iov_written = 1996 bytes_written < iov->iov_len ? bytes_written : iov->iov_len; 1997 dfsan_set_label(0, iov->iov_base, iov_written); 1998 bytes_written -= iov_written; 1999 } 2000 } 2001 2002 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg( 2003 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, 2004 struct timespec *timeout, dfsan_label sockfd_label, 2005 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, 2006 dfsan_label timeout_label, dfsan_label *ret_label) { 2007 int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout); 2008 for (int i = 0; i < ret; ++i) { 2009 dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len)); 2010 clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr); 2011 } 2012 *ret_label = 0; 2013 return ret; 2014 } 2015 2016 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg( 2017 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, 2018 struct timespec *timeout, dfsan_label sockfd_label, 2019 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, 2020 dfsan_label timeout_label, dfsan_label *ret_label, 2021 dfsan_origin sockfd_origin, dfsan_origin msgvec_origin, 2022 dfsan_origin vlen_origin, dfsan_origin flags_origin, 2023 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 2024 return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label, 2025 msgvec_label, vlen_label, flags_label, timeout_label, 2026 ret_label); 2027 } 2028 2029 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg( 2030 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, 2031 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) { 2032 ssize_t ret = recvmsg(sockfd, msg, flags); 2033 if (ret >= 0) 2034 clear_msghdr_labels(ret, msg); 2035 *ret_label = 0; 2036 return ret; 2037 } 2038 2039 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg( 2040 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, 2041 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label, 2042 dfsan_origin sockfd_origin, dfsan_origin msg_origin, 2043 dfsan_origin flags_origin, dfsan_origin *ret_origin) { 2044 return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label, 2045 flags_label, ret_label); 2046 } 2047 2048 SANITIZER_INTERFACE_ATTRIBUTE int 2049 __dfsw_socketpair(int domain, int type, int protocol, int sv[2], 2050 dfsan_label domain_label, dfsan_label type_label, 2051 dfsan_label protocol_label, dfsan_label sv_label, 2052 dfsan_label *ret_label) { 2053 int ret = socketpair(domain, type, protocol, sv); 2054 *ret_label = 0; 2055 if (ret == 0) { 2056 dfsan_set_label(0, sv, sizeof(*sv) * 2); 2057 } 2058 return ret; 2059 } 2060 2061 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair( 2062 int domain, int type, int protocol, int sv[2], dfsan_label domain_label, 2063 dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label, 2064 dfsan_label *ret_label, dfsan_origin domain_origin, 2065 dfsan_origin type_origin, dfsan_origin protocol_origin, 2066 dfsan_origin sv_origin, dfsan_origin *ret_origin) { 2067 return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label, 2068 protocol_label, sv_label, ret_label); 2069 } 2070 2071 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt( 2072 int sockfd, int level, int optname, void *optval, socklen_t *optlen, 2073 dfsan_label sockfd_label, dfsan_label level_label, 2074 dfsan_label optname_label, dfsan_label optval_label, 2075 dfsan_label optlen_label, dfsan_label *ret_label) { 2076 int ret = getsockopt(sockfd, level, optname, optval, optlen); 2077 if (ret != -1 && optval && optlen) { 2078 dfsan_set_label(0, optlen, sizeof(*optlen)); 2079 dfsan_set_label(0, optval, *optlen); 2080 } 2081 *ret_label = 0; 2082 return ret; 2083 } 2084 2085 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt( 2086 int sockfd, int level, int optname, void *optval, socklen_t *optlen, 2087 dfsan_label sockfd_label, dfsan_label level_label, 2088 dfsan_label optname_label, dfsan_label optval_label, 2089 dfsan_label optlen_label, dfsan_label *ret_label, 2090 dfsan_origin sockfd_origin, dfsan_origin level_origin, 2091 dfsan_origin optname_origin, dfsan_origin optval_origin, 2092 dfsan_origin optlen_origin, dfsan_origin *ret_origin) { 2093 return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label, 2094 level_label, optname_label, optval_label, 2095 optlen_label, ret_label); 2096 } 2097 2098 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname( 2099 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2100 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2101 dfsan_label *ret_label) { 2102 socklen_t origlen = addrlen ? *addrlen : 0; 2103 int ret = getsockname(sockfd, addr, addrlen); 2104 if (ret != -1 && addr && addrlen) { 2105 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 2106 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 2107 dfsan_set_label(0, addr, written_bytes); 2108 } 2109 *ret_label = 0; 2110 return ret; 2111 } 2112 2113 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname( 2114 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2115 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2116 dfsan_label *ret_label, dfsan_origin sockfd_origin, 2117 dfsan_origin addr_origin, dfsan_origin addrlen_origin, 2118 dfsan_origin *ret_origin) { 2119 return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label, 2120 addrlen_label, ret_label); 2121 } 2122 2123 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername( 2124 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2125 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2126 dfsan_label *ret_label) { 2127 socklen_t origlen = addrlen ? *addrlen : 0; 2128 int ret = getpeername(sockfd, addr, addrlen); 2129 if (ret != -1 && addr && addrlen) { 2130 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 2131 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 2132 dfsan_set_label(0, addr, written_bytes); 2133 } 2134 *ret_label = 0; 2135 return ret; 2136 } 2137 2138 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername( 2139 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2140 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2141 dfsan_label *ret_label, dfsan_origin sockfd_origin, 2142 dfsan_origin addr_origin, dfsan_origin addrlen_origin, 2143 dfsan_origin *ret_origin) { 2144 return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label, 2145 addrlen_label, ret_label); 2146 } 2147 2148 // Type of the function passed to dfsan_set_write_callback. 2149 typedef void (*write_dfsan_callback_t)(int fd, const void *buf, ssize_t count); 2150 2151 // Calls to dfsan_set_write_callback() set the values in this struct. 2152 // Calls to the custom version of write() read (and invoke) them. 2153 static struct { 2154 write_dfsan_callback_t write_callback = nullptr; 2155 } write_callback_info; 2156 2157 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw_dfsan_set_write_callback( 2158 write_dfsan_callback_t write_callback, dfsan_label write_callback_label, 2159 dfsan_label *ret_label) { 2160 write_callback_info.write_callback = write_callback; 2161 } 2162 2163 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback( 2164 write_dfsan_callback_t write_callback, dfsan_label write_callback_label, 2165 dfsan_label *ret_label, dfsan_origin write_callback_origin, 2166 dfsan_origin *ret_origin) { 2167 write_callback_info.write_callback = write_callback; 2168 } 2169 2170 static inline void setup_tls_args_for_write_callback( 2171 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, 2172 bool origins, dfsan_origin fd_origin, dfsan_origin buf_origin, 2173 dfsan_origin count_origin) { 2174 // The callback code will expect argument shadow labels in the args TLS, 2175 // and origin labels in the origin args TLS. 2176 // Previously this was done by a trampoline, but we want to remove this: 2177 // https://github.com/llvm/llvm-project/issues/54172 2178 // 2179 // Instead, this code is manually setting up the args TLS data. 2180 // 2181 // The offsets used need to correspond with the instrumentation code, 2182 // see llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp 2183 // DFSanFunction::getShadowForTLSArgument. 2184 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L1684 2185 // https://github.com/llvm/llvm-project/blob/0acc9e4b5edd8b39ff3d4c6d0e17f02007671c4e/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp#L125 2186 // 2187 // Here the arguments are all primitives, but it can be more complex 2188 // to compute offsets for array/aggregate type arguments. 2189 // 2190 // TODO(browneee): Consider a builtin to improve maintainabliity. 2191 // With a builtin, we would provide the argument labels via builtin, 2192 // and the builtin would reuse parts of the instrumentation code to ensure 2193 // that this code and the instrumentation can never be out of sync. 2194 // Note: Currently DFSan instrumentation does not run on this code, so 2195 // the builtin may need to be handled outside DFSan instrumentation. 2196 dfsan_set_arg_tls(0, fd_label); 2197 dfsan_set_arg_tls(1, buf_label); 2198 dfsan_set_arg_tls(2, count_label); 2199 if (origins) { 2200 dfsan_set_arg_origin_tls(0, fd_origin); 2201 dfsan_set_arg_origin_tls(1, buf_origin); 2202 dfsan_set_arg_origin_tls(2, count_origin); 2203 } 2204 } 2205 2206 SANITIZER_INTERFACE_ATTRIBUTE int 2207 __dfsw_write(int fd, const void *buf, size_t count, 2208 dfsan_label fd_label, dfsan_label buf_label, 2209 dfsan_label count_label, dfsan_label *ret_label) { 2210 if (write_callback_info.write_callback) { 2211 setup_tls_args_for_write_callback(fd_label, buf_label, count_label, false, 2212 0, 0, 0); 2213 write_callback_info.write_callback(fd, buf, count); 2214 } 2215 2216 *ret_label = 0; 2217 return write(fd, buf, count); 2218 } 2219 2220 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write( 2221 int fd, const void *buf, size_t count, dfsan_label fd_label, 2222 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, 2223 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, 2224 dfsan_origin *ret_origin) { 2225 if (write_callback_info.write_callback) { 2226 setup_tls_args_for_write_callback(fd_label, buf_label, count_label, true, 2227 fd_origin, buf_origin, count_origin); 2228 write_callback_info.write_callback(fd, buf, count); 2229 } 2230 2231 *ret_label = 0; 2232 return write(fd, buf, count); 2233 } 2234 } // namespace __dfsan 2235 2236 // Type used to extract a dfsan_label with va_arg() 2237 typedef int dfsan_label_va; 2238 2239 // Formats a chunk either a constant string or a single format directive (e.g., 2240 // '%.3f'). 2241 struct Formatter { 2242 Formatter(char *str_, const char *fmt_, size_t size_) 2243 : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_), 2244 width(-1) {} 2245 2246 int format() { 2247 char *tmp_fmt = build_format_string(); 2248 int retval = 2249 snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt, 2250 0 /* used only to avoid warnings */); 2251 free(tmp_fmt); 2252 return retval; 2253 } 2254 2255 template <typename T> int format(T arg) { 2256 char *tmp_fmt = build_format_string(); 2257 int retval; 2258 if (width >= 0) { 2259 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 2260 tmp_fmt, width, arg); 2261 } else { 2262 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 2263 tmp_fmt, arg); 2264 } 2265 free(tmp_fmt); 2266 return retval; 2267 } 2268 2269 char *build_format_string() { 2270 size_t fmt_size = fmt_cur - fmt_start + 1; 2271 char *new_fmt = (char *)malloc(fmt_size + 1); 2272 assert(new_fmt); 2273 internal_memcpy(new_fmt, fmt_start, fmt_size); 2274 new_fmt[fmt_size] = '\0'; 2275 return new_fmt; 2276 } 2277 2278 char *str_cur() { return str + str_off; } 2279 2280 size_t num_written_bytes(int retval) { 2281 if (retval < 0) { 2282 return 0; 2283 } 2284 2285 size_t num_avail = str_off < size ? size - str_off : 0; 2286 if (num_avail == 0) { 2287 return 0; 2288 } 2289 2290 size_t num_written = retval; 2291 // A return value of {v,}snprintf of size or more means that the output was 2292 // truncated. 2293 if (num_written >= num_avail) { 2294 num_written -= num_avail; 2295 } 2296 2297 return num_written; 2298 } 2299 2300 char *str; 2301 size_t str_off; 2302 size_t size; 2303 const char *fmt_start; 2304 const char *fmt_cur; 2305 int width; 2306 }; 2307 2308 // Formats the input and propagates the input labels to the output. The output 2309 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and 2310 // 'ap' are the format string and the list of arguments for formatting. Returns 2311 // the return value vsnprintf would return. 2312 // 2313 // The function tokenizes the format string in chunks representing either a 2314 // constant string or a single format directive (e.g., '%.3f') and formats each 2315 // chunk independently into the output string. This approach allows to figure 2316 // out which bytes of the output string depends on which argument and thus to 2317 // propagate labels more precisely. 2318 // 2319 // WARNING: This implementation does not support conversion specifiers with 2320 // positional arguments. 2321 static int format_buffer(char *str, size_t size, const char *fmt, 2322 dfsan_label *va_labels, dfsan_label *ret_label, 2323 dfsan_origin *va_origins, dfsan_origin *ret_origin, 2324 va_list ap) { 2325 Formatter formatter(str, fmt, size); 2326 2327 while (*formatter.fmt_cur) { 2328 formatter.fmt_start = formatter.fmt_cur; 2329 formatter.width = -1; 2330 int retval = 0; 2331 2332 if (*formatter.fmt_cur != '%') { 2333 // Ordinary character. Consume all the characters until a '%' or the end 2334 // of the string. 2335 for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%'; 2336 ++formatter.fmt_cur) {} 2337 retval = formatter.format(); 2338 dfsan_set_label(0, formatter.str_cur(), 2339 formatter.num_written_bytes(retval)); 2340 } else { 2341 // Conversion directive. Consume all the characters until a conversion 2342 // specifier or the end of the string. 2343 bool end_fmt = false; 2344 for (; *formatter.fmt_cur && !end_fmt; ) { 2345 switch (*++formatter.fmt_cur) { 2346 case 'd': 2347 case 'i': 2348 case 'o': 2349 case 'u': 2350 case 'x': 2351 case 'X': 2352 switch (*(formatter.fmt_cur - 1)) { 2353 case 'h': 2354 // Also covers the 'hh' case (since the size of the arg is still 2355 // an int). 2356 retval = formatter.format(va_arg(ap, int)); 2357 break; 2358 case 'l': 2359 if (formatter.fmt_cur - formatter.fmt_start >= 2 && 2360 *(formatter.fmt_cur - 2) == 'l') { 2361 retval = formatter.format(va_arg(ap, long long int)); 2362 } else { 2363 retval = formatter.format(va_arg(ap, long int)); 2364 } 2365 break; 2366 case 'q': 2367 retval = formatter.format(va_arg(ap, long long int)); 2368 break; 2369 case 'j': 2370 retval = formatter.format(va_arg(ap, intmax_t)); 2371 break; 2372 case 'z': 2373 case 't': 2374 retval = formatter.format(va_arg(ap, size_t)); 2375 break; 2376 default: 2377 retval = formatter.format(va_arg(ap, int)); 2378 } 2379 if (va_origins == nullptr) 2380 dfsan_set_label(*va_labels++, formatter.str_cur(), 2381 formatter.num_written_bytes(retval)); 2382 else 2383 dfsan_set_label_origin(*va_labels++, *va_origins++, 2384 formatter.str_cur(), 2385 formatter.num_written_bytes(retval)); 2386 end_fmt = true; 2387 break; 2388 2389 case 'a': 2390 case 'A': 2391 case 'e': 2392 case 'E': 2393 case 'f': 2394 case 'F': 2395 case 'g': 2396 case 'G': 2397 if (*(formatter.fmt_cur - 1) == 'L') { 2398 retval = formatter.format(va_arg(ap, long double)); 2399 } else { 2400 retval = formatter.format(va_arg(ap, double)); 2401 } 2402 if (va_origins == nullptr) 2403 dfsan_set_label(*va_labels++, formatter.str_cur(), 2404 formatter.num_written_bytes(retval)); 2405 else 2406 dfsan_set_label_origin(*va_labels++, *va_origins++, 2407 formatter.str_cur(), 2408 formatter.num_written_bytes(retval)); 2409 end_fmt = true; 2410 break; 2411 2412 case 'c': 2413 retval = formatter.format(va_arg(ap, int)); 2414 if (va_origins == nullptr) 2415 dfsan_set_label(*va_labels++, formatter.str_cur(), 2416 formatter.num_written_bytes(retval)); 2417 else 2418 dfsan_set_label_origin(*va_labels++, *va_origins++, 2419 formatter.str_cur(), 2420 formatter.num_written_bytes(retval)); 2421 end_fmt = true; 2422 break; 2423 2424 case 's': { 2425 char *arg = va_arg(ap, char *); 2426 retval = formatter.format(arg); 2427 if (va_origins) { 2428 va_origins++; 2429 dfsan_mem_origin_transfer(formatter.str_cur(), arg, 2430 formatter.num_written_bytes(retval)); 2431 } 2432 va_labels++; 2433 dfsan_mem_shadow_transfer(formatter.str_cur(), arg, 2434 formatter.num_written_bytes(retval)); 2435 end_fmt = true; 2436 break; 2437 } 2438 2439 case 'p': 2440 retval = formatter.format(va_arg(ap, void *)); 2441 if (va_origins == nullptr) 2442 dfsan_set_label(*va_labels++, formatter.str_cur(), 2443 formatter.num_written_bytes(retval)); 2444 else 2445 dfsan_set_label_origin(*va_labels++, *va_origins++, 2446 formatter.str_cur(), 2447 formatter.num_written_bytes(retval)); 2448 end_fmt = true; 2449 break; 2450 2451 case 'n': { 2452 int *ptr = va_arg(ap, int *); 2453 *ptr = (int)formatter.str_off; 2454 va_labels++; 2455 if (va_origins) 2456 va_origins++; 2457 dfsan_set_label(0, ptr, sizeof(ptr)); 2458 end_fmt = true; 2459 break; 2460 } 2461 2462 case '%': 2463 retval = formatter.format(); 2464 dfsan_set_label(0, formatter.str_cur(), 2465 formatter.num_written_bytes(retval)); 2466 end_fmt = true; 2467 break; 2468 2469 case '*': 2470 formatter.width = va_arg(ap, int); 2471 va_labels++; 2472 if (va_origins) 2473 va_origins++; 2474 break; 2475 2476 default: 2477 break; 2478 } 2479 } 2480 } 2481 2482 if (retval < 0) { 2483 return retval; 2484 } 2485 2486 formatter.fmt_cur++; 2487 formatter.str_off += retval; 2488 } 2489 2490 *ret_label = 0; 2491 if (ret_origin) 2492 *ret_origin = 0; 2493 2494 // Number of bytes written in total. 2495 return formatter.str_off; 2496 } 2497 2498 extern "C" { 2499 SANITIZER_INTERFACE_ATTRIBUTE 2500 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label, 2501 dfsan_label format_label, dfsan_label *va_labels, 2502 dfsan_label *ret_label, ...) { 2503 va_list ap; 2504 va_start(ap, ret_label); 2505 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr, 2506 nullptr, ap); 2507 va_end(ap); 2508 return ret; 2509 } 2510 2511 SANITIZER_INTERFACE_ATTRIBUTE 2512 int __dfso_sprintf(char *str, const char *format, dfsan_label str_label, 2513 dfsan_label format_label, dfsan_label *va_labels, 2514 dfsan_label *ret_label, dfsan_origin str_origin, 2515 dfsan_origin format_origin, dfsan_origin *va_origins, 2516 dfsan_origin *ret_origin, ...) { 2517 va_list ap; 2518 va_start(ap, ret_origin); 2519 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins, 2520 ret_origin, ap); 2521 va_end(ap); 2522 return ret; 2523 } 2524 2525 SANITIZER_INTERFACE_ATTRIBUTE 2526 int __dfsw_snprintf(char *str, size_t size, const char *format, 2527 dfsan_label str_label, dfsan_label size_label, 2528 dfsan_label format_label, dfsan_label *va_labels, 2529 dfsan_label *ret_label, ...) { 2530 va_list ap; 2531 va_start(ap, ret_label); 2532 int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr, 2533 nullptr, ap); 2534 va_end(ap); 2535 return ret; 2536 } 2537 2538 SANITIZER_INTERFACE_ATTRIBUTE 2539 int __dfso_snprintf(char *str, size_t size, const char *format, 2540 dfsan_label str_label, dfsan_label size_label, 2541 dfsan_label format_label, dfsan_label *va_labels, 2542 dfsan_label *ret_label, dfsan_origin str_origin, 2543 dfsan_origin size_origin, dfsan_origin format_origin, 2544 dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) { 2545 va_list ap; 2546 va_start(ap, ret_origin); 2547 int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins, 2548 ret_origin, ap); 2549 va_end(ap); 2550 return ret; 2551 } 2552 2553 static void BeforeFork() { 2554 StackDepotLockAll(); 2555 GetChainedOriginDepot()->LockAll(); 2556 } 2557 2558 static void AfterFork() { 2559 GetChainedOriginDepot()->UnlockAll(); 2560 StackDepotUnlockAll(); 2561 } 2562 2563 SANITIZER_INTERFACE_ATTRIBUTE 2564 pid_t __dfsw_fork(dfsan_label *ret_label) { 2565 pid_t pid = fork(); 2566 *ret_label = 0; 2567 return pid; 2568 } 2569 2570 SANITIZER_INTERFACE_ATTRIBUTE 2571 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) { 2572 BeforeFork(); 2573 pid_t pid = __dfsw_fork(ret_label); 2574 AfterFork(); 2575 return pid; 2576 } 2577 2578 // Default empty implementations (weak). Users should redefine them. 2579 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {} 2580 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *, 2581 u32 *) {} 2582 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg, 2583 const uptr *end) {} 2584 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {} 2585 2586 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {} 2587 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {} 2588 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {} 2589 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {} 2590 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {} 2591 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1, 2592 void) {} 2593 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2, 2594 void) {} 2595 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4, 2596 void) {} 2597 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8, 2598 void) {} 2599 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {} 2600 } // extern "C" 2601