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_label *sdest = shadow_for(dest); 501 const dfsan_label *ssrc = shadow_for(src); 502 internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); 503 return internal_memcpy(dest, src, n); 504 } 505 506 static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) { 507 dfsan_mem_origin_transfer(dest, src, n); 508 return dfsan_memcpy(dest, src, n); 509 } 510 511 static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) { 512 internal_memset(s, c, n); 513 dfsan_set_label(c_label, s, n); 514 } 515 516 static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label, 517 dfsan_origin c_origin, size_t n) { 518 internal_memset(s, c, n); 519 dfsan_set_label_origin(c_label, c_origin, s, n); 520 } 521 522 SANITIZER_INTERFACE_ATTRIBUTE 523 void *__dfsw_memcpy(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_memcpy(dest, src, n); 528 } 529 530 SANITIZER_INTERFACE_ATTRIBUTE 531 void *__dfso_memcpy(void *dest, const void *src, size_t n, 532 dfsan_label dest_label, dfsan_label src_label, 533 dfsan_label n_label, dfsan_label *ret_label, 534 dfsan_origin dest_origin, dfsan_origin src_origin, 535 dfsan_origin n_origin, dfsan_origin *ret_origin) { 536 *ret_label = dest_label; 537 *ret_origin = dest_origin; 538 return dfsan_memcpy_with_origin(dest, src, n); 539 } 540 541 SANITIZER_INTERFACE_ATTRIBUTE 542 void *__dfsw_memmove(void *dest, const void *src, size_t n, 543 dfsan_label dest_label, dfsan_label src_label, 544 dfsan_label n_label, dfsan_label *ret_label) { 545 *ret_label = dest_label; 546 return dfsan_memmove(dest, src, n); 547 } 548 549 SANITIZER_INTERFACE_ATTRIBUTE 550 void *__dfso_memmove(void *dest, const void *src, size_t n, 551 dfsan_label dest_label, dfsan_label src_label, 552 dfsan_label n_label, dfsan_label *ret_label, 553 dfsan_origin dest_origin, dfsan_origin src_origin, 554 dfsan_origin n_origin, dfsan_origin *ret_origin) { 555 *ret_label = dest_label; 556 *ret_origin = dest_origin; 557 return dfsan_memmove_with_origin(dest, src, n); 558 } 559 560 SANITIZER_INTERFACE_ATTRIBUTE 561 void *__dfsw_memset(void *s, int c, size_t n, 562 dfsan_label s_label, dfsan_label c_label, 563 dfsan_label n_label, dfsan_label *ret_label) { 564 dfsan_memset(s, c, c_label, n); 565 *ret_label = s_label; 566 return s; 567 } 568 569 SANITIZER_INTERFACE_ATTRIBUTE 570 void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label, 571 dfsan_label c_label, dfsan_label n_label, 572 dfsan_label *ret_label, dfsan_origin s_origin, 573 dfsan_origin c_origin, dfsan_origin n_origin, 574 dfsan_origin *ret_origin) { 575 dfsan_memset_with_origin(s, c, c_label, c_origin, n); 576 *ret_label = s_label; 577 *ret_origin = s_origin; 578 return s; 579 } 580 581 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src, 582 dfsan_label dest_label, 583 dfsan_label src_label, 584 dfsan_label *ret_label) { 585 size_t dest_len = strlen(dest); 586 char *ret = strcat(dest, src); 587 dfsan_label *sdest = shadow_for(dest + dest_len); 588 const dfsan_label *ssrc = shadow_for(src); 589 internal_memcpy((void *)sdest, (const void *)ssrc, 590 strlen(src) * sizeof(dfsan_label)); 591 *ret_label = dest_label; 592 return ret; 593 } 594 595 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat( 596 char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label, 597 dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin, 598 dfsan_origin *ret_origin) { 599 size_t dest_len = strlen(dest); 600 char *ret = strcat(dest, src); 601 dfsan_label *sdest = shadow_for(dest + dest_len); 602 const dfsan_label *ssrc = shadow_for(src); 603 size_t src_len = strlen(src); 604 dfsan_mem_origin_transfer(dest + dest_len, src, src_len); 605 internal_memcpy((void *)sdest, (const void *)ssrc, 606 src_len * sizeof(dfsan_label)); 607 *ret_label = dest_label; 608 *ret_origin = dest_origin; 609 return ret; 610 } 611 612 SANITIZER_INTERFACE_ATTRIBUTE char * 613 __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) { 614 size_t len = strlen(s); 615 void *p = malloc(len+1); 616 dfsan_memcpy(p, s, len+1); 617 *ret_label = 0; 618 return static_cast<char *>(p); 619 } 620 621 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s, 622 dfsan_label s_label, 623 dfsan_label *ret_label, 624 dfsan_origin s_origin, 625 dfsan_origin *ret_origin) { 626 size_t len = strlen(s); 627 void *p = malloc(len + 1); 628 dfsan_memcpy_with_origin(p, s, len + 1); 629 *ret_label = 0; 630 return static_cast<char *>(p); 631 } 632 633 SANITIZER_INTERFACE_ATTRIBUTE char * 634 __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, 635 dfsan_label s2_label, dfsan_label n_label, 636 dfsan_label *ret_label) { 637 size_t len = strlen(s2); 638 if (len < n) { 639 dfsan_memcpy(s1, s2, len+1); 640 dfsan_memset(s1+len+1, 0, 0, n-len-1); 641 } else { 642 dfsan_memcpy(s1, s2, n); 643 } 644 645 *ret_label = s1_label; 646 return s1; 647 } 648 649 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy( 650 char *s1, const char *s2, size_t n, dfsan_label s1_label, 651 dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label, 652 dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin, 653 dfsan_origin *ret_origin) { 654 size_t len = strlen(s2); 655 if (len < n) { 656 dfsan_memcpy_with_origin(s1, s2, len + 1); 657 dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1); 658 } else { 659 dfsan_memcpy_with_origin(s1, s2, n); 660 } 661 662 *ret_label = s1_label; 663 *ret_origin = s1_origin; 664 return s1; 665 } 666 667 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 668 __dfsw_pread(int fd, void *buf, size_t count, off_t offset, 669 dfsan_label fd_label, dfsan_label buf_label, 670 dfsan_label count_label, dfsan_label offset_label, 671 dfsan_label *ret_label) { 672 ssize_t ret = pread(fd, buf, count, offset); 673 if (ret > 0) 674 dfsan_set_label(0, buf, ret); 675 *ret_label = 0; 676 return ret; 677 } 678 679 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread( 680 int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label, 681 dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label, 682 dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin, 683 dfsan_origin count_origin, dfsan_label offset_origin, 684 dfsan_origin *ret_origin) { 685 return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label, 686 offset_label, ret_label); 687 } 688 689 SANITIZER_INTERFACE_ATTRIBUTE ssize_t 690 __dfsw_read(int fd, void *buf, size_t count, 691 dfsan_label fd_label, dfsan_label buf_label, 692 dfsan_label count_label, 693 dfsan_label *ret_label) { 694 ssize_t ret = read(fd, buf, count); 695 if (ret > 0) 696 dfsan_set_label(0, buf, ret); 697 *ret_label = 0; 698 return ret; 699 } 700 701 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read( 702 int fd, void *buf, size_t count, dfsan_label fd_label, 703 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, 704 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, 705 dfsan_origin *ret_origin) { 706 return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label, 707 ret_label); 708 } 709 710 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id, 711 struct timespec *tp, 712 dfsan_label clk_id_label, 713 dfsan_label tp_label, 714 dfsan_label *ret_label) { 715 int ret = clock_gettime(clk_id, tp); 716 if (ret == 0) 717 dfsan_set_label(0, tp, sizeof(struct timespec)); 718 *ret_label = 0; 719 return ret; 720 } 721 722 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime( 723 clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label, 724 dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin, 725 dfsan_origin tp_origin, dfsan_origin *ret_origin) { 726 return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label); 727 } 728 729 static void dfsan_set_zero_label(const void *ptr, uptr size) { 730 dfsan_set_label(0, const_cast<void *>(ptr), size); 731 } 732 733 // dlopen() ultimately calls mmap() down inside the loader, which generally 734 // doesn't participate in dynamic symbol resolution. Therefore we won't 735 // intercept its calls to mmap, and we have to hook it here. 736 SANITIZER_INTERFACE_ATTRIBUTE void * 737 __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label, 738 dfsan_label flag_label, dfsan_label *ret_label) { 739 void *handle = dlopen(filename, flag); 740 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle); 741 if (map) 742 ForEachMappedRegion(map, dfsan_set_zero_label); 743 *ret_label = 0; 744 return handle; 745 } 746 747 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen( 748 const char *filename, int flag, dfsan_label filename_label, 749 dfsan_label flag_label, dfsan_label *ret_label, 750 dfsan_origin filename_origin, dfsan_origin flag_origin, 751 dfsan_origin *ret_origin) { 752 return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label); 753 } 754 755 static void *DFsanThreadStartFunc(void *arg) { 756 DFsanThread *t = (DFsanThread *)arg; 757 SetCurrentThread(t); 758 return t->ThreadStart(); 759 } 760 761 static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr, 762 void *start_routine_trampoline, 763 void *start_routine, void *arg, 764 dfsan_label *ret_label, 765 bool track_origins = false) { 766 pthread_attr_t myattr; 767 if (!attr) { 768 pthread_attr_init(&myattr); 769 attr = &myattr; 770 } 771 772 // Ensure that the thread stack is large enough to hold all TLS data. 773 AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr))); 774 775 DFsanThread *t = 776 DFsanThread::Create(start_routine_trampoline, 777 (thread_callback_t)start_routine, arg, track_origins); 778 int res = pthread_create(thread, attr, DFsanThreadStartFunc, t); 779 780 if (attr == &myattr) 781 pthread_attr_destroy(&myattr); 782 *ret_label = 0; 783 return res; 784 } 785 786 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create( 787 pthread_t *thread, const pthread_attr_t *attr, 788 void *(*start_routine_trampoline)(void *, void *, dfsan_label, 789 dfsan_label *), 790 void *start_routine, void *arg, dfsan_label thread_label, 791 dfsan_label attr_label, dfsan_label start_routine_label, 792 dfsan_label arg_label, dfsan_label *ret_label) { 793 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, 794 start_routine, arg, ret_label); 795 } 796 797 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create( 798 pthread_t *thread, const pthread_attr_t *attr, 799 void *(*start_routine_trampoline)(void *, void *, dfsan_label, 800 dfsan_label *, dfsan_origin, 801 dfsan_origin *), 802 void *start_routine, void *arg, dfsan_label thread_label, 803 dfsan_label attr_label, dfsan_label start_routine_label, 804 dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin, 805 dfsan_origin attr_origin, dfsan_origin start_routine_origin, 806 dfsan_origin arg_origin, dfsan_origin *ret_origin) { 807 return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline, 808 start_routine, arg, ret_label, true); 809 } 810 811 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread, 812 void **retval, 813 dfsan_label thread_label, 814 dfsan_label retval_label, 815 dfsan_label *ret_label) { 816 int ret = pthread_join(thread, retval); 817 if (ret == 0 && retval) 818 dfsan_set_label(0, retval, sizeof(*retval)); 819 *ret_label = 0; 820 return ret; 821 } 822 823 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join( 824 pthread_t thread, void **retval, dfsan_label thread_label, 825 dfsan_label retval_label, dfsan_label *ret_label, 826 dfsan_origin thread_origin, dfsan_origin retval_origin, 827 dfsan_origin *ret_origin) { 828 return __dfsw_pthread_join(thread, retval, thread_label, retval_label, 829 ret_label); 830 } 831 832 struct dl_iterate_phdr_info { 833 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 834 size_t size, void *data, dfsan_label info_label, 835 dfsan_label size_label, dfsan_label data_label, 836 dfsan_label *ret_label); 837 void *callback; 838 void *data; 839 }; 840 841 struct dl_iterate_phdr_origin_info { 842 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 843 size_t size, void *data, dfsan_label info_label, 844 dfsan_label size_label, dfsan_label data_label, 845 dfsan_label *ret_label, dfsan_origin info_origin, 846 dfsan_origin size_origin, dfsan_origin data_origin, 847 dfsan_origin *ret_origin); 848 void *callback; 849 void *data; 850 }; 851 852 int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) { 853 dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data; 854 dfsan_set_label(0, *info); 855 dfsan_set_label(0, const_cast<char *>(info->dlpi_name), 856 strlen(info->dlpi_name) + 1); 857 dfsan_set_label( 858 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), 859 sizeof(*info->dlpi_phdr) * info->dlpi_phnum); 860 dfsan_label ret_label; 861 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, 862 0, &ret_label); 863 } 864 865 int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size, 866 void *data) { 867 dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data; 868 dfsan_set_label(0, *info); 869 dfsan_set_label(0, const_cast<char *>(info->dlpi_name), 870 strlen(info->dlpi_name) + 1); 871 dfsan_set_label( 872 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)), 873 sizeof(*info->dlpi_phdr) * info->dlpi_phnum); 874 dfsan_label ret_label; 875 dfsan_origin ret_origin; 876 return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0, 877 0, &ret_label, 0, 0, 0, &ret_origin); 878 } 879 880 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( 881 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 882 size_t size, void *data, dfsan_label info_label, 883 dfsan_label size_label, dfsan_label data_label, 884 dfsan_label *ret_label), 885 void *callback, void *data, dfsan_label callback_label, 886 dfsan_label data_label, dfsan_label *ret_label) { 887 dl_iterate_phdr_info dipi = { callback_trampoline, callback, data }; 888 *ret_label = 0; 889 return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); 890 } 891 892 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr( 893 int (*callback_trampoline)(void *callback, struct dl_phdr_info *info, 894 size_t size, void *data, dfsan_label info_label, 895 dfsan_label size_label, dfsan_label data_label, 896 dfsan_label *ret_label, dfsan_origin info_origin, 897 dfsan_origin size_origin, 898 dfsan_origin data_origin, 899 dfsan_origin *ret_origin), 900 void *callback, void *data, dfsan_label callback_label, 901 dfsan_label data_label, dfsan_label *ret_label, 902 dfsan_origin callback_origin, dfsan_origin data_origin, 903 dfsan_origin *ret_origin) { 904 dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data}; 905 *ret_label = 0; 906 return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi); 907 } 908 909 // This function is only available for glibc 2.27 or newer. Mark it weak so 910 // linking succeeds with older glibcs. 911 SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep, 912 size_t *alignp); 913 914 SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info( 915 size_t *sizep, size_t *alignp, dfsan_label sizep_label, 916 dfsan_label alignp_label) { 917 assert(_dl_get_tls_static_info); 918 _dl_get_tls_static_info(sizep, alignp); 919 dfsan_set_label(0, sizep, sizeof(*sizep)); 920 dfsan_set_label(0, alignp, sizeof(*alignp)); 921 } 922 923 SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info( 924 size_t *sizep, size_t *alignp, dfsan_label sizep_label, 925 dfsan_label alignp_label, dfsan_origin sizep_origin, 926 dfsan_origin alignp_origin) { 927 __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label); 928 } 929 930 SANITIZER_INTERFACE_ATTRIBUTE 931 char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 932 dfsan_label buf_label, dfsan_label *ret_label) { 933 char *ret = ctime_r(timep, buf); 934 if (ret) { 935 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf, 936 strlen(buf) + 1); 937 *ret_label = buf_label; 938 } else { 939 *ret_label = 0; 940 } 941 return ret; 942 } 943 944 SANITIZER_INTERFACE_ATTRIBUTE 945 char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label, 946 dfsan_label buf_label, dfsan_label *ret_label, 947 dfsan_origin timep_origin, dfsan_origin buf_origin, 948 dfsan_origin *ret_origin) { 949 char *ret = ctime_r(timep, buf); 950 if (ret) { 951 dfsan_set_label_origin( 952 dfsan_read_label(timep, sizeof(time_t)), 953 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf, 954 strlen(buf) + 1); 955 *ret_label = buf_label; 956 *ret_origin = buf_origin; 957 } else { 958 *ret_label = 0; 959 } 960 return ret; 961 } 962 963 SANITIZER_INTERFACE_ATTRIBUTE 964 char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 965 dfsan_label size_label, dfsan_label stream_label, 966 dfsan_label *ret_label) { 967 char *ret = fgets(s, size, stream); 968 if (ret) { 969 dfsan_set_label(0, ret, strlen(ret) + 1); 970 *ret_label = s_label; 971 } else { 972 *ret_label = 0; 973 } 974 return ret; 975 } 976 977 SANITIZER_INTERFACE_ATTRIBUTE 978 char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label, 979 dfsan_label size_label, dfsan_label stream_label, 980 dfsan_label *ret_label, dfsan_origin s_origin, 981 dfsan_origin size_origin, dfsan_origin stream_origin, 982 dfsan_origin *ret_origin) { 983 char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label, 984 ret_label); 985 if (ret) 986 *ret_origin = s_origin; 987 return ret; 988 } 989 990 SANITIZER_INTERFACE_ATTRIBUTE 991 char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label, 992 dfsan_label size_label, dfsan_label *ret_label) { 993 char *ret = getcwd(buf, size); 994 if (ret) { 995 dfsan_set_label(0, ret, strlen(ret) + 1); 996 *ret_label = buf_label; 997 } else { 998 *ret_label = 0; 999 } 1000 return ret; 1001 } 1002 1003 SANITIZER_INTERFACE_ATTRIBUTE 1004 char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label, 1005 dfsan_label size_label, dfsan_label *ret_label, 1006 dfsan_origin buf_origin, dfsan_origin size_origin, 1007 dfsan_origin *ret_origin) { 1008 char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label); 1009 if (ret) 1010 *ret_origin = buf_origin; 1011 return ret; 1012 } 1013 1014 SANITIZER_INTERFACE_ATTRIBUTE 1015 char *__dfsw_get_current_dir_name(dfsan_label *ret_label) { 1016 char *ret = get_current_dir_name(); 1017 if (ret) 1018 dfsan_set_label(0, ret, strlen(ret) + 1); 1019 *ret_label = 0; 1020 return ret; 1021 } 1022 1023 SANITIZER_INTERFACE_ATTRIBUTE 1024 char *__dfso_get_current_dir_name(dfsan_label *ret_label, 1025 dfsan_origin *ret_origin) { 1026 return __dfsw_get_current_dir_name(ret_label); 1027 } 1028 1029 // This function is only available for glibc 2.25 or newer. Mark it weak so 1030 // linking succeeds with older glibcs. 1031 SANITIZER_WEAK_ATTRIBUTE int getentropy(void *buffer, size_t length); 1032 1033 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getentropy(void *buffer, size_t length, 1034 dfsan_label buffer_label, 1035 dfsan_label length_label, 1036 dfsan_label *ret_label) { 1037 int ret = getentropy(buffer, length); 1038 if (ret == 0) { 1039 dfsan_set_label(0, buffer, length); 1040 } 1041 *ret_label = 0; 1042 return ret; 1043 } 1044 1045 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getentropy(void *buffer, size_t length, 1046 dfsan_label buffer_label, 1047 dfsan_label length_label, 1048 dfsan_label *ret_label, 1049 dfsan_origin buffer_origin, 1050 dfsan_origin length_origin, 1051 dfsan_origin *ret_origin) { 1052 return __dfsw_getentropy(buffer, length, buffer_label, length_label, 1053 ret_label); 1054 } 1055 1056 SANITIZER_INTERFACE_ATTRIBUTE 1057 int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label, 1058 dfsan_label len_label, dfsan_label *ret_label) { 1059 int ret = gethostname(name, len); 1060 if (ret == 0) { 1061 dfsan_set_label(0, name, strlen(name) + 1); 1062 } 1063 *ret_label = 0; 1064 return ret; 1065 } 1066 1067 SANITIZER_INTERFACE_ATTRIBUTE 1068 int __dfso_gethostname(char *name, size_t len, dfsan_label name_label, 1069 dfsan_label len_label, dfsan_label *ret_label, 1070 dfsan_origin name_origin, dfsan_origin len_origin, 1071 dfsan_label *ret_origin) { 1072 return __dfsw_gethostname(name, len, name_label, len_label, ret_label); 1073 } 1074 1075 SANITIZER_INTERFACE_ATTRIBUTE 1076 int __dfsw_getrlimit(int resource, struct rlimit *rlim, 1077 dfsan_label resource_label, dfsan_label rlim_label, 1078 dfsan_label *ret_label) { 1079 int ret = getrlimit(resource, rlim); 1080 if (ret == 0) { 1081 dfsan_set_label(0, rlim, sizeof(struct rlimit)); 1082 } 1083 *ret_label = 0; 1084 return ret; 1085 } 1086 1087 SANITIZER_INTERFACE_ATTRIBUTE 1088 int __dfso_getrlimit(int resource, struct rlimit *rlim, 1089 dfsan_label resource_label, dfsan_label rlim_label, 1090 dfsan_label *ret_label, dfsan_origin resource_origin, 1091 dfsan_origin rlim_origin, dfsan_origin *ret_origin) { 1092 return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label, 1093 ret_label); 1094 } 1095 1096 SANITIZER_INTERFACE_ATTRIBUTE 1097 int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, 1098 dfsan_label usage_label, dfsan_label *ret_label) { 1099 int ret = getrusage(who, usage); 1100 if (ret == 0) { 1101 dfsan_set_label(0, usage, sizeof(struct rusage)); 1102 } 1103 *ret_label = 0; 1104 return ret; 1105 } 1106 1107 SANITIZER_INTERFACE_ATTRIBUTE 1108 int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label, 1109 dfsan_label usage_label, dfsan_label *ret_label, 1110 dfsan_origin who_origin, dfsan_origin usage_origin, 1111 dfsan_label *ret_origin) { 1112 return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label); 1113 } 1114 1115 SANITIZER_INTERFACE_ATTRIBUTE 1116 char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, 1117 dfsan_label src_label, dfsan_label *ret_label) { 1118 char *ret = strcpy(dest, src); 1119 if (ret) { 1120 internal_memcpy(shadow_for(dest), shadow_for(src), 1121 sizeof(dfsan_label) * (strlen(src) + 1)); 1122 } 1123 *ret_label = dst_label; 1124 return ret; 1125 } 1126 1127 SANITIZER_INTERFACE_ATTRIBUTE 1128 char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label, 1129 dfsan_label src_label, dfsan_label *ret_label, 1130 dfsan_origin dst_origin, dfsan_origin src_origin, 1131 dfsan_origin *ret_origin) { 1132 char *ret = strcpy(dest, src); 1133 if (ret) { 1134 size_t str_len = strlen(src) + 1; 1135 dfsan_mem_origin_transfer(dest, src, str_len); 1136 internal_memcpy(shadow_for(dest), shadow_for(src), 1137 sizeof(dfsan_label) * str_len); 1138 } 1139 *ret_label = dst_label; 1140 *ret_origin = dst_origin; 1141 return ret; 1142 } 1143 1144 static long int dfsan_strtol(const char *nptr, char **endptr, int base, 1145 char **tmp_endptr) { 1146 assert(tmp_endptr); 1147 long int ret = strtol(nptr, tmp_endptr, base); 1148 if (endptr) 1149 *endptr = *tmp_endptr; 1150 return ret; 1151 } 1152 1153 static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr, 1154 dfsan_label base_label, 1155 dfsan_label *ret_label) { 1156 if (tmp_endptr > nptr) { 1157 // If *tmp_endptr is '\0' include its label as well. 1158 *ret_label = dfsan_union( 1159 base_label, 1160 dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1))); 1161 } else { 1162 *ret_label = 0; 1163 } 1164 } 1165 1166 static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr, 1167 dfsan_label base_label, 1168 dfsan_label *ret_label, 1169 dfsan_origin base_origin, 1170 dfsan_origin *ret_origin) { 1171 if (tmp_endptr > nptr) { 1172 // When multiple inputs are tainted, we propagate one of its origins. 1173 // Because checking if base_label is tainted does not need additional 1174 // computation, we prefer to propagating base_origin. 1175 *ret_origin = base_label 1176 ? base_origin 1177 : dfsan_read_origin_of_first_taint( 1178 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1179 } 1180 } 1181 1182 SANITIZER_INTERFACE_ATTRIBUTE 1183 long int __dfsw_strtol(const char *nptr, char **endptr, int base, 1184 dfsan_label nptr_label, dfsan_label endptr_label, 1185 dfsan_label base_label, dfsan_label *ret_label) { 1186 char *tmp_endptr; 1187 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); 1188 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1189 return ret; 1190 } 1191 1192 SANITIZER_INTERFACE_ATTRIBUTE 1193 long int __dfso_strtol(const char *nptr, char **endptr, int base, 1194 dfsan_label nptr_label, dfsan_label endptr_label, 1195 dfsan_label base_label, dfsan_label *ret_label, 1196 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1197 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1198 char *tmp_endptr; 1199 long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr); 1200 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1201 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1202 ret_origin); 1203 return ret; 1204 } 1205 1206 static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) { 1207 assert(tmp_endptr); 1208 double ret = strtod(nptr, tmp_endptr); 1209 if (endptr) 1210 *endptr = *tmp_endptr; 1211 return ret; 1212 } 1213 1214 static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr, 1215 dfsan_label *ret_label) { 1216 if (tmp_endptr > nptr) { 1217 // If *tmp_endptr is '\0' include its label as well. 1218 *ret_label = dfsan_read_label( 1219 nptr, 1220 tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1221 } else { 1222 *ret_label = 0; 1223 } 1224 } 1225 1226 SANITIZER_INTERFACE_ATTRIBUTE 1227 double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, 1228 dfsan_label endptr_label, dfsan_label *ret_label) { 1229 char *tmp_endptr; 1230 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); 1231 dfsan_strtod_label(nptr, tmp_endptr, ret_label); 1232 return ret; 1233 } 1234 1235 SANITIZER_INTERFACE_ATTRIBUTE 1236 double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label, 1237 dfsan_label endptr_label, dfsan_label *ret_label, 1238 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1239 dfsan_origin *ret_origin) { 1240 char *tmp_endptr; 1241 double ret = dfsan_strtod(nptr, endptr, &tmp_endptr); 1242 dfsan_strtod_label(nptr, tmp_endptr, ret_label); 1243 if (tmp_endptr > nptr) { 1244 // If *tmp_endptr is '\0' include its label as well. 1245 *ret_origin = dfsan_read_origin_of_first_taint( 1246 nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)); 1247 } else { 1248 *ret_origin = 0; 1249 } 1250 return ret; 1251 } 1252 1253 static long long int dfsan_strtoll(const char *nptr, char **endptr, int base, 1254 char **tmp_endptr) { 1255 assert(tmp_endptr); 1256 long long int ret = strtoll(nptr, tmp_endptr, base); 1257 if (endptr) 1258 *endptr = *tmp_endptr; 1259 return ret; 1260 } 1261 1262 SANITIZER_INTERFACE_ATTRIBUTE 1263 long long int __dfsw_strtoll(const char *nptr, char **endptr, int base, 1264 dfsan_label nptr_label, dfsan_label endptr_label, 1265 dfsan_label base_label, dfsan_label *ret_label) { 1266 char *tmp_endptr; 1267 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); 1268 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1269 return ret; 1270 } 1271 1272 SANITIZER_INTERFACE_ATTRIBUTE 1273 long long int __dfso_strtoll(const char *nptr, char **endptr, int base, 1274 dfsan_label nptr_label, dfsan_label endptr_label, 1275 dfsan_label base_label, dfsan_label *ret_label, 1276 dfsan_origin nptr_origin, 1277 dfsan_origin endptr_origin, 1278 dfsan_origin base_origin, 1279 dfsan_origin *ret_origin) { 1280 char *tmp_endptr; 1281 long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr); 1282 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1283 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1284 ret_origin); 1285 return ret; 1286 } 1287 1288 static unsigned long int dfsan_strtoul(const char *nptr, char **endptr, 1289 int base, char **tmp_endptr) { 1290 assert(tmp_endptr); 1291 unsigned long int ret = strtoul(nptr, tmp_endptr, base); 1292 if (endptr) 1293 *endptr = *tmp_endptr; 1294 return ret; 1295 } 1296 1297 SANITIZER_INTERFACE_ATTRIBUTE 1298 unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base, 1299 dfsan_label nptr_label, dfsan_label endptr_label, 1300 dfsan_label base_label, dfsan_label *ret_label) { 1301 char *tmp_endptr; 1302 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); 1303 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1304 return ret; 1305 } 1306 1307 SANITIZER_INTERFACE_ATTRIBUTE 1308 unsigned long int __dfso_strtoul( 1309 const char *nptr, char **endptr, int base, dfsan_label nptr_label, 1310 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, 1311 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1312 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1313 char *tmp_endptr; 1314 unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr); 1315 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1316 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1317 ret_origin); 1318 return ret; 1319 } 1320 1321 static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr, 1322 int base, char **tmp_endptr) { 1323 assert(tmp_endptr); 1324 long long unsigned int ret = strtoull(nptr, tmp_endptr, base); 1325 if (endptr) 1326 *endptr = *tmp_endptr; 1327 return ret; 1328 } 1329 1330 SANITIZER_INTERFACE_ATTRIBUTE 1331 long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, 1332 int base, dfsan_label nptr_label, 1333 dfsan_label endptr_label, 1334 dfsan_label base_label, 1335 dfsan_label *ret_label) { 1336 char *tmp_endptr; 1337 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); 1338 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1339 return ret; 1340 } 1341 1342 SANITIZER_INTERFACE_ATTRIBUTE 1343 long long unsigned int __dfso_strtoull( 1344 const char *nptr, char **endptr, int base, dfsan_label nptr_label, 1345 dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label, 1346 dfsan_origin nptr_origin, dfsan_origin endptr_origin, 1347 dfsan_origin base_origin, dfsan_origin *ret_origin) { 1348 char *tmp_endptr; 1349 long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr); 1350 dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label); 1351 dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin, 1352 ret_origin); 1353 return ret; 1354 } 1355 1356 SANITIZER_INTERFACE_ATTRIBUTE 1357 time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) { 1358 time_t ret = time(t); 1359 if (ret != (time_t) -1 && t) { 1360 dfsan_set_label(0, t, sizeof(time_t)); 1361 } 1362 *ret_label = 0; 1363 return ret; 1364 } 1365 1366 SANITIZER_INTERFACE_ATTRIBUTE 1367 time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label, 1368 dfsan_origin t_origin, dfsan_origin *ret_origin) { 1369 return __dfsw_time(t, t_label, ret_label); 1370 } 1371 1372 SANITIZER_INTERFACE_ATTRIBUTE 1373 int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 1374 dfsan_label src_label, dfsan_label dst_label, 1375 dfsan_label *ret_label) { 1376 int ret = inet_pton(af, src, dst); 1377 if (ret == 1) { 1378 dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst, 1379 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 1380 } 1381 *ret_label = 0; 1382 return ret; 1383 } 1384 1385 SANITIZER_INTERFACE_ATTRIBUTE 1386 int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label, 1387 dfsan_label src_label, dfsan_label dst_label, 1388 dfsan_label *ret_label, dfsan_origin af_origin, 1389 dfsan_origin src_origin, dfsan_origin dst_origin, 1390 dfsan_origin *ret_origin) { 1391 int ret = inet_pton(af, src, dst); 1392 if (ret == 1) { 1393 int src_len = strlen(src) + 1; 1394 dfsan_set_label_origin( 1395 dfsan_read_label(src, src_len), 1396 dfsan_read_origin_of_first_taint(src, src_len), dst, 1397 af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr)); 1398 } 1399 *ret_label = 0; 1400 return ret; 1401 } 1402 1403 SANITIZER_INTERFACE_ATTRIBUTE 1404 struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result, 1405 dfsan_label timep_label, dfsan_label result_label, 1406 dfsan_label *ret_label) { 1407 struct tm *ret = localtime_r(timep, result); 1408 if (ret) { 1409 dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result, 1410 sizeof(struct tm)); 1411 *ret_label = result_label; 1412 } else { 1413 *ret_label = 0; 1414 } 1415 return ret; 1416 } 1417 1418 SANITIZER_INTERFACE_ATTRIBUTE 1419 struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result, 1420 dfsan_label timep_label, dfsan_label result_label, 1421 dfsan_label *ret_label, dfsan_origin timep_origin, 1422 dfsan_origin result_origin, 1423 dfsan_origin *ret_origin) { 1424 struct tm *ret = localtime_r(timep, result); 1425 if (ret) { 1426 dfsan_set_label_origin( 1427 dfsan_read_label(timep, sizeof(time_t)), 1428 dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result, 1429 sizeof(struct tm)); 1430 *ret_label = result_label; 1431 *ret_origin = result_origin; 1432 } else { 1433 *ret_label = 0; 1434 } 1435 return ret; 1436 } 1437 1438 SANITIZER_INTERFACE_ATTRIBUTE 1439 int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd, 1440 char *buf, size_t buflen, struct passwd **result, 1441 dfsan_label uid_label, dfsan_label pwd_label, 1442 dfsan_label buf_label, dfsan_label buflen_label, 1443 dfsan_label result_label, dfsan_label *ret_label) { 1444 // Store the data in pwd, the strings referenced from pwd in buf, and the 1445 // address of pwd in *result. On failure, NULL is stored in *result. 1446 int ret = getpwuid_r(uid, pwd, buf, buflen, result); 1447 if (ret == 0) { 1448 dfsan_set_label(0, pwd, sizeof(struct passwd)); 1449 dfsan_set_label(0, buf, strlen(buf) + 1); 1450 } 1451 *ret_label = 0; 1452 dfsan_set_label(0, result, sizeof(struct passwd*)); 1453 return ret; 1454 } 1455 1456 SANITIZER_INTERFACE_ATTRIBUTE 1457 int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen, 1458 struct passwd **result, dfsan_label uid_label, 1459 dfsan_label pwd_label, dfsan_label buf_label, 1460 dfsan_label buflen_label, dfsan_label result_label, 1461 dfsan_label *ret_label, dfsan_origin uid_origin, 1462 dfsan_origin pwd_origin, dfsan_origin buf_origin, 1463 dfsan_origin buflen_origin, dfsan_origin result_origin, 1464 dfsan_origin *ret_origin) { 1465 return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label, 1466 buf_label, buflen_label, result_label, ret_label); 1467 } 1468 1469 SANITIZER_INTERFACE_ATTRIBUTE 1470 int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents, 1471 int timeout, dfsan_label epfd_label, 1472 dfsan_label events_label, dfsan_label maxevents_label, 1473 dfsan_label timeout_label, dfsan_label *ret_label) { 1474 int ret = epoll_wait(epfd, events, maxevents, timeout); 1475 if (ret > 0) 1476 dfsan_set_label(0, events, ret * sizeof(*events)); 1477 *ret_label = 0; 1478 return ret; 1479 } 1480 1481 SANITIZER_INTERFACE_ATTRIBUTE 1482 int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents, 1483 int timeout, dfsan_label epfd_label, 1484 dfsan_label events_label, dfsan_label maxevents_label, 1485 dfsan_label timeout_label, dfsan_label *ret_label, 1486 dfsan_origin epfd_origin, dfsan_origin events_origin, 1487 dfsan_origin maxevents_origin, 1488 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1489 return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label, 1490 events_label, maxevents_label, timeout_label, 1491 ret_label); 1492 } 1493 1494 SANITIZER_INTERFACE_ATTRIBUTE 1495 int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout, 1496 dfsan_label dfs_label, dfsan_label nfds_label, 1497 dfsan_label timeout_label, dfsan_label *ret_label) { 1498 int ret = poll(fds, nfds, timeout); 1499 if (ret >= 0) { 1500 for (; nfds > 0; --nfds) { 1501 dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents)); 1502 } 1503 } 1504 *ret_label = 0; 1505 return ret; 1506 } 1507 1508 SANITIZER_INTERFACE_ATTRIBUTE 1509 int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout, 1510 dfsan_label dfs_label, dfsan_label nfds_label, 1511 dfsan_label timeout_label, dfsan_label *ret_label, 1512 dfsan_origin dfs_origin, dfsan_origin nfds_origin, 1513 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1514 return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label, 1515 ret_label); 1516 } 1517 1518 SANITIZER_INTERFACE_ATTRIBUTE 1519 int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds, 1520 fd_set *exceptfds, struct timeval *timeout, 1521 dfsan_label nfds_label, dfsan_label readfds_label, 1522 dfsan_label writefds_label, dfsan_label exceptfds_label, 1523 dfsan_label timeout_label, dfsan_label *ret_label) { 1524 int ret = select(nfds, readfds, writefds, exceptfds, timeout); 1525 // Clear everything (also on error) since their content is either set or 1526 // undefined. 1527 if (readfds) { 1528 dfsan_set_label(0, readfds, sizeof(fd_set)); 1529 } 1530 if (writefds) { 1531 dfsan_set_label(0, writefds, sizeof(fd_set)); 1532 } 1533 if (exceptfds) { 1534 dfsan_set_label(0, exceptfds, sizeof(fd_set)); 1535 } 1536 dfsan_set_label(0, timeout, sizeof(struct timeval)); 1537 *ret_label = 0; 1538 return ret; 1539 } 1540 1541 SANITIZER_INTERFACE_ATTRIBUTE 1542 int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds, 1543 fd_set *exceptfds, struct timeval *timeout, 1544 dfsan_label nfds_label, dfsan_label readfds_label, 1545 dfsan_label writefds_label, dfsan_label exceptfds_label, 1546 dfsan_label timeout_label, dfsan_label *ret_label, 1547 dfsan_origin nfds_origin, dfsan_origin readfds_origin, 1548 dfsan_origin writefds_origin, dfsan_origin exceptfds_origin, 1549 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1550 return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label, 1551 readfds_label, writefds_label, exceptfds_label, 1552 timeout_label, ret_label); 1553 } 1554 1555 SANITIZER_INTERFACE_ATTRIBUTE 1556 int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 1557 dfsan_label pid_label, 1558 dfsan_label cpusetsize_label, 1559 dfsan_label mask_label, dfsan_label *ret_label) { 1560 int ret = sched_getaffinity(pid, cpusetsize, mask); 1561 if (ret == 0) { 1562 dfsan_set_label(0, mask, cpusetsize); 1563 } 1564 *ret_label = 0; 1565 return ret; 1566 } 1567 1568 SANITIZER_INTERFACE_ATTRIBUTE 1569 int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask, 1570 dfsan_label pid_label, 1571 dfsan_label cpusetsize_label, 1572 dfsan_label mask_label, dfsan_label *ret_label, 1573 dfsan_origin pid_origin, 1574 dfsan_origin cpusetsize_origin, 1575 dfsan_origin mask_origin, 1576 dfsan_origin *ret_origin) { 1577 return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label, 1578 cpusetsize_label, mask_label, ret_label); 1579 } 1580 1581 SANITIZER_INTERFACE_ATTRIBUTE 1582 int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label, 1583 dfsan_label *ret_label) { 1584 int ret = sigemptyset(set); 1585 dfsan_set_label(0, set, sizeof(sigset_t)); 1586 *ret_label = 0; 1587 return ret; 1588 } 1589 1590 SANITIZER_INTERFACE_ATTRIBUTE 1591 int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label, 1592 dfsan_label *ret_label, dfsan_origin set_origin, 1593 dfsan_origin *ret_origin) { 1594 return __dfsw_sigemptyset(set, set_label, ret_label); 1595 } 1596 1597 class SignalHandlerScope { 1598 public: 1599 SignalHandlerScope() { 1600 if (DFsanThread *t = GetCurrentThread()) 1601 t->EnterSignalHandler(); 1602 } 1603 ~SignalHandlerScope() { 1604 if (DFsanThread *t = GetCurrentThread()) 1605 t->LeaveSignalHandler(); 1606 } 1607 }; 1608 1609 // Clear DFSan runtime TLS state at the end of a scope. 1610 // 1611 // Implementation must be async-signal-safe and use small data size, because 1612 // instances of this class may live on the signal handler stack. 1613 // 1614 // DFSan uses TLS to pass metadata of arguments and return values. When an 1615 // instrumented function accesses the TLS, if a signal callback happens, and the 1616 // callback calls other instrumented functions with updating the same TLS, the 1617 // TLS is in an inconsistent state after the callback ends. This may cause 1618 // either under-tainting or over-tainting. 1619 // 1620 // The current implementation simply resets TLS at restore. This prevents from 1621 // over-tainting. Although under-tainting may still happen, a taint flow can be 1622 // found eventually if we run a DFSan-instrumented program multiple times. The 1623 // alternative option is saving the entire TLS. However the TLS storage takes 1624 // 2k bytes, and signal calls could be nested. So it does not seem worth. 1625 class ScopedClearThreadLocalState { 1626 public: 1627 ScopedClearThreadLocalState() {} 1628 ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); } 1629 }; 1630 1631 // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls. 1632 const int kMaxSignals = 1024; 1633 static atomic_uintptr_t sigactions[kMaxSignals]; 1634 1635 static void SignalHandler(int signo) { 1636 SignalHandlerScope signal_handler_scope; 1637 ScopedClearThreadLocalState scoped_clear_tls; 1638 1639 // Clear shadows for all inputs provided by system. This is why DFSan 1640 // instrumentation generates a trampoline function to each function pointer, 1641 // and uses the trampoline to clear shadows. However sigaction does not use 1642 // a function pointer directly, so we have to do this manually. 1643 dfsan_clear_arg_tls(0, sizeof(dfsan_label)); 1644 1645 typedef void (*signal_cb)(int x); 1646 signal_cb cb = 1647 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1648 cb(signo); 1649 } 1650 1651 static void SignalAction(int signo, siginfo_t *si, void *uc) { 1652 SignalHandlerScope signal_handler_scope; 1653 ScopedClearThreadLocalState scoped_clear_tls; 1654 1655 // Clear shadows for all inputs provided by system. Similar to SignalHandler. 1656 dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label)); 1657 dfsan_set_label(0, si, sizeof(*si)); 1658 dfsan_set_label(0, uc, sizeof(ucontext_t)); 1659 1660 typedef void (*sigaction_cb)(int, siginfo_t *, void *); 1661 sigaction_cb cb = 1662 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1663 cb(signo, si, uc); 1664 } 1665 1666 SANITIZER_INTERFACE_ATTRIBUTE 1667 int __dfsw_sigaction(int signum, const struct sigaction *act, 1668 struct sigaction *oldact, dfsan_label signum_label, 1669 dfsan_label act_label, dfsan_label oldact_label, 1670 dfsan_label *ret_label) { 1671 CHECK_LT(signum, kMaxSignals); 1672 SignalSpinLocker lock; 1673 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1674 struct sigaction new_act; 1675 struct sigaction *pnew_act = act ? &new_act : nullptr; 1676 if (act) { 1677 internal_memcpy(pnew_act, act, sizeof(struct sigaction)); 1678 if (pnew_act->sa_flags & SA_SIGINFO) { 1679 uptr cb = (uptr)(pnew_act->sa_sigaction); 1680 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1681 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1682 pnew_act->sa_sigaction = SignalAction; 1683 } 1684 } else { 1685 uptr cb = (uptr)(pnew_act->sa_handler); 1686 if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) { 1687 atomic_store(&sigactions[signum], cb, memory_order_relaxed); 1688 pnew_act->sa_handler = SignalHandler; 1689 } 1690 } 1691 } 1692 1693 int ret = sigaction(signum, pnew_act, oldact); 1694 1695 if (ret == 0 && oldact) { 1696 if (oldact->sa_flags & SA_SIGINFO) { 1697 if (oldact->sa_sigaction == SignalAction) 1698 oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb; 1699 } else { 1700 if (oldact->sa_handler == SignalHandler) 1701 oldact->sa_handler = (decltype(oldact->sa_handler))old_cb; 1702 } 1703 } 1704 1705 if (oldact) { 1706 dfsan_set_label(0, oldact, sizeof(struct sigaction)); 1707 } 1708 *ret_label = 0; 1709 return ret; 1710 } 1711 1712 SANITIZER_INTERFACE_ATTRIBUTE 1713 int __dfso_sigaction(int signum, const struct sigaction *act, 1714 struct sigaction *oldact, dfsan_label signum_label, 1715 dfsan_label act_label, dfsan_label oldact_label, 1716 dfsan_label *ret_label, dfsan_origin signum_origin, 1717 dfsan_origin act_origin, dfsan_origin oldact_origin, 1718 dfsan_origin *ret_origin) { 1719 return __dfsw_sigaction(signum, act, oldact, signum_label, act_label, 1720 oldact_label, ret_label); 1721 } 1722 1723 static sighandler_t dfsan_signal(int signum, sighandler_t handler, 1724 dfsan_label *ret_label) { 1725 CHECK_LT(signum, kMaxSignals); 1726 SignalSpinLocker lock; 1727 uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed); 1728 if (handler != SIG_IGN && handler != SIG_DFL) { 1729 atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed); 1730 handler = &SignalHandler; 1731 } 1732 1733 sighandler_t ret = signal(signum, handler); 1734 1735 if (ret == SignalHandler) 1736 ret = (sighandler_t)old_cb; 1737 1738 *ret_label = 0; 1739 return ret; 1740 } 1741 1742 SANITIZER_INTERFACE_ATTRIBUTE 1743 sighandler_t __dfsw_signal(int signum, 1744 void *(*handler_trampoline)(void *, int, dfsan_label, 1745 dfsan_label *), 1746 sighandler_t handler, dfsan_label signum_label, 1747 dfsan_label handler_label, dfsan_label *ret_label) { 1748 return dfsan_signal(signum, handler, ret_label); 1749 } 1750 1751 SANITIZER_INTERFACE_ATTRIBUTE 1752 sighandler_t __dfso_signal( 1753 int signum, 1754 void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *, 1755 dfsan_origin, dfsan_origin *), 1756 sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label, 1757 dfsan_label *ret_label, dfsan_origin signum_origin, 1758 dfsan_origin handler_origin, dfsan_origin *ret_origin) { 1759 return dfsan_signal(signum, handler, ret_label); 1760 } 1761 1762 SANITIZER_INTERFACE_ATTRIBUTE 1763 int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1764 dfsan_label old_ss_label, dfsan_label *ret_label) { 1765 int ret = sigaltstack(ss, old_ss); 1766 if (ret != -1 && old_ss) 1767 dfsan_set_label(0, old_ss, sizeof(*old_ss)); 1768 *ret_label = 0; 1769 return ret; 1770 } 1771 1772 SANITIZER_INTERFACE_ATTRIBUTE 1773 int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label, 1774 dfsan_label old_ss_label, dfsan_label *ret_label, 1775 dfsan_origin ss_origin, dfsan_origin old_ss_origin, 1776 dfsan_origin *ret_origin) { 1777 return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label); 1778 } 1779 1780 SANITIZER_INTERFACE_ATTRIBUTE 1781 int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz, 1782 dfsan_label tv_label, dfsan_label tz_label, 1783 dfsan_label *ret_label) { 1784 int ret = gettimeofday(tv, tz); 1785 if (tv) { 1786 dfsan_set_label(0, tv, sizeof(struct timeval)); 1787 } 1788 if (tz) { 1789 dfsan_set_label(0, tz, sizeof(struct timezone)); 1790 } 1791 *ret_label = 0; 1792 return ret; 1793 } 1794 1795 SANITIZER_INTERFACE_ATTRIBUTE 1796 int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz, 1797 dfsan_label tv_label, dfsan_label tz_label, 1798 dfsan_label *ret_label, dfsan_origin tv_origin, 1799 dfsan_origin tz_origin, dfsan_origin *ret_origin) { 1800 return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label); 1801 } 1802 1803 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n, 1804 dfsan_label s_label, 1805 dfsan_label c_label, 1806 dfsan_label n_label, 1807 dfsan_label *ret_label) { 1808 void *ret = memchr(s, c, n); 1809 if (flags().strict_data_dependencies) { 1810 *ret_label = ret ? s_label : 0; 1811 } else { 1812 size_t len = 1813 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 1814 : n; 1815 *ret_label = 1816 dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label)); 1817 } 1818 return ret; 1819 } 1820 1821 SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr( 1822 void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label, 1823 dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin, 1824 dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) { 1825 void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label); 1826 if (flags().strict_data_dependencies) { 1827 if (ret) 1828 *ret_origin = s_origin; 1829 } else { 1830 size_t len = 1831 ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1 1832 : n; 1833 dfsan_origin o = dfsan_read_origin_of_first_taint(s, len); 1834 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 1835 } 1836 return ret; 1837 } 1838 1839 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c, 1840 dfsan_label s_label, 1841 dfsan_label c_label, 1842 dfsan_label *ret_label) { 1843 char *ret = strrchr(s, c); 1844 if (flags().strict_data_dependencies) { 1845 *ret_label = ret ? s_label : 0; 1846 } else { 1847 *ret_label = 1848 dfsan_union(dfsan_read_label(s, strlen(s) + 1), 1849 dfsan_union(s_label, c_label)); 1850 } 1851 1852 return ret; 1853 } 1854 1855 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr( 1856 char *s, int c, dfsan_label s_label, dfsan_label c_label, 1857 dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin, 1858 dfsan_origin *ret_origin) { 1859 char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label); 1860 if (flags().strict_data_dependencies) { 1861 if (ret) 1862 *ret_origin = s_origin; 1863 } else { 1864 size_t s_len = strlen(s) + 1; 1865 dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len); 1866 *ret_origin = o ? o : (s_label ? s_origin : c_origin); 1867 } 1868 1869 return ret; 1870 } 1871 1872 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle, 1873 dfsan_label haystack_label, 1874 dfsan_label needle_label, 1875 dfsan_label *ret_label) { 1876 char *ret = strstr(haystack, needle); 1877 if (flags().strict_data_dependencies) { 1878 *ret_label = ret ? haystack_label : 0; 1879 } else { 1880 size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1; 1881 *ret_label = 1882 dfsan_union(dfsan_read_label(haystack, len), 1883 dfsan_union(dfsan_read_label(needle, strlen(needle) + 1), 1884 dfsan_union(haystack_label, needle_label))); 1885 } 1886 1887 return ret; 1888 } 1889 1890 SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle, 1891 dfsan_label haystack_label, 1892 dfsan_label needle_label, 1893 dfsan_label *ret_label, 1894 dfsan_origin haystack_origin, 1895 dfsan_origin needle_origin, 1896 dfsan_origin *ret_origin) { 1897 char *ret = 1898 __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label); 1899 if (flags().strict_data_dependencies) { 1900 if (ret) 1901 *ret_origin = haystack_origin; 1902 } else { 1903 size_t needle_len = strlen(needle); 1904 size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1; 1905 dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len); 1906 if (o) { 1907 *ret_origin = o; 1908 } else { 1909 o = dfsan_read_origin_of_first_taint(needle, needle_len + 1); 1910 *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin); 1911 } 1912 } 1913 1914 return ret; 1915 } 1916 1917 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req, 1918 struct timespec *rem, 1919 dfsan_label req_label, 1920 dfsan_label rem_label, 1921 dfsan_label *ret_label) { 1922 int ret = nanosleep(req, rem); 1923 *ret_label = 0; 1924 if (ret == -1) { 1925 // Interrupted by a signal, rem is filled with the remaining time. 1926 dfsan_set_label(0, rem, sizeof(struct timespec)); 1927 } 1928 return ret; 1929 } 1930 1931 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep( 1932 const struct timespec *req, struct timespec *rem, dfsan_label req_label, 1933 dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin, 1934 dfsan_origin rem_origin, dfsan_origin *ret_origin) { 1935 return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label); 1936 } 1937 1938 static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) { 1939 dfsan_set_label(0, msg, sizeof(*msg)); 1940 dfsan_set_label(0, msg->msg_name, msg->msg_namelen); 1941 dfsan_set_label(0, msg->msg_control, msg->msg_controllen); 1942 for (size_t i = 0; bytes_written > 0; ++i) { 1943 assert(i < msg->msg_iovlen); 1944 struct iovec *iov = &msg->msg_iov[i]; 1945 size_t iov_written = 1946 bytes_written < iov->iov_len ? bytes_written : iov->iov_len; 1947 dfsan_set_label(0, iov->iov_base, iov_written); 1948 bytes_written -= iov_written; 1949 } 1950 } 1951 1952 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg( 1953 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, 1954 struct timespec *timeout, dfsan_label sockfd_label, 1955 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, 1956 dfsan_label timeout_label, dfsan_label *ret_label) { 1957 int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout); 1958 for (int i = 0; i < ret; ++i) { 1959 dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len)); 1960 clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr); 1961 } 1962 *ret_label = 0; 1963 return ret; 1964 } 1965 1966 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg( 1967 int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, 1968 struct timespec *timeout, dfsan_label sockfd_label, 1969 dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label, 1970 dfsan_label timeout_label, dfsan_label *ret_label, 1971 dfsan_origin sockfd_origin, dfsan_origin msgvec_origin, 1972 dfsan_origin vlen_origin, dfsan_origin flags_origin, 1973 dfsan_origin timeout_origin, dfsan_origin *ret_origin) { 1974 return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label, 1975 msgvec_label, vlen_label, flags_label, timeout_label, 1976 ret_label); 1977 } 1978 1979 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg( 1980 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, 1981 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) { 1982 ssize_t ret = recvmsg(sockfd, msg, flags); 1983 if (ret >= 0) 1984 clear_msghdr_labels(ret, msg); 1985 *ret_label = 0; 1986 return ret; 1987 } 1988 1989 SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg( 1990 int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label, 1991 dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label, 1992 dfsan_origin sockfd_origin, dfsan_origin msg_origin, 1993 dfsan_origin flags_origin, dfsan_origin *ret_origin) { 1994 return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label, 1995 flags_label, ret_label); 1996 } 1997 1998 SANITIZER_INTERFACE_ATTRIBUTE int 1999 __dfsw_socketpair(int domain, int type, int protocol, int sv[2], 2000 dfsan_label domain_label, dfsan_label type_label, 2001 dfsan_label protocol_label, dfsan_label sv_label, 2002 dfsan_label *ret_label) { 2003 int ret = socketpair(domain, type, protocol, sv); 2004 *ret_label = 0; 2005 if (ret == 0) { 2006 dfsan_set_label(0, sv, sizeof(*sv) * 2); 2007 } 2008 return ret; 2009 } 2010 2011 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair( 2012 int domain, int type, int protocol, int sv[2], dfsan_label domain_label, 2013 dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label, 2014 dfsan_label *ret_label, dfsan_origin domain_origin, 2015 dfsan_origin type_origin, dfsan_origin protocol_origin, 2016 dfsan_origin sv_origin, dfsan_origin *ret_origin) { 2017 return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label, 2018 protocol_label, sv_label, ret_label); 2019 } 2020 2021 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt( 2022 int sockfd, int level, int optname, void *optval, socklen_t *optlen, 2023 dfsan_label sockfd_label, dfsan_label level_label, 2024 dfsan_label optname_label, dfsan_label optval_label, 2025 dfsan_label optlen_label, dfsan_label *ret_label) { 2026 int ret = getsockopt(sockfd, level, optname, optval, optlen); 2027 if (ret != -1 && optval && optlen) { 2028 dfsan_set_label(0, optlen, sizeof(*optlen)); 2029 dfsan_set_label(0, optval, *optlen); 2030 } 2031 *ret_label = 0; 2032 return ret; 2033 } 2034 2035 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt( 2036 int sockfd, int level, int optname, void *optval, socklen_t *optlen, 2037 dfsan_label sockfd_label, dfsan_label level_label, 2038 dfsan_label optname_label, dfsan_label optval_label, 2039 dfsan_label optlen_label, dfsan_label *ret_label, 2040 dfsan_origin sockfd_origin, dfsan_origin level_origin, 2041 dfsan_origin optname_origin, dfsan_origin optval_origin, 2042 dfsan_origin optlen_origin, dfsan_origin *ret_origin) { 2043 return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label, 2044 level_label, optname_label, optval_label, 2045 optlen_label, ret_label); 2046 } 2047 2048 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname( 2049 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2050 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2051 dfsan_label *ret_label) { 2052 socklen_t origlen = addrlen ? *addrlen : 0; 2053 int ret = getsockname(sockfd, addr, addrlen); 2054 if (ret != -1 && addr && addrlen) { 2055 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 2056 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 2057 dfsan_set_label(0, addr, written_bytes); 2058 } 2059 *ret_label = 0; 2060 return ret; 2061 } 2062 2063 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname( 2064 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2065 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2066 dfsan_label *ret_label, dfsan_origin sockfd_origin, 2067 dfsan_origin addr_origin, dfsan_origin addrlen_origin, 2068 dfsan_origin *ret_origin) { 2069 return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label, 2070 addrlen_label, ret_label); 2071 } 2072 2073 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername( 2074 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2075 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2076 dfsan_label *ret_label) { 2077 socklen_t origlen = addrlen ? *addrlen : 0; 2078 int ret = getpeername(sockfd, addr, addrlen); 2079 if (ret != -1 && addr && addrlen) { 2080 socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen; 2081 dfsan_set_label(0, addrlen, sizeof(*addrlen)); 2082 dfsan_set_label(0, addr, written_bytes); 2083 } 2084 *ret_label = 0; 2085 return ret; 2086 } 2087 2088 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername( 2089 int sockfd, struct sockaddr *addr, socklen_t *addrlen, 2090 dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label, 2091 dfsan_label *ret_label, dfsan_origin sockfd_origin, 2092 dfsan_origin addr_origin, dfsan_origin addrlen_origin, 2093 dfsan_origin *ret_origin) { 2094 return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label, 2095 addrlen_label, ret_label); 2096 } 2097 2098 // Type of the trampoline function passed to the custom version of 2099 // dfsan_set_write_callback. 2100 typedef void (*write_trampoline_t)( 2101 void *callback, 2102 int fd, const void *buf, ssize_t count, 2103 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label); 2104 2105 typedef void (*write_origin_trampoline_t)( 2106 void *callback, int fd, const void *buf, ssize_t count, 2107 dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label, 2108 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin); 2109 2110 // Calls to dfsan_set_write_callback() set the values in this struct. 2111 // Calls to the custom version of write() read (and invoke) them. 2112 static struct { 2113 write_trampoline_t write_callback_trampoline = nullptr; 2114 void *write_callback = nullptr; 2115 } write_callback_info; 2116 2117 static struct { 2118 write_origin_trampoline_t write_callback_trampoline = nullptr; 2119 void *write_callback = nullptr; 2120 } write_origin_callback_info; 2121 2122 SANITIZER_INTERFACE_ATTRIBUTE void 2123 __dfsw_dfsan_set_write_callback( 2124 write_trampoline_t write_callback_trampoline, 2125 void *write_callback, 2126 dfsan_label write_callback_label, 2127 dfsan_label *ret_label) { 2128 write_callback_info.write_callback_trampoline = write_callback_trampoline; 2129 write_callback_info.write_callback = write_callback; 2130 } 2131 2132 SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback( 2133 write_origin_trampoline_t write_callback_trampoline, void *write_callback, 2134 dfsan_label write_callback_label, dfsan_label *ret_label, 2135 dfsan_origin write_callback_origin, dfsan_origin *ret_origin) { 2136 write_origin_callback_info.write_callback_trampoline = 2137 write_callback_trampoline; 2138 write_origin_callback_info.write_callback = write_callback; 2139 } 2140 2141 SANITIZER_INTERFACE_ATTRIBUTE int 2142 __dfsw_write(int fd, const void *buf, size_t count, 2143 dfsan_label fd_label, dfsan_label buf_label, 2144 dfsan_label count_label, dfsan_label *ret_label) { 2145 if (write_callback_info.write_callback) { 2146 write_callback_info.write_callback_trampoline( 2147 write_callback_info.write_callback, 2148 fd, buf, count, 2149 fd_label, buf_label, count_label); 2150 } 2151 2152 *ret_label = 0; 2153 return write(fd, buf, count); 2154 } 2155 2156 SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write( 2157 int fd, const void *buf, size_t count, dfsan_label fd_label, 2158 dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label, 2159 dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin, 2160 dfsan_origin *ret_origin) { 2161 if (write_origin_callback_info.write_callback) { 2162 write_origin_callback_info.write_callback_trampoline( 2163 write_origin_callback_info.write_callback, fd, buf, count, fd_label, 2164 buf_label, count_label, fd_origin, buf_origin, count_origin); 2165 } 2166 2167 *ret_label = 0; 2168 return write(fd, buf, count); 2169 } 2170 } // namespace __dfsan 2171 2172 // Type used to extract a dfsan_label with va_arg() 2173 typedef int dfsan_label_va; 2174 2175 // Formats a chunk either a constant string or a single format directive (e.g., 2176 // '%.3f'). 2177 struct Formatter { 2178 Formatter(char *str_, const char *fmt_, size_t size_) 2179 : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_), 2180 width(-1) {} 2181 2182 int format() { 2183 char *tmp_fmt = build_format_string(); 2184 int retval = 2185 snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt, 2186 0 /* used only to avoid warnings */); 2187 free(tmp_fmt); 2188 return retval; 2189 } 2190 2191 template <typename T> int format(T arg) { 2192 char *tmp_fmt = build_format_string(); 2193 int retval; 2194 if (width >= 0) { 2195 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 2196 tmp_fmt, width, arg); 2197 } else { 2198 retval = snprintf(str + str_off, str_off < size ? size - str_off : 0, 2199 tmp_fmt, arg); 2200 } 2201 free(tmp_fmt); 2202 return retval; 2203 } 2204 2205 char *build_format_string() { 2206 size_t fmt_size = fmt_cur - fmt_start + 1; 2207 char *new_fmt = (char *)malloc(fmt_size + 1); 2208 assert(new_fmt); 2209 internal_memcpy(new_fmt, fmt_start, fmt_size); 2210 new_fmt[fmt_size] = '\0'; 2211 return new_fmt; 2212 } 2213 2214 char *str_cur() { return str + str_off; } 2215 2216 size_t num_written_bytes(int retval) { 2217 if (retval < 0) { 2218 return 0; 2219 } 2220 2221 size_t num_avail = str_off < size ? size - str_off : 0; 2222 if (num_avail == 0) { 2223 return 0; 2224 } 2225 2226 size_t num_written = retval; 2227 // A return value of {v,}snprintf of size or more means that the output was 2228 // truncated. 2229 if (num_written >= num_avail) { 2230 num_written -= num_avail; 2231 } 2232 2233 return num_written; 2234 } 2235 2236 char *str; 2237 size_t str_off; 2238 size_t size; 2239 const char *fmt_start; 2240 const char *fmt_cur; 2241 int width; 2242 }; 2243 2244 // Formats the input and propagates the input labels to the output. The output 2245 // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and 2246 // 'ap' are the format string and the list of arguments for formatting. Returns 2247 // the return value vsnprintf would return. 2248 // 2249 // The function tokenizes the format string in chunks representing either a 2250 // constant string or a single format directive (e.g., '%.3f') and formats each 2251 // chunk independently into the output string. This approach allows to figure 2252 // out which bytes of the output string depends on which argument and thus to 2253 // propagate labels more precisely. 2254 // 2255 // WARNING: This implementation does not support conversion specifiers with 2256 // positional arguments. 2257 static int format_buffer(char *str, size_t size, const char *fmt, 2258 dfsan_label *va_labels, dfsan_label *ret_label, 2259 dfsan_origin *va_origins, dfsan_origin *ret_origin, 2260 va_list ap) { 2261 Formatter formatter(str, fmt, size); 2262 2263 while (*formatter.fmt_cur) { 2264 formatter.fmt_start = formatter.fmt_cur; 2265 formatter.width = -1; 2266 int retval = 0; 2267 2268 if (*formatter.fmt_cur != '%') { 2269 // Ordinary character. Consume all the characters until a '%' or the end 2270 // of the string. 2271 for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%'; 2272 ++formatter.fmt_cur) {} 2273 retval = formatter.format(); 2274 dfsan_set_label(0, formatter.str_cur(), 2275 formatter.num_written_bytes(retval)); 2276 } else { 2277 // Conversion directive. Consume all the characters until a conversion 2278 // specifier or the end of the string. 2279 bool end_fmt = false; 2280 for (; *formatter.fmt_cur && !end_fmt; ) { 2281 switch (*++formatter.fmt_cur) { 2282 case 'd': 2283 case 'i': 2284 case 'o': 2285 case 'u': 2286 case 'x': 2287 case 'X': 2288 switch (*(formatter.fmt_cur - 1)) { 2289 case 'h': 2290 // Also covers the 'hh' case (since the size of the arg is still 2291 // an int). 2292 retval = formatter.format(va_arg(ap, int)); 2293 break; 2294 case 'l': 2295 if (formatter.fmt_cur - formatter.fmt_start >= 2 && 2296 *(formatter.fmt_cur - 2) == 'l') { 2297 retval = formatter.format(va_arg(ap, long long int)); 2298 } else { 2299 retval = formatter.format(va_arg(ap, long int)); 2300 } 2301 break; 2302 case 'q': 2303 retval = formatter.format(va_arg(ap, long long int)); 2304 break; 2305 case 'j': 2306 retval = formatter.format(va_arg(ap, intmax_t)); 2307 break; 2308 case 'z': 2309 case 't': 2310 retval = formatter.format(va_arg(ap, size_t)); 2311 break; 2312 default: 2313 retval = formatter.format(va_arg(ap, int)); 2314 } 2315 if (va_origins == nullptr) 2316 dfsan_set_label(*va_labels++, formatter.str_cur(), 2317 formatter.num_written_bytes(retval)); 2318 else 2319 dfsan_set_label_origin(*va_labels++, *va_origins++, 2320 formatter.str_cur(), 2321 formatter.num_written_bytes(retval)); 2322 end_fmt = true; 2323 break; 2324 2325 case 'a': 2326 case 'A': 2327 case 'e': 2328 case 'E': 2329 case 'f': 2330 case 'F': 2331 case 'g': 2332 case 'G': 2333 if (*(formatter.fmt_cur - 1) == 'L') { 2334 retval = formatter.format(va_arg(ap, long double)); 2335 } else { 2336 retval = formatter.format(va_arg(ap, double)); 2337 } 2338 if (va_origins == nullptr) 2339 dfsan_set_label(*va_labels++, formatter.str_cur(), 2340 formatter.num_written_bytes(retval)); 2341 else 2342 dfsan_set_label_origin(*va_labels++, *va_origins++, 2343 formatter.str_cur(), 2344 formatter.num_written_bytes(retval)); 2345 end_fmt = true; 2346 break; 2347 2348 case 'c': 2349 retval = formatter.format(va_arg(ap, int)); 2350 if (va_origins == nullptr) 2351 dfsan_set_label(*va_labels++, formatter.str_cur(), 2352 formatter.num_written_bytes(retval)); 2353 else 2354 dfsan_set_label_origin(*va_labels++, *va_origins++, 2355 formatter.str_cur(), 2356 formatter.num_written_bytes(retval)); 2357 end_fmt = true; 2358 break; 2359 2360 case 's': { 2361 char *arg = va_arg(ap, char *); 2362 retval = formatter.format(arg); 2363 if (va_origins) { 2364 va_origins++; 2365 dfsan_mem_origin_transfer(formatter.str_cur(), arg, 2366 formatter.num_written_bytes(retval)); 2367 } 2368 va_labels++; 2369 internal_memcpy(shadow_for(formatter.str_cur()), shadow_for(arg), 2370 sizeof(dfsan_label) * 2371 formatter.num_written_bytes(retval)); 2372 end_fmt = true; 2373 break; 2374 } 2375 2376 case 'p': 2377 retval = formatter.format(va_arg(ap, void *)); 2378 if (va_origins == nullptr) 2379 dfsan_set_label(*va_labels++, formatter.str_cur(), 2380 formatter.num_written_bytes(retval)); 2381 else 2382 dfsan_set_label_origin(*va_labels++, *va_origins++, 2383 formatter.str_cur(), 2384 formatter.num_written_bytes(retval)); 2385 end_fmt = true; 2386 break; 2387 2388 case 'n': { 2389 int *ptr = va_arg(ap, int *); 2390 *ptr = (int)formatter.str_off; 2391 va_labels++; 2392 if (va_origins) 2393 va_origins++; 2394 dfsan_set_label(0, ptr, sizeof(ptr)); 2395 end_fmt = true; 2396 break; 2397 } 2398 2399 case '%': 2400 retval = formatter.format(); 2401 dfsan_set_label(0, formatter.str_cur(), 2402 formatter.num_written_bytes(retval)); 2403 end_fmt = true; 2404 break; 2405 2406 case '*': 2407 formatter.width = va_arg(ap, int); 2408 va_labels++; 2409 if (va_origins) 2410 va_origins++; 2411 break; 2412 2413 default: 2414 break; 2415 } 2416 } 2417 } 2418 2419 if (retval < 0) { 2420 return retval; 2421 } 2422 2423 formatter.fmt_cur++; 2424 formatter.str_off += retval; 2425 } 2426 2427 *ret_label = 0; 2428 if (ret_origin) 2429 *ret_origin = 0; 2430 2431 // Number of bytes written in total. 2432 return formatter.str_off; 2433 } 2434 2435 extern "C" { 2436 SANITIZER_INTERFACE_ATTRIBUTE 2437 int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label, 2438 dfsan_label format_label, dfsan_label *va_labels, 2439 dfsan_label *ret_label, ...) { 2440 va_list ap; 2441 va_start(ap, ret_label); 2442 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr, 2443 nullptr, ap); 2444 va_end(ap); 2445 return ret; 2446 } 2447 2448 SANITIZER_INTERFACE_ATTRIBUTE 2449 int __dfso_sprintf(char *str, const char *format, dfsan_label str_label, 2450 dfsan_label format_label, dfsan_label *va_labels, 2451 dfsan_label *ret_label, dfsan_origin str_origin, 2452 dfsan_origin format_origin, dfsan_origin *va_origins, 2453 dfsan_origin *ret_origin, ...) { 2454 va_list ap; 2455 va_start(ap, ret_origin); 2456 int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins, 2457 ret_origin, ap); 2458 va_end(ap); 2459 return ret; 2460 } 2461 2462 SANITIZER_INTERFACE_ATTRIBUTE 2463 int __dfsw_snprintf(char *str, size_t size, const char *format, 2464 dfsan_label str_label, dfsan_label size_label, 2465 dfsan_label format_label, dfsan_label *va_labels, 2466 dfsan_label *ret_label, ...) { 2467 va_list ap; 2468 va_start(ap, ret_label); 2469 int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr, 2470 nullptr, ap); 2471 va_end(ap); 2472 return ret; 2473 } 2474 2475 SANITIZER_INTERFACE_ATTRIBUTE 2476 int __dfso_snprintf(char *str, size_t size, const char *format, 2477 dfsan_label str_label, dfsan_label size_label, 2478 dfsan_label format_label, dfsan_label *va_labels, 2479 dfsan_label *ret_label, dfsan_origin str_origin, 2480 dfsan_origin size_origin, dfsan_origin format_origin, 2481 dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) { 2482 va_list ap; 2483 va_start(ap, ret_origin); 2484 int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins, 2485 ret_origin, ap); 2486 va_end(ap); 2487 return ret; 2488 } 2489 2490 static void BeforeFork() { 2491 StackDepotLockAll(); 2492 GetChainedOriginDepot()->LockAll(); 2493 } 2494 2495 static void AfterFork() { 2496 GetChainedOriginDepot()->UnlockAll(); 2497 StackDepotUnlockAll(); 2498 } 2499 2500 SANITIZER_INTERFACE_ATTRIBUTE 2501 pid_t __dfsw_fork(dfsan_label *ret_label) { 2502 pid_t pid = fork(); 2503 *ret_label = 0; 2504 return pid; 2505 } 2506 2507 SANITIZER_INTERFACE_ATTRIBUTE 2508 pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) { 2509 BeforeFork(); 2510 pid_t pid = __dfsw_fork(ret_label); 2511 AfterFork(); 2512 return pid; 2513 } 2514 2515 // Default empty implementations (weak). Users should redefine them. 2516 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {} 2517 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *, 2518 u32 *) {} 2519 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg, 2520 const uptr *end) {} 2521 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {} 2522 2523 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {} 2524 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {} 2525 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {} 2526 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {} 2527 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {} 2528 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1, 2529 void) {} 2530 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2, 2531 void) {} 2532 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4, 2533 void) {} 2534 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8, 2535 void) {} 2536 SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {} 2537 } // extern "C" 2538