brintos

brintos / llvm-project-archived public Read only

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