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