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