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_thread.h" 42 #include "sanitizer_common/sanitizer_common.h" 43 #include "sanitizer_common/sanitizer_internal_defs.h" 44 #include "sanitizer_common/sanitizer_linux.h" 45 #include "sanitizer_common/sanitizer_stackdepot.h" 46 47 using namespace __dfsan; 48 49 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \ 50 do { \ 51 if (f) \ 52 f(__VA_ARGS__); \ 53 } while (false) 54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \ 55 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__); 56 57 // Async-safe, non-reentrant spin lock. 58 class SignalSpinLocker { 59 public: 60 SignalSpinLocker() { 61 sigset_t all_set; 62 sigfillset(&all_set); 63 pthread_sigmask(SIG_SETMASK, &all_set, &saved_thread_mask_); 64 sigactions_mu.Lock(); 65 } 66 ~SignalSpinLocker() { 67 sigactions_mu.Unlock(); 68 pthread_sigmask(SIG_SETMASK, &saved_thread_mask_, nullptr); 69 } 70 71 private: 72 static StaticSpinMutex sigactions_mu; 73 sigset_t saved_thread_mask_; 74 75 SignalSpinLocker(const SignalSpinLocker &) = delete; 76 SignalSpinLocker &operator=(const SignalSpinLocker &) = delete; 77 }; 78 79 StaticSpinMutex SignalSpinLocker::sigactions_mu; 80 81 extern "C" { 82 SANITIZER_INTERFACE_ATTRIBUTE int 83 __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label, 84 dfsan_label buf_label, dfsan_label *ret_label) { 85 int ret = stat(path, buf); 86 if (ret == 0) 87 dfsan_set_label(0, buf, sizeof(struct stat)); 88 *ret_label = 0; 89 return ret; 90 } 91 92 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat( 93 const char *path, struct stat *buf, dfsan_label path_label, 94 dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin, 95 dfsan_origin buf_origin, dfsan_origin *ret_origin) { 96 int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label); 97 return ret; 98 } 99 100 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf, 101 dfsan_label fd_label, 102 dfsan_label buf_label, 103 dfsan_label *ret_label) { 104 int ret = fstat(fd, buf); 105 if (ret == 0) 106 dfsan_set_label(0, buf, sizeof(struct stat)); 107 *ret_label = 0; 108 return ret; 109 } 110 111 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat( 112 int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label, 113 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, 114 dfsan_origin *ret_origin) { 115 int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label); 116 return ret; 117 } 118 119 static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read, 120 dfsan_label s_label, dfsan_label c_label, 121 dfsan_label *ret_label) { 122 char *match_pos = nullptr; 123 for (size_t i = 0;; ++i) { 124 if (s[i] == c || s[i] == 0) { 125 // If s[i] is the \0 at the end of the string, and \0 is not the 126 // character we are searching for, then return null. 127 *bytes_read = i + 1; 128 match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast<char *>(s + i); 129 break; 130 } 131 } 132 if (flags().strict_data_dependencies) 133 *ret_label = s_label; 134 else 135 *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read), 136 dfsan_union(s_label, c_label)); 137 return match_pos; 138 } 139 140 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, 141 dfsan_label s_label, 142 dfsan_label c_label, 143 dfsan_label *ret_label) { 144 size_t bytes_read; 145 return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, 146 ret_label); 147 } 148 149 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr( 150 const char *s, int c, dfsan_label s_label, dfsan_label c_label, 151 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, 152 dfsan_origin *ret_origin) { 153 size_t bytes_read; 154 char *r = 155 dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label); 156 if (flags().strict_data_dependencies) { 157 *ret_origin = s_origin; 158 } else if (*ret_label) { 159 dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read); 160 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 161 } 162 return r; 163 } 164 165 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s, 166 const char *accept, 167 dfsan_label s_label, 168 dfsan_label accept_label, 169 dfsan_label *ret_label) { 170 const char *ret = strpbrk(s, accept); 171 if (flags().strict_data_dependencies) { 172 *ret_label = ret ? s_label : 0; 173 } else { 174 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1; 175 *ret_label = 176 dfsan_union(dfsan_read_label(s, s_bytes_read), 177 dfsan_union(dfsan_read_label(accept, strlen(accept) + 1), 178 dfsan_union(s_label, accept_label))); 179 } 180 return const_cast<char *>(ret); 181 } 182 183 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk( 184 const char *s, const char *accept, dfsan_label s_label, 185 dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin, 186 dfsan_origin accept_origin, dfsan_origin *ret_origin) { 187 const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label); 188 if (flags().strict_data_dependencies) { 189 if (ret) 190 *ret_origin = s_origin; 191 } else { 192 if (*ret_label) { 193 size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1; 194 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read); 195 if (o) { 196 *ret_origin = o; 197 } else { 198 o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1); 199 *ret_origin = o ? o : (s_label ? s_origin : accept_origin); 200 } 201 } 202 } 203 return const_cast<char *>(ret); 204 } 205 206 static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n, 207 size_t *bytes_read) { 208 const char *cs1 = (const char *) s1, *cs2 = (const char *) s2; 209 for (size_t i = 0; i != n; ++i) { 210 if (cs1[i] != cs2[i]) { 211 *bytes_read = i + 1; 212 return cs1[i] - cs2[i]; 213 } 214 } 215 *bytes_read = n; 216 return 0; 217 } 218 219 static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2, 220 size_t pos) { 221 if (flags().strict_data_dependencies) 222 return 0; 223 return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos)); 224 } 225 226 static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos, 227 dfsan_label *ret_label, 228 dfsan_origin *ret_origin) { 229 *ret_label = dfsan_get_memcmp_label(s1, s2, pos); 230 if (*ret_label == 0) 231 return; 232 dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos); 233 *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos); 234 } 235 236 static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n, 237 dfsan_label *ret_label) { 238 size_t bytes_read; 239 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); 240 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 241 return r; 242 } 243 244 static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n, 245 dfsan_label *ret_label, 246 dfsan_origin *ret_origin) { 247 size_t bytes_read; 248 int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read); 249 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 250 return r; 251 } 252 253 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc, 254 const void *s1, const void *s2, size_t n, 255 dfsan_label s1_label, dfsan_label s2_label, 256 dfsan_label n_label) 257 258 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc, 259 const void *s1, const void *s2, size_t n, 260 dfsan_label s1_label, dfsan_label s2_label, 261 dfsan_label n_label, dfsan_origin s1_origin, 262 dfsan_origin s2_origin, dfsan_origin n_origin) 263 264 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, 265 size_t n, dfsan_label s1_label, 266 dfsan_label s2_label, 267 dfsan_label n_label, 268 dfsan_label *ret_label) { 269 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n, 270 s1_label, s2_label, n_label); 271 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); 272 } 273 274 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp( 275 const void *s1, const void *s2, size_t n, dfsan_label s1_label, 276 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 277 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 278 dfsan_origin *ret_origin) { 279 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1, 280 s2, n, s1_label, s2_label, n_label, s1_origin, 281 s2_origin, n_origin); 282 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); 283 } 284 285 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2, 286 size_t n, dfsan_label s1_label, 287 dfsan_label s2_label, 288 dfsan_label n_label, 289 dfsan_label *ret_label) { 290 return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label); 291 } 292 293 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp( 294 const void *s1, const void *s2, size_t n, dfsan_label s1_label, 295 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 296 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 297 dfsan_origin *ret_origin) { 298 return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin); 299 } 300 301 // When n == 0, compare strings without byte limit. 302 // When n > 0, compare the first (at most) n bytes of s1 and s2. 303 static int dfsan_strncmp(const char *s1, const char *s2, size_t n, 304 size_t *bytes_read) { 305 for (size_t i = 0;; ++i) { 306 if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) { 307 *bytes_read = i + 1; 308 return s1[i] - s2[i]; 309 } 310 } 311 } 312 313 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc, 314 const char *s1, const char *s2, 315 dfsan_label s1_label, dfsan_label s2_label) 316 317 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc, 318 const char *s1, const char *s2, 319 dfsan_label s1_label, dfsan_label s2_label, 320 dfsan_origin s1_origin, dfsan_origin s2_origin) 321 322 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2, 323 dfsan_label s1_label, 324 dfsan_label s2_label, 325 dfsan_label *ret_label) { 326 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2, 327 s1_label, s2_label); 328 size_t bytes_read; 329 int r = dfsan_strncmp(s1, s2, 0, &bytes_read); 330 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 331 return r; 332 } 333 334 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp( 335 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, 336 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, 337 dfsan_origin *ret_origin) { 338 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1, 339 s2, s1_label, s2_label, s1_origin, s2_origin); 340 size_t bytes_read; 341 int r = dfsan_strncmp(s1, s2, 0, &bytes_read); 342 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 343 return r; 344 } 345 346 // When n == 0, compare strings without byte limit. 347 // When n > 0, compare the first (at most) n bytes of s1 and s2. 348 static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n, 349 size_t *bytes_read) { 350 for (size_t i = 0;; ++i) { 351 char s1_lower = tolower(s1[i]); 352 char s2_lower = tolower(s2[i]); 353 354 if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || 355 (n > 0 && i == n - 1)) { 356 *bytes_read = i + 1; 357 return s1_lower - s2_lower; 358 } 359 } 360 } 361 362 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1, 363 const char *s2, 364 dfsan_label s1_label, 365 dfsan_label s2_label, 366 dfsan_label *ret_label) { 367 size_t bytes_read; 368 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); 369 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 370 return r; 371 } 372 373 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp( 374 const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, 375 dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin, 376 dfsan_origin *ret_origin) { 377 size_t bytes_read; 378 int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read); 379 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 380 return r; 381 } 382 383 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc, 384 const char *s1, const char *s2, size_t n, 385 dfsan_label s1_label, dfsan_label s2_label, 386 dfsan_label n_label) 387 388 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc, 389 const char *s1, const char *s2, size_t n, 390 dfsan_label s1_label, dfsan_label s2_label, 391 dfsan_label n_label, dfsan_origin s1_origin, 392 dfsan_origin s2_origin, dfsan_origin n_origin) 393 394 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, 395 size_t n, dfsan_label s1_label, 396 dfsan_label s2_label, 397 dfsan_label n_label, 398 dfsan_label *ret_label) { 399 if (n == 0) { 400 *ret_label = 0; 401 return 0; 402 } 403 404 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2, 405 n, s1_label, s2_label, n_label); 406 407 size_t bytes_read; 408 int r = dfsan_strncmp(s1, s2, n, &bytes_read); 409 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 410 return r; 411 } 412 413 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp( 414 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 415 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 416 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 417 dfsan_origin *ret_origin) { 418 if (n == 0) { 419 *ret_label = 0; 420 return 0; 421 } 422 423 CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(), 424 s1, s2, n, s1_label, s2_label, n_label, s1_origin, 425 s2_origin, n_origin); 426 427 size_t bytes_read; 428 int r = dfsan_strncmp(s1, s2, n, &bytes_read); 429 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 430 return r; 431 } 432 433 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp( 434 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 435 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) { 436 if (n == 0) { 437 *ret_label = 0; 438 return 0; 439 } 440 441 size_t bytes_read; 442 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); 443 *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read); 444 return r; 445 } 446 447 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp( 448 const char *s1, const char *s2, size_t n, dfsan_label s1_label, 449 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 450 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 451 dfsan_origin *ret_origin) { 452 if (n == 0) { 453 *ret_label = 0; 454 return 0; 455 } 456 457 size_t bytes_read; 458 int r = dfsan_strncasecmp(s1, s2, n, &bytes_read); 459 dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin); 460 return r; 461 } 462 463 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size, 464 dfsan_label nmemb_label, 465 dfsan_label size_label, 466 dfsan_label *ret_label) { 467 void *p = calloc(nmemb, size); 468 dfsan_set_label(0, p, nmemb * size); 469 *ret_label = 0; 470 return p; 471 } 472 473 SANITIZER_INTERFACE_ATTRIBUTE size_t 474 __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 475 size_t ret = strlen(s); 476 if (flags().strict_data_dependencies) { 477 *ret_label = 0; 478 } else { 479 *ret_label = dfsan_read_label(s, ret + 1); 480 } 481 return ret; 482 } 483 484 SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s, 485 dfsan_label s_label, 486 dfsan_label *ret_label, 487 dfsan_origin s_origin, 488 dfsan_origin *ret_origin) { 489 size_t ret = __dfsw_strlen(s, s_label, ret_label); 490 if (!flags().strict_data_dependencies) 491 *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1); 492 return ret; 493 } 494 495 static void *dfsan_memmove(void *dest, const void *src, size_t n) { 496 dfsan_label *sdest = shadow_for(dest); 497 const dfsan_label *ssrc = shadow_for(src); 498 internal_memmove((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); 499 return internal_memmove(dest, src, n); 500 } 501 502 static void *dfsan_memcpy(void *dest, const void *src, size_t n) { 503 dfsan_label *sdest = shadow_for(dest); 504 const dfsan_label *ssrc = shadow_for(src); 505 internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); 506 return internal_memcpy(dest, src, n); 507 } 508 509 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) { 510 internal_memset(s, c, n); 511 dfsan_set_label(c_label, s, n); 512 } 513 514 SANITIZER_INTERFACE_ATTRIBUTE 515 void *__dfsw_memcpy(void *dest, const void *src, size_t n, 516 dfsan_label dest_label, dfsan_label src_label, 517 dfsan_label n_label, dfsan_label *ret_label) { 518 *ret_label = dest_label; 519 return dfsan_memcpy(dest, src, n); 520 } 521 522 SANITIZER_INTERFACE_ATTRIBUTE 523 void *__dfsw_memmove(void *dest, const void *src, size_t n, 524 dfsan_label dest_label, dfsan_label src_label, 525 dfsan_label n_label, dfsan_label *ret_label) { 526 *ret_label = dest_label; 527 return dfsan_memmove(dest, src, n); 528 } 529 530 SANITIZER_INTERFACE_ATTRIBUTE 531 void *__dfsw_memset(void *s, int c, size_t n, 532 dfsan_label s_label, dfsan_label c_label, 533 dfsan_label n_label, dfsan_label *ret_label) { 534 dfsan_memset(s, c, c_label, n); 535 *ret_label = s_label; 536 return s; 537 } 538 539 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, 540 dfsan_label dest_label, 541 dfsan_label src_label, 542 dfsan_label *ret_label) { 543 size_t dest_len = strlen(dest); 544 char *ret = strcat(dest, src); // NOLINT 545 dfsan_label *sdest = shadow_for(dest + dest_len); 546 const dfsan_label *ssrc = shadow_for(src); 547 internal_memcpy((void *)sdest, (const void *)ssrc, 548 strlen(src) * sizeof(dfsan_label)); 549 *ret_label = dest_label; 550 return ret; 551 } 552 553 SANITIZER_INTERFACE_ATTRIBUTE char * 554 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 555 size_t len = strlen(s); 556 void *p = malloc(len+1); 557 dfsan_memcpy(p, s, len+1); 558 *ret_label = 0; 559 return static_cast<char *>(p); 560 } 561 562 SANITIZER_INTERFACE_ATTRIBUTE char * 563 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, 564 dfsan_label s2_label, dfsan_label n_label, 565 dfsan_label *ret_label) { 566 size_t len = strlen(s2); 567 if (len < n) { 568 dfsan_memcpy(s1, s2, len+1); 569 dfsan_memset(s1+len+1, 0, 0, n-len-1); 570 } else { 571 dfsan_memcpy(s1, s2, n); 572 } 573 574 *ret_label = s1_label; 575 return s1; 576 } 577 578 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 579 __dfsw_pread(int fd, void *buf, size_t count, off_t offset, 580 dfsan_label fd_label, dfsan_label buf_label, 581 dfsan_label count_label, dfsan_label offset_label, 582 dfsan_label *ret_label) { 583 ssize_t ret = pread(fd, buf, count, offset); 584 if (ret > 0) 585 dfsan_set_label(0, buf, ret); 586 *ret_label = 0; 587 return ret; 588 } 589 590 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 591 __dfsw_read(int fd, void *buf, size_t count, 592 dfsan_label fd_label, dfsan_label buf_label, 593 dfsan_label count_label, 594 dfsan_label *ret_label) { 595 ssize_t ret = read(fd, buf, count); 596 if (ret > 0) 597 dfsan_set_label(0, buf, ret); 598 *ret_label = 0; 599 return ret; 600 } 601 602 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, 603 struct timespec *tp, 604 dfsan_label clk_id_label, 605 dfsan_label tp_label, 606 dfsan_label *ret_label) { 607 int ret = clock_gettime(clk_id, tp); 608 if (ret == 0) 609 dfsan_set_label(0, tp, sizeof(struct timespec)); 610 *ret_label = 0; 611 return ret; 612 } 613 614 static void unpoison(const void *ptr, uptr size) { 615 dfsan_set_label(0, const_cast<void *>(ptr), size); 616 } 617 618 // dlopen() ultimately calls mmap() down inside the loader, which generally 619 // doesn't participate in dynamic symbol resolution. Therefore we won't 620 // intercept its calls to mmap, and we have to hook it here. 621 SANITIZER_INTERFACE_ATTRIBUTE void * 622 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label, 623 dfsan_label flag_label, dfsan_label *ret_label) { 624 void *handle = dlopen(filename, flag); 625 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle); 626 if (map) 627 ForEachMappedRegion(map, unpoison); 628 *ret_label = 0; 629 return handle; 630 } 631 632 static void *DFsanThreadStartFunc(void *arg) { 633 DFsanThread *t = (DFsanThread *)arg; 634 SetCurrentThread(t); 635 return t->ThreadStart(); 636 } 637 638 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, 639 void *start_routine_trampoline, 640 void *start_routine, void *arg, 641 dfsan_label *ret_label, 642 bool track_origins = false) { 643 pthread_attr_t myattr; 644 if (!attr) { 645 pthread_attr_init(&myattr); 646 attr = &myattr; 647 } 648 649 // Ensure that the thread stack is large enough to hold all TLS data. 650 AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr))); 651 652 DFsanThread *t = 653 DFsanThread::Create(start_routine_trampoline, 654 (thread_callback_t)start_routine, arg, track_origins); 655 int res = pthread_create(thread, attr, DFsanThreadStartFunc, t); 656 657 if (attr == &myattr) 658 pthread_attr_destroy(&myattr); 659 *ret_label = 0; 660 return res; 661 } 662 663 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( 664 pthread_t *thread, const pthread_attr_t *attr, 665 void *(*start_routine_trampoline)(void *, void *, dfsan_label, 666 dfsan_label *), 667 void *start_routine, void *arg, dfsan_label thread_label, 668 dfsan_label attr_label, dfsan_label start_routine_label, 669 dfsan_label arg_label, dfsan_label *ret_label) { 670 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, 671 start_routine, arg, ret_label); 672 } 673 674 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create( 675 pthread_t *thread, const pthread_attr_t *attr, 676 void *(*start_routine_trampoline)(void *, void *, dfsan_label, 677 dfsan_label *, dfsan_origin, 678 dfsan_origin *), 679 void *start_routine, void *arg, dfsan_label thread_label, 680 dfsan_label attr_label, dfsan_label start_routine_label, 681 dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin, 682 dfsan_origin attr_origin, dfsan_origin start_routine_origin, 683 dfsan_origin arg_origin, dfsan_origin *ret_origin) { 684 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, 685 start_routine, arg, ret_label, true); 686 } 687 688 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, 689 void **retval, 690 dfsan_label thread_label, 691 dfsan_label retval_label, 692 dfsan_label *ret_label) { 693 int ret = pthread_join(thread, retval); 694 if (ret == 0 && retval) 695 dfsan_set_label(0, retval, sizeof(*retval)); 696 *ret_label = 0; 697 return ret; 698 } 699 700 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join( 701 pthread_t thread, void **retval, dfsan_label thread_label, 702 dfsan_label retval_label, dfsan_label *ret_label, 703 dfsan_origin thread_origin, dfsan_origin retval_origin, 704 dfsan_origin *ret_origin) { 705 return __dfsw_pthread_join(thread, retval, thread_label, retval_label, 706 ret_label); 707 } 708 709 struct dl_iterate_phdr_info { 710 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 711 size_t size, void *data, dfsan_label info_label, 712 dfsan_label size_label, dfsan_label data_label, 713 dfsan_label *ret_label); 714 void *callback; 715 void *data; 716 }; 717 718 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { 719 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data; 720 dfsan_set_label(0, *info); 721 dfsan_set_label(0, const_cast<char *>(info->dlpi_name), 722 strlen(info->dlpi_name) + 1); 723 dfsan_set_label( 724 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), 725 sizeof(*info->dlpi_phdr) * info->dlpi_phnum); 726 dfsan_label ret_label; 727 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, 728 0, &ret_label); 729 } 730 731 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( 732 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 733 size_t size, void *data, dfsan_label info_label, 734 dfsan_label size_label, dfsan_label data_label, 735 dfsan_label *ret_label), 736 void *callback, void *data, dfsan_label callback_label, 737 dfsan_label data_label, dfsan_label *ret_label) { 738 dl_iterate_phdr_info dipi = { callback_trampoline, callback, data }; 739 *ret_label = 0; 740 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); 741 } 742 743 // This function is only available for glibc 2.27 or newer. Mark it weak so 744 // linking succeeds with older glibcs. 745 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep, 746 size_t *alignp); 747 748 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info( 749 size_t *sizep, size_t *alignp, dfsan_label sizep_label, 750 dfsan_label alignp_label) { 751 assert(_dl_get_tls_static_info); 752 _dl_get_tls_static_info(sizep, alignp); 753 dfsan_set_label(0, sizep, sizeof(*sizep)); 754 dfsan_set_label(0, alignp, sizeof(*alignp)); 755 } 756 757 SANITIZER_INTERFACE_ATTRIBUTE 758 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 759 dfsan_label buf_label, dfsan_label *ret_label) { 760 char *ret = ctime_r(timep, buf); 761 if (ret) { 762 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf, 763 strlen(buf) + 1); 764 *ret_label = buf_label; 765 } else { 766 *ret_label = 0; 767 } 768 return ret; 769 } 770 771 SANITIZER_INTERFACE_ATTRIBUTE 772 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 773 dfsan_label size_label, dfsan_label stream_label, 774 dfsan_label *ret_label) { 775 char *ret = fgets(s, size, stream); 776 if (ret) { 777 dfsan_set_label(0, ret, strlen(ret) + 1); 778 *ret_label = s_label; 779 } else { 780 *ret_label = 0; 781 } 782 return ret; 783 } 784 785 SANITIZER_INTERFACE_ATTRIBUTE 786 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, 787 dfsan_label size_label, dfsan_label *ret_label) { 788 char *ret = getcwd(buf, size); 789 if (ret) { 790 dfsan_set_label(0, ret, strlen(ret) + 1); 791 *ret_label = buf_label; 792 } else { 793 *ret_label = 0; 794 } 795 return ret; 796 } 797 798 SANITIZER_INTERFACE_ATTRIBUTE 799 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { 800 char *ret = get_current_dir_name(); 801 if (ret) { 802 dfsan_set_label(0, ret, strlen(ret) + 1); 803 } 804 *ret_label = 0; 805 return ret; 806 } 807 808 SANITIZER_INTERFACE_ATTRIBUTE 809 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, 810 dfsan_label len_label, dfsan_label *ret_label) { 811 int ret = gethostname(name, len); 812 if (ret == 0) { 813 dfsan_set_label(0, name, strlen(name) + 1); 814 } 815 *ret_label = 0; 816 return ret; 817 } 818 819 SANITIZER_INTERFACE_ATTRIBUTE 820 int __dfsw_getrlimit(int resource, struct rlimit *rlim, 821 dfsan_label resource_label, dfsan_label rlim_label, 822 dfsan_label *ret_label) { 823 int ret = getrlimit(resource, rlim); 824 if (ret == 0) { 825 dfsan_set_label(0, rlim, sizeof(struct rlimit)); 826 } 827 *ret_label = 0; 828 return ret; 829 } 830 831 SANITIZER_INTERFACE_ATTRIBUTE 832 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, 833 dfsan_label usage_label, dfsan_label *ret_label) { 834 int ret = getrusage(who, usage); 835 if (ret == 0) { 836 dfsan_set_label(0, usage, sizeof(struct rusage)); 837 } 838 *ret_label = 0; 839 return ret; 840 } 841 842 SANITIZER_INTERFACE_ATTRIBUTE 843 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, 844 dfsan_label src_label, dfsan_label *ret_label) { 845 char *ret = strcpy(dest, src); // NOLINT 846 if (ret) { 847 internal_memcpy(shadow_for(dest), shadow_for(src), 848 sizeof(dfsan_label) * (strlen(src) + 1)); 849 } 850 *ret_label = dst_label; 851 return ret; 852 } 853 854 SANITIZER_INTERFACE_ATTRIBUTE 855 long int __dfsw_strtol(const char *nptr, char **endptr, int base, 856 dfsan_label nptr_label, dfsan_label endptr_label, 857 dfsan_label base_label, dfsan_label *ret_label) { 858 char *tmp_endptr; 859 long int ret = strtol(nptr, &tmp_endptr, base); 860 if (endptr) { 861 *endptr = tmp_endptr; 862 } 863 if (tmp_endptr > nptr) { 864 // If *tmp_endptr is '\0' include its label as well. 865 *ret_label = dfsan_union( 866 base_label, 867 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 868 } else { 869 *ret_label = 0; 870 } 871 return ret; 872 } 873 874 SANITIZER_INTERFACE_ATTRIBUTE 875 double __dfsw_strtod(const char *nptr, char **endptr, 876 dfsan_label nptr_label, dfsan_label endptr_label, 877 dfsan_label *ret_label) { 878 char *tmp_endptr; 879 double ret = strtod(nptr, &tmp_endptr); 880 if (endptr) { 881 *endptr = tmp_endptr; 882 } 883 if (tmp_endptr > nptr) { 884 // If *tmp_endptr is '\0' include its label as well. 885 *ret_label = dfsan_read_label( 886 nptr, 887 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 888 } else { 889 *ret_label = 0; 890 } 891 return ret; 892 } 893 894 SANITIZER_INTERFACE_ATTRIBUTE 895 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, 896 dfsan_label nptr_label, dfsan_label endptr_label, 897 dfsan_label base_label, dfsan_label *ret_label) { 898 char *tmp_endptr; 899 long long int ret = strtoll(nptr, &tmp_endptr, base); 900 if (endptr) { 901 *endptr = tmp_endptr; 902 } 903 if (tmp_endptr > nptr) { 904 // If *tmp_endptr is '\0' include its label as well. 905 *ret_label = dfsan_union( 906 base_label, 907 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 908 } else { 909 *ret_label = 0; 910 } 911 return ret; 912 } 913 914 SANITIZER_INTERFACE_ATTRIBUTE 915 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base, 916 dfsan_label nptr_label, dfsan_label endptr_label, 917 dfsan_label base_label, dfsan_label *ret_label) { 918 char *tmp_endptr; 919 unsigned long int ret = strtoul(nptr, &tmp_endptr, base); 920 if (endptr) { 921 *endptr = tmp_endptr; 922 } 923 if (tmp_endptr > nptr) { 924 // If *tmp_endptr is '\0' include its label as well. 925 *ret_label = dfsan_union( 926 base_label, 927 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 928 } else { 929 *ret_label = 0; 930 } 931 return ret; 932 } 933 934 SANITIZER_INTERFACE_ATTRIBUTE 935 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, 936 int base, dfsan_label nptr_label, 937 dfsan_label endptr_label, 938 dfsan_label base_label, 939 dfsan_label *ret_label) { 940 char *tmp_endptr; 941 long long unsigned int ret = strtoull(nptr, &tmp_endptr, base); 942 if (endptr) { 943 *endptr = tmp_endptr; 944 } 945 if (tmp_endptr > nptr) { 946 // If *tmp_endptr is '\0' include its label as well. 947 *ret_label = dfsan_union( 948 base_label, 949 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 950 } else { 951 *ret_label = 0; 952 } 953 return ret; 954 } 955 956 SANITIZER_INTERFACE_ATTRIBUTE 957 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { 958 time_t ret = time(t); 959 if (ret != (time_t) -1 && t) { 960 dfsan_set_label(0, t, sizeof(time_t)); 961 } 962 *ret_label = 0; 963 return ret; 964 } 965 966 SANITIZER_INTERFACE_ATTRIBUTE 967 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 968 dfsan_label src_label, dfsan_label dst_label, 969 dfsan_label *ret_label) { 970 int ret = inet_pton(af, src, dst); 971 if (ret == 1) { 972 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst, 973 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 974 } 975 *ret_label = 0; 976 return ret; 977 } 978 979 SANITIZER_INTERFACE_ATTRIBUTE 980 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, 981 dfsan_label timep_label, dfsan_label result_label, 982 dfsan_label *ret_label) { 983 struct tm *ret = localtime_r(timep, result); 984 if (ret) { 985 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result, 986 sizeof(struct tm)); 987 *ret_label = result_label; 988 } else { 989 *ret_label = 0; 990 } 991 return ret; 992 } 993 994 SANITIZER_INTERFACE_ATTRIBUTE 995 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, 996 char *buf, size_t buflen, struct passwd **result, 997 dfsan_label uid_label, dfsan_label pwd_label, 998 dfsan_label buf_label, dfsan_label buflen_label, 999 dfsan_label result_label, dfsan_label *ret_label) { 1000 // Store the data in pwd, the strings referenced from pwd in buf, and the 1001 // address of pwd in *result. On failure, NULL is stored in *result. 1002 int ret = getpwuid_r(uid, pwd, buf, buflen, result); 1003 if (ret == 0) { 1004 dfsan_set_label(0, pwd, sizeof(struct passwd)); 1005 dfsan_set_label(0, buf, strlen(buf) + 1); 1006 } 1007 *ret_label = 0; 1008 dfsan_set_label(0, result, sizeof(struct passwd*)); 1009 return ret; 1010 } 1011 1012 SANITIZER_INTERFACE_ATTRIBUTE 1013 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, 1014 int timeout, dfsan_label epfd_label, 1015 dfsan_label events_label, dfsan_label maxevents_label, 1016 dfsan_label timeout_label, dfsan_label *ret_label) { 1017 int ret = epoll_wait(epfd, events, maxevents, timeout); 1018 if (ret > 0) 1019 dfsan_set_label(0, events, ret * sizeof(*events)); 1020 *ret_label = 0; 1021 return ret; 1022 } 1023 1024 SANITIZER_INTERFACE_ATTRIBUTE 1025 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, 1026 dfsan_label dfs_label, dfsan_label nfds_label, 1027 dfsan_label timeout_label, dfsan_label *ret_label) { 1028 int ret = poll(fds, nfds, timeout); 1029 if (ret >= 0) { 1030 for (; nfds > 0; --nfds) { 1031 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents)); 1032 } 1033 } 1034 *ret_label = 0; 1035 return ret; 1036 } 1037 1038 SANITIZER_INTERFACE_ATTRIBUTE 1039 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, 1040 fd_set *exceptfds, struct timeval *timeout, 1041 dfsan_label nfds_label, dfsan_label readfds_label, 1042 dfsan_label writefds_label, dfsan_label exceptfds_label, 1043 dfsan_label timeout_label, dfsan_label *ret_label) { 1044 int ret = select(nfds, readfds, writefds, exceptfds, timeout); 1045 // Clear everything (also on error) since their content is either set or 1046 // undefined. 1047 if (readfds) { 1048 dfsan_set_label(0, readfds, sizeof(fd_set)); 1049 } 1050 if (writefds) { 1051 dfsan_set_label(0, writefds, sizeof(fd_set)); 1052 } 1053 if (exceptfds) { 1054 dfsan_set_label(0, exceptfds, sizeof(fd_set)); 1055 } 1056 dfsan_set_label(0, timeout, sizeof(struct timeval)); 1057 *ret_label = 0; 1058 return ret; 1059 } 1060 1061 SANITIZER_INTERFACE_ATTRIBUTE 1062 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 1063 dfsan_label pid_label, 1064 dfsan_label cpusetsize_label, 1065 dfsan_label mask_label, dfsan_label *ret_label) { 1066 int ret = sched_getaffinity(pid, cpusetsize, mask); 1067 if (ret == 0) { 1068 dfsan_set_label(0, mask, cpusetsize); 1069 } 1070 *ret_label = 0; 1071 return ret; 1072 } 1073 1074 SANITIZER_INTERFACE_ATTRIBUTE 1075 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, 1076 dfsan_label *ret_label) { 1077 int ret = sigemptyset(set); 1078 dfsan_set_label(0, set, sizeof(sigset_t)); 1079 return ret; 1080 } 1081 1082 SANITIZER_INTERFACE_ATTRIBUTE 1083 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label, 1084 dfsan_label *ret_label, dfsan_origin set_origin, 1085 dfsan_origin *ret_origin) { 1086 return __dfsw_sigemptyset(set, set_label, ret_label); 1087 } 1088 1089 class SignalHandlerScope { 1090 public: 1091 SignalHandlerScope() { 1092 if (DFsanThread *t = GetCurrentThread()) 1093 t->EnterSignalHandler(); 1094 } 1095 ~SignalHandlerScope() { 1096 if (DFsanThread *t = GetCurrentThread()) 1097 t->LeaveSignalHandler(); 1098 } 1099 }; 1100 1101 // Clear DFSan runtime TLS state at the end of a scope. 1102 // 1103 // Implementation must be async-signal-safe and use small data size, because 1104 // instances of this class may live on the signal handler stack. 1105 // 1106 // DFSan uses TLS to pass metadata of arguments and return values. When an 1107 // instrumented function accesses the TLS, if a signal callback happens, and the 1108 // callback calls other instrumented functions with updating the same TLS, the 1109 // TLS is in an inconsistent state after the callback ends. This may cause 1110 // either under-tainting or over-tainting. 1111 // 1112 // The current implementation simply resets TLS at restore. This prevents from 1113 // over-tainting. Although under-tainting may still happen, a taint flow can be 1114 // found eventually if we run a DFSan-instrumented program multiple times. The 1115 // alternative option is saving the entire TLS. However the TLS storage takes 1116 // 2k bytes, and signal calls could be nested. So it does not seem worth. 1117 class ScopedClearThreadLocalState { 1118 public: 1119 ScopedClearThreadLocalState() {} 1120 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); } 1121 }; 1122 1123 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls. 1124 const int kMaxSignals = 1024; 1125 static atomic_uintptr_t sigactions[kMaxSignals]; 1126 1127 static void SignalHandler(int signo) { 1128 SignalHandlerScope signal_handler_scope; 1129 ScopedClearThreadLocalState scoped_clear_tls; 1130 1131 // Clear shadows for all inputs provided by system. This is why DFSan 1132 // instrumentation generates a trampoline function to each function pointer, 1133 // and uses the trampoline to clear shadows. However sigaction does not use 1134 // a function pointer directly, so we have to do this manually. 1135 dfsan_clear_arg_tls(0, sizeof(dfsan_label)); 1136 1137 typedef void (*signal_cb)(int x); 1138 signal_cb cb = 1139 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1140 cb(signo); 1141 } 1142 1143 static void SignalAction(int signo, siginfo_t *si, void *uc) { 1144 SignalHandlerScope signal_handler_scope; 1145 ScopedClearThreadLocalState scoped_clear_tls; 1146 1147 // Clear shadows for all inputs provided by system. Similar to SignalHandler. 1148 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label)); 1149 dfsan_set_label(0, si, sizeof(*si)); 1150 dfsan_set_label(0, uc, sizeof(ucontext_t)); 1151 1152 typedef void (*sigaction_cb)(int, siginfo_t *, void *); 1153 sigaction_cb cb = 1154 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1155 cb(signo, si, uc); 1156 } 1157 1158 SANITIZER_INTERFACE_ATTRIBUTE 1159 int __dfsw_sigaction(int signum, const struct sigaction *act, 1160 struct sigaction *oldact, dfsan_label signum_label, 1161 dfsan_label act_label, dfsan_label oldact_label, 1162 dfsan_label *ret_label) { 1163 CHECK_LT(signum, kMaxSignals); 1164 SignalSpinLocker lock; 1165 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1166 struct sigaction new_act; 1167 struct sigaction *pnew_act = act ? &new_act : nullptr; 1168 if (act) { 1169 internal_memcpy(pnew_act, act, sizeof(struct sigaction)); 1170 if (pnew_act->sa_flags & SA_SIGINFO) { 1171 uptr cb = (uptr)(pnew_act->sa_sigaction); 1172 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1173 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1174 pnew_act->sa_sigaction = SignalAction; 1175 } 1176 } else { 1177 uptr cb = (uptr)(pnew_act->sa_handler); 1178 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1179 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1180 pnew_act->sa_handler = SignalHandler; 1181 } 1182 } 1183 } 1184 1185 int ret = sigaction(signum, pnew_act, oldact); 1186 1187 if (ret == 0 && oldact) { 1188 if (oldact->sa_flags & SA_SIGINFO) { 1189 if (oldact->sa_sigaction == SignalAction) 1190 oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb; 1191 } else { 1192 if (oldact->sa_handler == SignalHandler) 1193 oldact->sa_handler = (decltype(oldact->sa_handler))old_cb; 1194 } 1195 } 1196 1197 if (oldact) { 1198 dfsan_set_label(0, oldact, sizeof(struct sigaction)); 1199 } 1200 *ret_label = 0; 1201 return ret; 1202 } 1203 1204 SANITIZER_INTERFACE_ATTRIBUTE 1205 int __dfso_sigaction(int signum, const struct sigaction *act, 1206 struct sigaction *oldact, dfsan_label signum_label, 1207 dfsan_label act_label, dfsan_label oldact_label, 1208 dfsan_label *ret_label, dfsan_origin signum_origin, 1209 dfsan_origin act_origin, dfsan_origin oldact_origin, 1210 dfsan_origin *ret_origin) { 1211 return __dfsw_sigaction(signum, act, oldact, signum_label, act_label, 1212 oldact_label, ret_label); 1213 } 1214 1215 static sighandler_t dfsan_signal(int signum, sighandler_t handler, 1216 dfsan_label *ret_label) { 1217 CHECK_LT(signum, kMaxSignals); 1218 SignalSpinLocker lock; 1219 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1220 if (handler != SIG_IGN && handler != SIG_DFL) { 1221 atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed); 1222 handler = &SignalHandler; 1223 } 1224 1225 sighandler_t ret = signal(signum, handler); 1226 1227 if (ret == SignalHandler) 1228 ret = (sighandler_t)old_cb; 1229 1230 *ret_label = 0; 1231 return ret; 1232 } 1233 1234 SANITIZER_INTERFACE_ATTRIBUTE 1235 sighandler_t __dfsw_signal(int signum, 1236 void *(*handler_trampoline)(void *, int, dfsan_label, 1237 dfsan_label *), 1238 sighandler_t handler, dfsan_label signum_label, 1239 dfsan_label handler_label, dfsan_label *ret_label) { 1240 return dfsan_signal(signum, handler, ret_label); 1241 } 1242 1243 SANITIZER_INTERFACE_ATTRIBUTE 1244 sighandler_t __dfso_signal( 1245 int signum, 1246 void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *, 1247 dfsan_origin, dfsan_origin *), 1248 sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label, 1249 dfsan_label *ret_label, dfsan_origin signum_origin, 1250 dfsan_origin handler_origin, dfsan_origin *ret_origin) { 1251 return dfsan_signal(signum, handler, ret_label); 1252 } 1253 1254 SANITIZER_INTERFACE_ATTRIBUTE 1255 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1256 dfsan_label old_ss_label, dfsan_label *ret_label) { 1257 int ret = sigaltstack(ss, old_ss); 1258 if (ret != -1 && old_ss) 1259 dfsan_set_label(0, old_ss, sizeof(*old_ss)); 1260 *ret_label = 0; 1261 return ret; 1262 } 1263 1264 SANITIZER_INTERFACE_ATTRIBUTE 1265 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1266 dfsan_label old_ss_label, dfsan_label *ret_label, 1267 dfsan_origin ss_origin, dfsan_origin old_ss_origin, 1268 dfsan_origin *ret_origin) { 1269 return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label); 1270 } 1271 1272 SANITIZER_INTERFACE_ATTRIBUTE 1273 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, 1274 dfsan_label tv_label, dfsan_label tz_label, 1275 dfsan_label *ret_label) { 1276 int ret = gettimeofday(tv, tz); 1277 if (tv) { 1278 dfsan_set_label(0, tv, sizeof(struct timeval)); 1279 } 1280 if (tz) { 1281 dfsan_set_label(0, tz, sizeof(struct timezone)); 1282 } 1283 *ret_label = 0; 1284 return ret; 1285 } 1286 1287 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, 1288 dfsan_label s_label, 1289 dfsan_label c_label, 1290 dfsan_label n_label, 1291 dfsan_label *ret_label) { 1292 void *ret = memchr(s, c, n); 1293 if (flags().strict_data_dependencies) { 1294 *ret_label = ret ? s_label : 0; 1295 } else { 1296 size_t len = 1297 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 1298 : n; 1299 *ret_label = 1300 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); 1301 } 1302 return ret; 1303 } 1304 1305 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, 1306 dfsan_label s_label, 1307 dfsan_label c_label, 1308 dfsan_label *ret_label) { 1309 char *ret = strrchr(s, c); 1310 if (flags().strict_data_dependencies) { 1311 *ret_label = ret ? s_label : 0; 1312 } else { 1313 *ret_label = 1314 dfsan_union(dfsan_read_label(s, strlen(s) + 1), 1315 dfsan_union(s_label, c_label)); 1316 } 1317 1318 return ret; 1319 } 1320 1321 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, 1322 dfsan_label haystack_label, 1323 dfsan_label needle_label, 1324 dfsan_label *ret_label) { 1325 char *ret = strstr(haystack, needle); 1326 if (flags().strict_data_dependencies) { 1327 *ret_label = ret ? haystack_label : 0; 1328 } else { 1329 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1; 1330 *ret_label = 1331 dfsan_union(dfsan_read_label(haystack, len), 1332 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1), 1333 dfsan_union(haystack_label, needle_label))); 1334 } 1335 1336 return ret; 1337 } 1338 1339 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, 1340 struct timespec *rem, 1341 dfsan_label req_label, 1342 dfsan_label rem_label, 1343 dfsan_label *ret_label) { 1344 int ret = nanosleep(req, rem); 1345 *ret_label = 0; 1346 if (ret == -1) { 1347 // Interrupted by a signal, rem is filled with the remaining time. 1348 dfsan_set_label(0, rem, sizeof(struct timespec)); 1349 } 1350 return ret; 1351 } 1352 1353 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) { 1354 dfsan_set_label(0, msg, sizeof(*msg)); 1355 dfsan_set_label(0, msg->msg_name, msg->msg_namelen); 1356 dfsan_set_label(0, msg->msg_control, msg->msg_controllen); 1357 for (size_t i = 0; bytes_written > 0; ++i) { 1358 assert(i < msg->msg_iovlen); 1359 struct iovec *iov = &msg->msg_iov[i]; 1360 size_t iov_written = 1361 bytes_written < iov->iov_len ? bytes_written : iov->iov_len; 1362 dfsan_set_label(0, iov->iov_base, iov_written); 1363 bytes_written -= iov_written; 1364 } 1365 } 1366 1367 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg( 1368 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, 1369 struct timespec *timeout, dfsan_label sockfd_label, 1370 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, 1371 dfsan_label timeout_label, dfsan_label *ret_label) { 1372 int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout); 1373 for (int i = 0; i < ret; ++i) { 1374 dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len)); 1375 clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr); 1376 } 1377 *ret_label = 0; 1378 return ret; 1379 } 1380 1381 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg( 1382 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, 1383 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) { 1384 ssize_t ret = recvmsg(sockfd, msg, flags); 1385 if (ret >= 0) 1386 clear_msghdr_labels(ret, msg); 1387 *ret_label = 0; 1388 return ret; 1389 } 1390 1391 SANITIZER_INTERFACE_ATTRIBUTE int 1392 __dfsw_socketpair(int domain, int type, int protocol, int sv[2], 1393 dfsan_label domain_label, dfsan_label type_label, 1394 dfsan_label protocol_label, dfsan_label sv_label, 1395 dfsan_label *ret_label) { 1396 int ret = socketpair(domain, type, protocol, sv); 1397 *ret_label = 0; 1398 if (ret == 0) { 1399 dfsan_set_label(0, sv, sizeof(*sv) * 2); 1400 } 1401 return ret; 1402 } 1403 1404 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt( 1405 int sockfd, int level, int optname, void *optval, socklen_t *optlen, 1406 dfsan_label sockfd_label, dfsan_label level_label, 1407 dfsan_label optname_label, dfsan_label optval_label, 1408 dfsan_label optlen_label, dfsan_label *ret_label) { 1409 int ret = getsockopt(sockfd, level, optname, optval, optlen); 1410 if (ret != -1 && optval && optlen) { 1411 dfsan_set_label(0, optlen, sizeof(*optlen)); 1412 dfsan_set_label(0, optval, *optlen); 1413 } 1414 *ret_label = 0; 1415 return ret; 1416 } 1417 1418 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname( 1419 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 1420 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 1421 dfsan_label *ret_label) { 1422 socklen_t origlen = addrlen ? *addrlen : 0; 1423 int ret = getsockname(sockfd, addr, addrlen); 1424 if (ret != -1 && addr && addrlen) { 1425 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 1426 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 1427 dfsan_set_label(0, addr, written_bytes); 1428 } 1429 *ret_label = 0; 1430 return ret; 1431 } 1432 1433 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername( 1434 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 1435 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 1436 dfsan_label *ret_label) { 1437 socklen_t origlen = addrlen ? *addrlen : 0; 1438 int ret = getpeername(sockfd, addr, addrlen); 1439 if (ret != -1 && addr && addrlen) { 1440 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 1441 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 1442 dfsan_set_label(0, addr, written_bytes); 1443 } 1444 *ret_label = 0; 1445 return ret; 1446 } 1447 1448 // Type of the trampoline function passed to the custom version of 1449 // dfsan_set_write_callback. 1450 typedef void (*write_trampoline_t)( 1451 void *callback, 1452 int fd, const void *buf, ssize_t count, 1453 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label); 1454 1455 typedef void (*write_origin_trampoline_t)( 1456 void *callback, int fd, const void *buf, ssize_t count, 1457 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, 1458 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin); 1459 1460 // Calls to dfsan_set_write_callback() set the values in this struct. 1461 // Calls to the custom version of write() read (and invoke) them. 1462 static struct { 1463 write_trampoline_t write_callback_trampoline = nullptr; 1464 void *write_callback = nullptr; 1465 } write_callback_info; 1466 1467 static struct { 1468 write_origin_trampoline_t write_callback_trampoline = nullptr; 1469 void *write_callback = nullptr; 1470 } write_origin_callback_info; 1471 1472 SANITIZER_INTERFACE_ATTRIBUTE void 1473 __dfsw_dfsan_set_write_callback( 1474 write_trampoline_t write_callback_trampoline, 1475 void *write_callback, 1476 dfsan_label write_callback_label, 1477 dfsan_label *ret_label) { 1478 write_callback_info.write_callback_trampoline = write_callback_trampoline; 1479 write_callback_info.write_callback = write_callback; 1480 } 1481 1482 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback( 1483 write_origin_trampoline_t write_callback_trampoline, void *write_callback, 1484 dfsan_label write_callback_label, dfsan_label *ret_label, 1485 dfsan_origin write_callback_origin, dfsan_origin *ret_origin) { 1486 write_origin_callback_info.write_callback_trampoline = 1487 write_callback_trampoline; 1488 write_origin_callback_info.write_callback = write_callback; 1489 } 1490 1491 SANITIZER_INTERFACE_ATTRIBUTE int 1492 __dfsw_write(int fd, const void *buf, size_t count, 1493 dfsan_label fd_label, dfsan_label buf_label, 1494 dfsan_label count_label, dfsan_label *ret_label) { 1495 if (write_callback_info.write_callback) { 1496 write_callback_info.write_callback_trampoline( 1497 write_callback_info.write_callback, 1498 fd, buf, count, 1499 fd_label, buf_label, count_label); 1500 } 1501 1502 *ret_label = 0; 1503 return write(fd, buf, count); 1504 } 1505 1506 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write( 1507 int fd, const void *buf, size_t count, dfsan_label fd_label, 1508 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, 1509 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, 1510 dfsan_origin *ret_origin) { 1511 if (write_origin_callback_info.write_callback) { 1512 write_origin_callback_info.write_callback_trampoline( 1513 write_origin_callback_info.write_callback, fd, buf, count, fd_label, 1514 buf_label, count_label, fd_origin, buf_origin, count_origin); 1515 } 1516 1517 *ret_label = 0; 1518 return write(fd, buf, count); 1519 } 1520 } // namespace __dfsan 1521 1522 // Type used to extract a dfsan_label with va_arg() 1523 typedef int dfsan_label_va; 1524 1525 // Formats a chunk either a constant string or a single format directive (e.g., 1526 // '%.3f'). 1527 struct Formatter { 1528 Formatter(char *str_, const char *fmt_, size_t size_) 1529 : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_), 1530 width(-1) {} 1531 1532 int format() { 1533 char *tmp_fmt = build_format_string(); 1534 int retval = 1535 snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt, 1536 0 /* used only to avoid warnings */); 1537 free(tmp_fmt); 1538 return retval; 1539 } 1540 1541 template <typename T> int format(T arg) { 1542 char *tmp_fmt = build_format_string(); 1543 int retval; 1544 if (width >= 0) { 1545 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 1546 tmp_fmt, width, arg); 1547 } else { 1548 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 1549 tmp_fmt, arg); 1550 } 1551 free(tmp_fmt); 1552 return retval; 1553 } 1554 1555 char *build_format_string() { 1556 size_t fmt_size = fmt_cur - fmt_start + 1; 1557 char *new_fmt = (char *)malloc(fmt_size + 1); 1558 assert(new_fmt); 1559 internal_memcpy(new_fmt, fmt_start, fmt_size); 1560 new_fmt[fmt_size] = '\0'; 1561 return new_fmt; 1562 } 1563 1564 char *str_cur() { return str + str_off; } 1565 1566 size_t num_written_bytes(int retval) { 1567 if (retval < 0) { 1568 return 0; 1569 } 1570 1571 size_t num_avail = str_off < size ? size - str_off : 0; 1572 if (num_avail == 0) { 1573 return 0; 1574 } 1575 1576 size_t num_written = retval; 1577 // A return value of {v,}snprintf of size or more means that the output was 1578 // truncated. 1579 if (num_written >= num_avail) { 1580 num_written -= num_avail; 1581 } 1582 1583 return num_written; 1584 } 1585 1586 char *str; 1587 size_t str_off; 1588 size_t size; 1589 const char *fmt_start; 1590 const char *fmt_cur; 1591 int width; 1592 }; 1593 1594 // Formats the input and propagates the input labels to the output. The output 1595 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and 1596 // 'ap' are the format string and the list of arguments for formatting. Returns 1597 // the return value vsnprintf would return. 1598 // 1599 // The function tokenizes the format string in chunks representing either a 1600 // constant string or a single format directive (e.g., '%.3f') and formats each 1601 // chunk independently into the output string. This approach allows to figure 1602 // out which bytes of the output string depends on which argument and thus to 1603 // propagate labels more precisely. 1604 // 1605 // WARNING: This implementation does not support conversion specifiers with 1606 // positional arguments. 1607 static int format_buffer(char *str, size_t size, const char *fmt, 1608 dfsan_label *va_labels, dfsan_label *ret_label, 1609 va_list ap) { 1610 Formatter formatter(str, fmt, size); 1611 1612 while (*formatter.fmt_cur) { 1613 formatter.fmt_start = formatter.fmt_cur; 1614 formatter.width = -1; 1615 int retval = 0; 1616 1617 if (*formatter.fmt_cur != '%') { 1618 // Ordinary character. Consume all the characters until a '%' or the end 1619 // of the string. 1620 for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%'; 1621 ++formatter.fmt_cur) {} 1622 retval = formatter.format(); 1623 dfsan_set_label(0, formatter.str_cur(), 1624 formatter.num_written_bytes(retval)); 1625 } else { 1626 // Conversion directive. Consume all the characters until a conversion 1627 // specifier or the end of the string. 1628 bool end_fmt = false; 1629 for (; *formatter.fmt_cur && !end_fmt; ) { 1630 switch (*++formatter.fmt_cur) { 1631 case 'd': 1632 case 'i': 1633 case 'o': 1634 case 'u': 1635 case 'x': 1636 case 'X': 1637 switch (*(formatter.fmt_cur - 1)) { 1638 case 'h': 1639 // Also covers the 'hh' case (since the size of the arg is still 1640 // an int). 1641 retval = formatter.format(va_arg(ap, int)); 1642 break; 1643 case 'l': 1644 if (formatter.fmt_cur - formatter.fmt_start >= 2 && 1645 *(formatter.fmt_cur - 2) == 'l') { 1646 retval = formatter.format(va_arg(ap, long long int)); 1647 } else { 1648 retval = formatter.format(va_arg(ap, long int)); 1649 } 1650 break; 1651 case 'q': 1652 retval = formatter.format(va_arg(ap, long long int)); 1653 break; 1654 case 'j': 1655 retval = formatter.format(va_arg(ap, intmax_t)); 1656 break; 1657 case 'z': 1658 case 't': 1659 retval = formatter.format(va_arg(ap, size_t)); 1660 break; 1661 default: 1662 retval = formatter.format(va_arg(ap, int)); 1663 } 1664 dfsan_set_label(*va_labels++, formatter.str_cur(), 1665 formatter.num_written_bytes(retval)); 1666 end_fmt = true; 1667 break; 1668 1669 case 'a': 1670 case 'A': 1671 case 'e': 1672 case 'E': 1673 case 'f': 1674 case 'F': 1675 case 'g': 1676 case 'G': 1677 if (*(formatter.fmt_cur - 1) == 'L') { 1678 retval = formatter.format(va_arg(ap, long double)); 1679 } else { 1680 retval = formatter.format(va_arg(ap, double)); 1681 } 1682 dfsan_set_label(*va_labels++, formatter.str_cur(), 1683 formatter.num_written_bytes(retval)); 1684 end_fmt = true; 1685 break; 1686 1687 case 'c': 1688 retval = formatter.format(va_arg(ap, int)); 1689 dfsan_set_label(*va_labels++, formatter.str_cur(), 1690 formatter.num_written_bytes(retval)); 1691 end_fmt = true; 1692 break; 1693 1694 case 's': { 1695 char *arg = va_arg(ap, char *); 1696 retval = formatter.format(arg); 1697 va_labels++; 1698 internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg), 1699 sizeof(dfsan_label) * 1700 formatter.num_written_bytes(retval)); 1701 end_fmt = true; 1702 break; 1703 } 1704 1705 case 'p': 1706 retval = formatter.format(va_arg(ap, void *)); 1707 dfsan_set_label(*va_labels++, formatter.str_cur(), 1708 formatter.num_written_bytes(retval)); 1709 end_fmt = true; 1710 break; 1711 1712 case 'n': { 1713 int *ptr = va_arg(ap, int *); 1714 *ptr = (int)formatter.str_off; 1715 va_labels++; 1716 dfsan_set_label(0, ptr, sizeof(ptr)); 1717 end_fmt = true; 1718 break; 1719 } 1720 1721 case '%': 1722 retval = formatter.format(); 1723 dfsan_set_label(0, formatter.str_cur(), 1724 formatter.num_written_bytes(retval)); 1725 end_fmt = true; 1726 break; 1727 1728 case '*': 1729 formatter.width = va_arg(ap, int); 1730 va_labels++; 1731 break; 1732 1733 default: 1734 break; 1735 } 1736 } 1737 } 1738 1739 if (retval < 0) { 1740 return retval; 1741 } 1742 1743 formatter.fmt_cur++; 1744 formatter.str_off += retval; 1745 } 1746 1747 *ret_label = 0; 1748 1749 // Number of bytes written in total. 1750 return formatter.str_off; 1751 } 1752 1753 extern "C" { 1754 SANITIZER_INTERFACE_ATTRIBUTE 1755 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label, 1756 dfsan_label format_label, dfsan_label *va_labels, 1757 dfsan_label *ret_label, ...) { 1758 va_list ap; 1759 va_start(ap, ret_label); 1760 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, ap); 1761 va_end(ap); 1762 return ret; 1763 } 1764 1765 SANITIZER_INTERFACE_ATTRIBUTE 1766 int __dfsw_snprintf(char *str, size_t size, const char *format, 1767 dfsan_label str_label, dfsan_label size_label, 1768 dfsan_label format_label, dfsan_label *va_labels, 1769 dfsan_label *ret_label, ...) { 1770 va_list ap; 1771 va_start(ap, ret_label); 1772 int ret = format_buffer(str, size, format, va_labels, ret_label, ap); 1773 va_end(ap); 1774 return ret; 1775 } 1776 1777 static void BeforeFork() { 1778 StackDepotLockAll(); 1779 GetChainedOriginDepot()->LockAll(); 1780 } 1781 1782 static void AfterFork() { 1783 GetChainedOriginDepot()->UnlockAll(); 1784 StackDepotUnlockAll(); 1785 } 1786 1787 SANITIZER_INTERFACE_ATTRIBUTE 1788 pid_t __dfsw_fork(dfsan_label *ret_label) { 1789 pid_t pid = fork(); 1790 *ret_label = 0; 1791 return pid; 1792 } 1793 1794 SANITIZER_INTERFACE_ATTRIBUTE 1795 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) { 1796 BeforeFork(); 1797 pid_t pid = __dfsw_fork(ret_label); 1798 AfterFork(); 1799 return pid; 1800 } 1801 1802 // Default empty implementations (weak). Users should redefine them. 1803 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {} 1804 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *, 1805 u32 *) {} 1806 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, void) {} 1807 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {} 1808 1809 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {} 1810 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {} 1811 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {} 1812 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {} 1813 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {} 1814 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1, 1815 void) {} 1816 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2, 1817 void) {} 1818 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4, 1819 void) {} 1820 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8, 1821 void) {} 1822 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {} 1823 } // extern "C" 1824