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