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