123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529 |
- //===-- dfsan_custom.cpp --------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file is a part of DataFlowSanitizer.
- //
- // This file defines the custom functions listed in done_abilist.txt.
- //===----------------------------------------------------------------------===//
- #include <arpa/inet.h>
- #include <assert.h>
- #include <ctype.h>
- #include <dlfcn.h>
- #include <link.h>
- #include <poll.h>
- #include <pthread.h>
- #include <pwd.h>
- #include <sched.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/epoll.h>
- #include <sys/resource.h>
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <time.h>
- #include <unistd.h>
- #include "dfsan/dfsan.h"
- #include "dfsan/dfsan_chained_origin_depot.h"
- #include "dfsan/dfsan_flags.h"
- #include "dfsan/dfsan_thread.h"
- #include "sanitizer_common/sanitizer_common.h"
- #include "sanitizer_common/sanitizer_internal_defs.h"
- #include "sanitizer_common/sanitizer_linux.h"
- #include "sanitizer_common/sanitizer_stackdepot.h"
- using namespace __dfsan;
- #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) \
- do { \
- if (f) \
- f(__VA_ARGS__); \
- } while (false)
- #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
- SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);
- // Async-safe, non-reentrant spin lock.
- class SignalSpinLocker {
- public:
- SignalSpinLocker() {
- sigset_t all_set;
- sigfillset(&all_set);
- pthread_sigmask(SIG_SETMASK, &all_set, &saved_thread_mask_);
- sigactions_mu.Lock();
- }
- ~SignalSpinLocker() {
- sigactions_mu.Unlock();
- pthread_sigmask(SIG_SETMASK, &saved_thread_mask_, nullptr);
- }
- private:
- static StaticSpinMutex sigactions_mu;
- sigset_t saved_thread_mask_;
- SignalSpinLocker(const SignalSpinLocker &) = delete;
- SignalSpinLocker &operator=(const SignalSpinLocker &) = delete;
- };
- StaticSpinMutex SignalSpinLocker::sigactions_mu;
- extern "C" {
- SANITIZER_INTERFACE_ATTRIBUTE int
- __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label,
- dfsan_label buf_label, dfsan_label *ret_label) {
- int ret = stat(path, buf);
- if (ret == 0)
- dfsan_set_label(0, buf, sizeof(struct stat));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat(
- const char *path, struct stat *buf, dfsan_label path_label,
- dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin,
- dfsan_origin buf_origin, dfsan_origin *ret_origin) {
- int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf,
- dfsan_label fd_label,
- dfsan_label buf_label,
- dfsan_label *ret_label) {
- int ret = fstat(fd, buf);
- if (ret == 0)
- dfsan_set_label(0, buf, sizeof(struct stat));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat(
- int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label,
- dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
- dfsan_origin *ret_origin) {
- int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label);
- return ret;
- }
- static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read,
- dfsan_label s_label, dfsan_label c_label,
- dfsan_label *ret_label) {
- char *match_pos = nullptr;
- for (size_t i = 0;; ++i) {
- if (s[i] == c || s[i] == 0) {
- // If s[i] is the \0 at the end of the string, and \0 is not the
- // character we are searching for, then return null.
- *bytes_read = i + 1;
- match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast<char *>(s + i);
- break;
- }
- }
- if (flags().strict_data_dependencies)
- *ret_label = s_label;
- else
- *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read),
- dfsan_union(s_label, c_label));
- return match_pos;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,
- dfsan_label s_label,
- dfsan_label c_label,
- dfsan_label *ret_label) {
- size_t bytes_read;
- return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr(
- const char *s, int c, dfsan_label s_label, dfsan_label c_label,
- dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
- dfsan_origin *ret_origin) {
- size_t bytes_read;
- char *r =
- dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label);
- if (flags().strict_data_dependencies) {
- *ret_origin = s_origin;
- } else if (*ret_label) {
- dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read);
- *ret_origin = o ? o : (s_label ? s_origin : c_origin);
- }
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s,
- const char *accept,
- dfsan_label s_label,
- dfsan_label accept_label,
- dfsan_label *ret_label) {
- const char *ret = strpbrk(s, accept);
- if (flags().strict_data_dependencies) {
- *ret_label = ret ? s_label : 0;
- } else {
- size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1;
- *ret_label =
- dfsan_union(dfsan_read_label(s, s_bytes_read),
- dfsan_union(dfsan_read_label(accept, strlen(accept) + 1),
- dfsan_union(s_label, accept_label)));
- }
- return const_cast<char *>(ret);
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk(
- const char *s, const char *accept, dfsan_label s_label,
- dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin,
- dfsan_origin accept_origin, dfsan_origin *ret_origin) {
- const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label);
- if (flags().strict_data_dependencies) {
- if (ret)
- *ret_origin = s_origin;
- } else {
- if (*ret_label) {
- size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1;
- dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read);
- if (o) {
- *ret_origin = o;
- } else {
- o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1);
- *ret_origin = o ? o : (s_label ? s_origin : accept_origin);
- }
- }
- }
- return const_cast<char *>(ret);
- }
- static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n,
- size_t *bytes_read) {
- const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
- for (size_t i = 0; i != n; ++i) {
- if (cs1[i] != cs2[i]) {
- *bytes_read = i + 1;
- return cs1[i] - cs2[i];
- }
- }
- *bytes_read = n;
- return 0;
- }
- static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2,
- size_t pos) {
- if (flags().strict_data_dependencies)
- return 0;
- return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos));
- }
- static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos,
- dfsan_label *ret_label,
- dfsan_origin *ret_origin) {
- *ret_label = dfsan_get_memcmp_label(s1, s2, pos);
- if (*ret_label == 0)
- return;
- dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos);
- *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos);
- }
- static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n,
- dfsan_label *ret_label) {
- size_t bytes_read;
- int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
- *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
- return r;
- }
- static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n,
- dfsan_label *ret_label,
- dfsan_origin *ret_origin) {
- size_t bytes_read;
- int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
- dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
- return r;
- }
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc,
- const void *s1, const void *s2, size_t n,
- dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label n_label)
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc,
- const void *s1, const void *s2, size_t n,
- dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label n_label, dfsan_origin s1_origin,
- dfsan_origin s2_origin, dfsan_origin n_origin)
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
- size_t n, dfsan_label s1_label,
- dfsan_label s2_label,
- dfsan_label n_label,
- dfsan_label *ret_label) {
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n,
- s1_label, s2_label, n_label);
- return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp(
- const void *s1, const void *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1,
- s2, n, s1_label, s2_label, n_label, s1_origin,
- s2_origin, n_origin);
- return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2,
- size_t n, dfsan_label s1_label,
- dfsan_label s2_label,
- dfsan_label n_label,
- dfsan_label *ret_label) {
- return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp(
- const void *s1, const void *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
- }
- // When n == 0, compare strings without byte limit.
- // When n > 0, compare the first (at most) n bytes of s1 and s2.
- static int dfsan_strncmp(const char *s1, const char *s2, size_t n,
- size_t *bytes_read) {
- for (size_t i = 0;; ++i) {
- if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) {
- *bytes_read = i + 1;
- return s1[i] - s2[i];
- }
- }
- }
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc,
- const char *s1, const char *s2,
- dfsan_label s1_label, dfsan_label s2_label)
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc,
- const char *s1, const char *s2,
- dfsan_label s1_label, dfsan_label s2_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin)
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,
- dfsan_label s1_label,
- dfsan_label s2_label,
- dfsan_label *ret_label) {
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2,
- s1_label, s2_label);
- size_t bytes_read;
- int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
- *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp(
- const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
- dfsan_origin *ret_origin) {
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1,
- s2, s1_label, s2_label, s1_origin, s2_origin);
- size_t bytes_read;
- int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
- dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
- return r;
- }
- // When n == 0, compare strings without byte limit.
- // When n > 0, compare the first (at most) n bytes of s1 and s2.
- static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n,
- size_t *bytes_read) {
- for (size_t i = 0;; ++i) {
- char s1_lower = tolower(s1[i]);
- char s2_lower = tolower(s2[i]);
- if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 ||
- (n > 0 && i == n - 1)) {
- *bytes_read = i + 1;
- return s1_lower - s2_lower;
- }
- }
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1,
- const char *s2,
- dfsan_label s1_label,
- dfsan_label s2_label,
- dfsan_label *ret_label) {
- size_t bytes_read;
- int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
- *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp(
- const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
- dfsan_origin *ret_origin) {
- size_t bytes_read;
- int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
- dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
- return r;
- }
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,
- const char *s1, const char *s2, size_t n,
- dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label n_label)
- DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc,
- const char *s1, const char *s2, size_t n,
- dfsan_label s1_label, dfsan_label s2_label,
- dfsan_label n_label, dfsan_origin s1_origin,
- dfsan_origin s2_origin, dfsan_origin n_origin)
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
- size_t n, dfsan_label s1_label,
- dfsan_label s2_label,
- dfsan_label n_label,
- dfsan_label *ret_label) {
- if (n == 0) {
- *ret_label = 0;
- return 0;
- }
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2,
- n, s1_label, s2_label, n_label);
- size_t bytes_read;
- int r = dfsan_strncmp(s1, s2, n, &bytes_read);
- *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp(
- const char *s1, const char *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- if (n == 0) {
- *ret_label = 0;
- return 0;
- }
- CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(),
- s1, s2, n, s1_label, s2_label, n_label, s1_origin,
- s2_origin, n_origin);
- size_t bytes_read;
- int r = dfsan_strncmp(s1, s2, n, &bytes_read);
- dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp(
- const char *s1, const char *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) {
- if (n == 0) {
- *ret_label = 0;
- return 0;
- }
- size_t bytes_read;
- int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
- *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp(
- const char *s1, const char *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- if (n == 0) {
- *ret_label = 0;
- return 0;
- }
- size_t bytes_read;
- int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
- dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
- return r;
- }
- SANITIZER_INTERFACE_ATTRIBUTE size_t
- __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
- size_t ret = strlen(s);
- if (flags().strict_data_dependencies) {
- *ret_label = 0;
- } else {
- *ret_label = dfsan_read_label(s, ret + 1);
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE size_t __dfso_strlen(const char *s,
- dfsan_label s_label,
- dfsan_label *ret_label,
- dfsan_origin s_origin,
- dfsan_origin *ret_origin) {
- size_t ret = __dfsw_strlen(s, s_label, ret_label);
- if (!flags().strict_data_dependencies)
- *ret_origin = dfsan_read_origin_of_first_taint(s, ret + 1);
- return ret;
- }
- static void *dfsan_memmove(void *dest, const void *src, size_t n) {
- dfsan_label *sdest = shadow_for(dest);
- const dfsan_label *ssrc = shadow_for(src);
- internal_memmove((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label));
- return internal_memmove(dest, src, n);
- }
- static void *dfsan_memmove_with_origin(void *dest, const void *src, size_t n) {
- dfsan_mem_origin_transfer(dest, src, n);
- return dfsan_memmove(dest, src, n);
- }
- static void *dfsan_memcpy(void *dest, const void *src, size_t n) {
- dfsan_mem_shadow_transfer(dest, src, n);
- return internal_memcpy(dest, src, n);
- }
- static void *dfsan_memcpy_with_origin(void *dest, const void *src, size_t n) {
- dfsan_mem_origin_transfer(dest, src, n);
- return dfsan_memcpy(dest, src, n);
- }
- static void dfsan_memset(void *s, int c, dfsan_label c_label, size_t n) {
- internal_memset(s, c, n);
- dfsan_set_label(c_label, s, n);
- }
- static void dfsan_memset_with_origin(void *s, int c, dfsan_label c_label,
- dfsan_origin c_origin, size_t n) {
- internal_memset(s, c, n);
- dfsan_set_label_origin(c_label, c_origin, s, n);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfsw_memcpy(void *dest, const void *src, size_t n,
- dfsan_label dest_label, dfsan_label src_label,
- dfsan_label n_label, dfsan_label *ret_label) {
- *ret_label = dest_label;
- return dfsan_memcpy(dest, src, n);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfso_memcpy(void *dest, const void *src, size_t n,
- dfsan_label dest_label, dfsan_label src_label,
- dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin dest_origin, dfsan_origin src_origin,
- dfsan_origin n_origin, dfsan_origin *ret_origin) {
- *ret_label = dest_label;
- *ret_origin = dest_origin;
- return dfsan_memcpy_with_origin(dest, src, n);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfsw_memmove(void *dest, const void *src, size_t n,
- dfsan_label dest_label, dfsan_label src_label,
- dfsan_label n_label, dfsan_label *ret_label) {
- *ret_label = dest_label;
- return dfsan_memmove(dest, src, n);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfso_memmove(void *dest, const void *src, size_t n,
- dfsan_label dest_label, dfsan_label src_label,
- dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin dest_origin, dfsan_origin src_origin,
- dfsan_origin n_origin, dfsan_origin *ret_origin) {
- *ret_label = dest_label;
- *ret_origin = dest_origin;
- return dfsan_memmove_with_origin(dest, src, n);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfsw_memset(void *s, int c, size_t n,
- dfsan_label s_label, dfsan_label c_label,
- dfsan_label n_label, dfsan_label *ret_label) {
- dfsan_memset(s, c, c_label, n);
- *ret_label = s_label;
- return s;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- void *__dfso_memset(void *s, int c, size_t n, dfsan_label s_label,
- dfsan_label c_label, dfsan_label n_label,
- dfsan_label *ret_label, dfsan_origin s_origin,
- dfsan_origin c_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- dfsan_memset_with_origin(s, c, c_label, c_origin, n);
- *ret_label = s_label;
- *ret_origin = s_origin;
- return s;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcat(char *dest, const char *src,
- dfsan_label dest_label,
- dfsan_label src_label,
- dfsan_label *ret_label) {
- size_t dest_len = strlen(dest);
- char *ret = strcat(dest, src);
- dfsan_mem_shadow_transfer(dest + dest_len, src, strlen(src));
- *ret_label = dest_label;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strcat(
- char *dest, const char *src, dfsan_label dest_label, dfsan_label src_label,
- dfsan_label *ret_label, dfsan_origin dest_origin, dfsan_origin src_origin,
- dfsan_origin *ret_origin) {
- size_t dest_len = strlen(dest);
- char *ret = strcat(dest, src);
- size_t src_len = strlen(src);
- dfsan_mem_origin_transfer(dest + dest_len, src, src_len);
- dfsan_mem_shadow_transfer(dest + dest_len, src, src_len);
- *ret_label = dest_label;
- *ret_origin = dest_origin;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *
- __dfsw_strdup(const char *s, dfsan_label s_label, dfsan_label *ret_label) {
- size_t len = strlen(s);
- void *p = malloc(len+1);
- dfsan_memcpy(p, s, len+1);
- *ret_label = 0;
- return static_cast<char *>(p);
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strdup(const char *s,
- dfsan_label s_label,
- dfsan_label *ret_label,
- dfsan_origin s_origin,
- dfsan_origin *ret_origin) {
- size_t len = strlen(s);
- void *p = malloc(len + 1);
- dfsan_memcpy_with_origin(p, s, len + 1);
- *ret_label = 0;
- return static_cast<char *>(p);
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *
- __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label,
- dfsan_label *ret_label) {
- size_t len = strlen(s2);
- if (len < n) {
- dfsan_memcpy(s1, s2, len+1);
- dfsan_memset(s1+len+1, 0, 0, n-len-1);
- } else {
- dfsan_memcpy(s1, s2, n);
- }
- *ret_label = s1_label;
- return s1;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strncpy(
- char *s1, const char *s2, size_t n, dfsan_label s1_label,
- dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
- dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
- dfsan_origin *ret_origin) {
- size_t len = strlen(s2);
- if (len < n) {
- dfsan_memcpy_with_origin(s1, s2, len + 1);
- dfsan_memset_with_origin(s1 + len + 1, 0, 0, 0, n - len - 1);
- } else {
- dfsan_memcpy_with_origin(s1, s2, n);
- }
- *ret_label = s1_label;
- *ret_origin = s1_origin;
- return s1;
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t
- __dfsw_pread(int fd, void *buf, size_t count, off_t offset,
- dfsan_label fd_label, dfsan_label buf_label,
- dfsan_label count_label, dfsan_label offset_label,
- dfsan_label *ret_label) {
- ssize_t ret = pread(fd, buf, count, offset);
- if (ret > 0)
- dfsan_set_label(0, buf, ret);
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_pread(
- int fd, void *buf, size_t count, off_t offset, dfsan_label fd_label,
- dfsan_label buf_label, dfsan_label count_label, dfsan_label offset_label,
- dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
- dfsan_origin count_origin, dfsan_label offset_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_pread(fd, buf, count, offset, fd_label, buf_label, count_label,
- offset_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t
- __dfsw_read(int fd, void *buf, size_t count,
- dfsan_label fd_label, dfsan_label buf_label,
- dfsan_label count_label,
- dfsan_label *ret_label) {
- ssize_t ret = read(fd, buf, count);
- if (ret > 0)
- dfsan_set_label(0, buf, ret);
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_read(
- int fd, void *buf, size_t count, dfsan_label fd_label,
- dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
- dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_read(fd, buf, count, fd_label, buf_label, count_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_clock_gettime(clockid_t clk_id,
- struct timespec *tp,
- dfsan_label clk_id_label,
- dfsan_label tp_label,
- dfsan_label *ret_label) {
- int ret = clock_gettime(clk_id, tp);
- if (ret == 0)
- dfsan_set_label(0, tp, sizeof(struct timespec));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_clock_gettime(
- clockid_t clk_id, struct timespec *tp, dfsan_label clk_id_label,
- dfsan_label tp_label, dfsan_label *ret_label, dfsan_origin clk_id_origin,
- dfsan_origin tp_origin, dfsan_origin *ret_origin) {
- return __dfsw_clock_gettime(clk_id, tp, clk_id_label, tp_label, ret_label);
- }
- static void dfsan_set_zero_label(const void *ptr, uptr size) {
- dfsan_set_label(0, const_cast<void *>(ptr), size);
- }
- // dlopen() ultimately calls mmap() down inside the loader, which generally
- // doesn't participate in dynamic symbol resolution. Therefore we won't
- // intercept its calls to mmap, and we have to hook it here.
- SANITIZER_INTERFACE_ATTRIBUTE void *
- __dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
- dfsan_label flag_label, dfsan_label *ret_label) {
- void *handle = dlopen(filename, flag);
- link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
- if (map)
- ForEachMappedRegion(map, dfsan_set_zero_label);
- *ret_label = 0;
- return handle;
- }
- SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_dlopen(
- const char *filename, int flag, dfsan_label filename_label,
- dfsan_label flag_label, dfsan_label *ret_label,
- dfsan_origin filename_origin, dfsan_origin flag_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_dlopen(filename, flag, filename_label, flag_label, ret_label);
- }
- static void *DFsanThreadStartFunc(void *arg) {
- DFsanThread *t = (DFsanThread *)arg;
- SetCurrentThread(t);
- t->Init();
- SetSigProcMask(&t->starting_sigset_, nullptr);
- return t->ThreadStart();
- }
- static int dfsan_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
- void *start_routine_trampoline,
- void *start_routine, void *arg,
- dfsan_label *ret_label,
- bool track_origins = false) {
- pthread_attr_t myattr;
- if (!attr) {
- pthread_attr_init(&myattr);
- attr = &myattr;
- }
- // Ensure that the thread stack is large enough to hold all TLS data.
- AdjustStackSize((void *)(const_cast<pthread_attr_t *>(attr)));
- DFsanThread *t =
- DFsanThread::Create(start_routine_trampoline,
- (thread_callback_t)start_routine, arg, track_origins);
- ScopedBlockSignals block(&t->starting_sigset_);
- int res = pthread_create(thread, attr, DFsanThreadStartFunc, t);
- if (attr == &myattr)
- pthread_attr_destroy(&myattr);
- *ret_label = 0;
- return res;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_create(
- pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine_trampoline)(void *, void *, dfsan_label,
- dfsan_label *),
- void *start_routine, void *arg, dfsan_label thread_label,
- dfsan_label attr_label, dfsan_label start_routine_label,
- dfsan_label arg_label, dfsan_label *ret_label) {
- return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline,
- start_routine, arg, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_create(
- pthread_t *thread, const pthread_attr_t *attr,
- void *(*start_routine_trampoline)(void *, void *, dfsan_label,
- dfsan_label *, dfsan_origin,
- dfsan_origin *),
- void *start_routine, void *arg, dfsan_label thread_label,
- dfsan_label attr_label, dfsan_label start_routine_label,
- dfsan_label arg_label, dfsan_label *ret_label, dfsan_origin thread_origin,
- dfsan_origin attr_origin, dfsan_origin start_routine_origin,
- dfsan_origin arg_origin, dfsan_origin *ret_origin) {
- return dfsan_pthread_create(thread, attr, (void *)start_routine_trampoline,
- start_routine, arg, ret_label, true);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_pthread_join(pthread_t thread,
- void **retval,
- dfsan_label thread_label,
- dfsan_label retval_label,
- dfsan_label *ret_label) {
- int ret = pthread_join(thread, retval);
- if (ret == 0 && retval)
- dfsan_set_label(0, retval, sizeof(*retval));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_pthread_join(
- pthread_t thread, void **retval, dfsan_label thread_label,
- dfsan_label retval_label, dfsan_label *ret_label,
- dfsan_origin thread_origin, dfsan_origin retval_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_pthread_join(thread, retval, thread_label, retval_label,
- ret_label);
- }
- struct dl_iterate_phdr_info {
- int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
- size_t size, void *data, dfsan_label info_label,
- dfsan_label size_label, dfsan_label data_label,
- dfsan_label *ret_label);
- void *callback;
- void *data;
- };
- struct dl_iterate_phdr_origin_info {
- int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
- size_t size, void *data, dfsan_label info_label,
- dfsan_label size_label, dfsan_label data_label,
- dfsan_label *ret_label, dfsan_origin info_origin,
- dfsan_origin size_origin, dfsan_origin data_origin,
- dfsan_origin *ret_origin);
- void *callback;
- void *data;
- };
- int dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) {
- dl_iterate_phdr_info *dipi = (dl_iterate_phdr_info *)data;
- dfsan_set_label(0, *info);
- dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
- strlen(info->dlpi_name) + 1);
- dfsan_set_label(
- 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
- sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
- dfsan_label ret_label;
- return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,
- 0, &ret_label);
- }
- int dl_iterate_phdr_origin_cb(struct dl_phdr_info *info, size_t size,
- void *data) {
- dl_iterate_phdr_origin_info *dipi = (dl_iterate_phdr_origin_info *)data;
- dfsan_set_label(0, *info);
- dfsan_set_label(0, const_cast<char *>(info->dlpi_name),
- strlen(info->dlpi_name) + 1);
- dfsan_set_label(
- 0, const_cast<char *>(reinterpret_cast<const char *>(info->dlpi_phdr)),
- sizeof(*info->dlpi_phdr) * info->dlpi_phnum);
- dfsan_label ret_label;
- dfsan_origin ret_origin;
- return dipi->callback_trampoline(dipi->callback, info, size, dipi->data, 0, 0,
- 0, &ret_label, 0, 0, 0, &ret_origin);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr(
- int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
- size_t size, void *data, dfsan_label info_label,
- dfsan_label size_label, dfsan_label data_label,
- dfsan_label *ret_label),
- void *callback, void *data, dfsan_label callback_label,
- dfsan_label data_label, dfsan_label *ret_label) {
- dl_iterate_phdr_info dipi = { callback_trampoline, callback, data };
- *ret_label = 0;
- return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_dl_iterate_phdr(
- int (*callback_trampoline)(void *callback, struct dl_phdr_info *info,
- size_t size, void *data, dfsan_label info_label,
- dfsan_label size_label, dfsan_label data_label,
- dfsan_label *ret_label, dfsan_origin info_origin,
- dfsan_origin size_origin,
- dfsan_origin data_origin,
- dfsan_origin *ret_origin),
- void *callback, void *data, dfsan_label callback_label,
- dfsan_label data_label, dfsan_label *ret_label,
- dfsan_origin callback_origin, dfsan_origin data_origin,
- dfsan_origin *ret_origin) {
- dl_iterate_phdr_origin_info dipi = {callback_trampoline, callback, data};
- *ret_label = 0;
- return dl_iterate_phdr(dl_iterate_phdr_origin_cb, &dipi);
- }
- // This function is only available for glibc 2.27 or newer. Mark it weak so
- // linking succeeds with older glibcs.
- SANITIZER_WEAK_ATTRIBUTE void _dl_get_tls_static_info(size_t *sizep,
- size_t *alignp);
- SANITIZER_INTERFACE_ATTRIBUTE void __dfsw__dl_get_tls_static_info(
- size_t *sizep, size_t *alignp, dfsan_label sizep_label,
- dfsan_label alignp_label) {
- assert(_dl_get_tls_static_info);
- _dl_get_tls_static_info(sizep, alignp);
- dfsan_set_label(0, sizep, sizeof(*sizep));
- dfsan_set_label(0, alignp, sizeof(*alignp));
- }
- SANITIZER_INTERFACE_ATTRIBUTE void __dfso__dl_get_tls_static_info(
- size_t *sizep, size_t *alignp, dfsan_label sizep_label,
- dfsan_label alignp_label, dfsan_origin sizep_origin,
- dfsan_origin alignp_origin) {
- __dfsw__dl_get_tls_static_info(sizep, alignp, sizep_label, alignp_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfsw_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
- dfsan_label buf_label, dfsan_label *ret_label) {
- char *ret = ctime_r(timep, buf);
- if (ret) {
- dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), buf,
- strlen(buf) + 1);
- *ret_label = buf_label;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfso_ctime_r(const time_t *timep, char *buf, dfsan_label timep_label,
- dfsan_label buf_label, dfsan_label *ret_label,
- dfsan_origin timep_origin, dfsan_origin buf_origin,
- dfsan_origin *ret_origin) {
- char *ret = ctime_r(timep, buf);
- if (ret) {
- dfsan_set_label_origin(
- dfsan_read_label(timep, sizeof(time_t)),
- dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), buf,
- strlen(buf) + 1);
- *ret_label = buf_label;
- *ret_origin = buf_origin;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfsw_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
- dfsan_label size_label, dfsan_label stream_label,
- dfsan_label *ret_label) {
- char *ret = fgets(s, size, stream);
- if (ret) {
- dfsan_set_label(0, ret, strlen(ret) + 1);
- *ret_label = s_label;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfso_fgets(char *s, int size, FILE *stream, dfsan_label s_label,
- dfsan_label size_label, dfsan_label stream_label,
- dfsan_label *ret_label, dfsan_origin s_origin,
- dfsan_origin size_origin, dfsan_origin stream_origin,
- dfsan_origin *ret_origin) {
- char *ret = __dfsw_fgets(s, size, stream, s_label, size_label, stream_label,
- ret_label);
- if (ret)
- *ret_origin = s_origin;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfsw_getcwd(char *buf, size_t size, dfsan_label buf_label,
- dfsan_label size_label, dfsan_label *ret_label) {
- char *ret = getcwd(buf, size);
- if (ret) {
- dfsan_set_label(0, ret, strlen(ret) + 1);
- *ret_label = buf_label;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfso_getcwd(char *buf, size_t size, dfsan_label buf_label,
- dfsan_label size_label, dfsan_label *ret_label,
- dfsan_origin buf_origin, dfsan_origin size_origin,
- dfsan_origin *ret_origin) {
- char *ret = __dfsw_getcwd(buf, size, buf_label, size_label, ret_label);
- if (ret)
- *ret_origin = buf_origin;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfsw_get_current_dir_name(dfsan_label *ret_label) {
- char *ret = get_current_dir_name();
- if (ret)
- dfsan_set_label(0, ret, strlen(ret) + 1);
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfso_get_current_dir_name(dfsan_label *ret_label,
- dfsan_origin *ret_origin) {
- return __dfsw_get_current_dir_name(ret_label);
- }
- // This function is only available for glibc 2.25 or newer. Mark it weak so
- // linking succeeds with older glibcs.
- SANITIZER_WEAK_ATTRIBUTE int getentropy(void *buffer, size_t length);
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getentropy(void *buffer, size_t length,
- dfsan_label buffer_label,
- dfsan_label length_label,
- dfsan_label *ret_label) {
- int ret = getentropy(buffer, length);
- if (ret == 0) {
- dfsan_set_label(0, buffer, length);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getentropy(void *buffer, size_t length,
- dfsan_label buffer_label,
- dfsan_label length_label,
- dfsan_label *ret_label,
- dfsan_origin buffer_origin,
- dfsan_origin length_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_getentropy(buffer, length, buffer_label, length_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_gethostname(char *name, size_t len, dfsan_label name_label,
- dfsan_label len_label, dfsan_label *ret_label) {
- int ret = gethostname(name, len);
- if (ret == 0) {
- dfsan_set_label(0, name, strlen(name) + 1);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_gethostname(char *name, size_t len, dfsan_label name_label,
- dfsan_label len_label, dfsan_label *ret_label,
- dfsan_origin name_origin, dfsan_origin len_origin,
- dfsan_label *ret_origin) {
- return __dfsw_gethostname(name, len, name_label, len_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_getrlimit(int resource, struct rlimit *rlim,
- dfsan_label resource_label, dfsan_label rlim_label,
- dfsan_label *ret_label) {
- int ret = getrlimit(resource, rlim);
- if (ret == 0) {
- dfsan_set_label(0, rlim, sizeof(struct rlimit));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_getrlimit(int resource, struct rlimit *rlim,
- dfsan_label resource_label, dfsan_label rlim_label,
- dfsan_label *ret_label, dfsan_origin resource_origin,
- dfsan_origin rlim_origin, dfsan_origin *ret_origin) {
- return __dfsw_getrlimit(resource, rlim, resource_label, rlim_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label,
- dfsan_label usage_label, dfsan_label *ret_label) {
- int ret = getrusage(who, usage);
- if (ret == 0) {
- dfsan_set_label(0, usage, sizeof(struct rusage));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_getrusage(int who, struct rusage *usage, dfsan_label who_label,
- dfsan_label usage_label, dfsan_label *ret_label,
- dfsan_origin who_origin, dfsan_origin usage_origin,
- dfsan_label *ret_origin) {
- return __dfsw_getrusage(who, usage, who_label, usage_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label,
- dfsan_label src_label, dfsan_label *ret_label) {
- char *ret = strcpy(dest, src);
- if (ret) {
- dfsan_mem_shadow_transfer(dest, src, strlen(src) + 1);
- }
- *ret_label = dst_label;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- char *__dfso_strcpy(char *dest, const char *src, dfsan_label dst_label,
- dfsan_label src_label, dfsan_label *ret_label,
- dfsan_origin dst_origin, dfsan_origin src_origin,
- dfsan_origin *ret_origin) {
- char *ret = strcpy(dest, src);
- if (ret) {
- size_t str_len = strlen(src) + 1;
- dfsan_mem_origin_transfer(dest, src, str_len);
- dfsan_mem_shadow_transfer(dest, src, str_len);
- }
- *ret_label = dst_label;
- *ret_origin = dst_origin;
- return ret;
- }
- static long int dfsan_strtol(const char *nptr, char **endptr, int base,
- char **tmp_endptr) {
- assert(tmp_endptr);
- long int ret = strtol(nptr, tmp_endptr, base);
- if (endptr)
- *endptr = *tmp_endptr;
- return ret;
- }
- static void dfsan_strtolong_label(const char *nptr, const char *tmp_endptr,
- dfsan_label base_label,
- dfsan_label *ret_label) {
- if (tmp_endptr > nptr) {
- // If *tmp_endptr is '\0' include its label as well.
- *ret_label = dfsan_union(
- base_label,
- dfsan_read_label(nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1)));
- } else {
- *ret_label = 0;
- }
- }
- static void dfsan_strtolong_origin(const char *nptr, const char *tmp_endptr,
- dfsan_label base_label,
- dfsan_label *ret_label,
- dfsan_origin base_origin,
- dfsan_origin *ret_origin) {
- if (tmp_endptr > nptr) {
- // When multiple inputs are tainted, we propagate one of its origins.
- // Because checking if base_label is tainted does not need additional
- // computation, we prefer to propagating base_origin.
- *ret_origin = base_label
- ? base_origin
- : dfsan_read_origin_of_first_taint(
- nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
- }
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long int __dfsw_strtol(const char *nptr, char **endptr, int base,
- dfsan_label nptr_label, dfsan_label endptr_label,
- dfsan_label base_label, dfsan_label *ret_label) {
- char *tmp_endptr;
- long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long int __dfso_strtol(const char *nptr, char **endptr, int base,
- dfsan_label nptr_label, dfsan_label endptr_label,
- dfsan_label base_label, dfsan_label *ret_label,
- dfsan_origin nptr_origin, dfsan_origin endptr_origin,
- dfsan_origin base_origin, dfsan_origin *ret_origin) {
- char *tmp_endptr;
- long int ret = dfsan_strtol(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
- ret_origin);
- return ret;
- }
- static double dfsan_strtod(const char *nptr, char **endptr, char **tmp_endptr) {
- assert(tmp_endptr);
- double ret = strtod(nptr, tmp_endptr);
- if (endptr)
- *endptr = *tmp_endptr;
- return ret;
- }
- static void dfsan_strtod_label(const char *nptr, const char *tmp_endptr,
- dfsan_label *ret_label) {
- if (tmp_endptr > nptr) {
- // If *tmp_endptr is '\0' include its label as well.
- *ret_label = dfsan_read_label(
- nptr,
- tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
- } else {
- *ret_label = 0;
- }
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- double __dfsw_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
- dfsan_label endptr_label, dfsan_label *ret_label) {
- char *tmp_endptr;
- double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
- dfsan_strtod_label(nptr, tmp_endptr, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- double __dfso_strtod(const char *nptr, char **endptr, dfsan_label nptr_label,
- dfsan_label endptr_label, dfsan_label *ret_label,
- dfsan_origin nptr_origin, dfsan_origin endptr_origin,
- dfsan_origin *ret_origin) {
- char *tmp_endptr;
- double ret = dfsan_strtod(nptr, endptr, &tmp_endptr);
- dfsan_strtod_label(nptr, tmp_endptr, ret_label);
- if (tmp_endptr > nptr) {
- // If *tmp_endptr is '\0' include its label as well.
- *ret_origin = dfsan_read_origin_of_first_taint(
- nptr, tmp_endptr - nptr + (*tmp_endptr ? 0 : 1));
- } else {
- *ret_origin = 0;
- }
- return ret;
- }
- static long long int dfsan_strtoll(const char *nptr, char **endptr, int base,
- char **tmp_endptr) {
- assert(tmp_endptr);
- long long int ret = strtoll(nptr, tmp_endptr, base);
- if (endptr)
- *endptr = *tmp_endptr;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long long int __dfsw_strtoll(const char *nptr, char **endptr, int base,
- dfsan_label nptr_label, dfsan_label endptr_label,
- dfsan_label base_label, dfsan_label *ret_label) {
- char *tmp_endptr;
- long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long long int __dfso_strtoll(const char *nptr, char **endptr, int base,
- dfsan_label nptr_label, dfsan_label endptr_label,
- dfsan_label base_label, dfsan_label *ret_label,
- dfsan_origin nptr_origin,
- dfsan_origin endptr_origin,
- dfsan_origin base_origin,
- dfsan_origin *ret_origin) {
- char *tmp_endptr;
- long long int ret = dfsan_strtoll(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
- ret_origin);
- return ret;
- }
- static unsigned long int dfsan_strtoul(const char *nptr, char **endptr,
- int base, char **tmp_endptr) {
- assert(tmp_endptr);
- unsigned long int ret = strtoul(nptr, tmp_endptr, base);
- if (endptr)
- *endptr = *tmp_endptr;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- unsigned long int __dfsw_strtoul(const char *nptr, char **endptr, int base,
- dfsan_label nptr_label, dfsan_label endptr_label,
- dfsan_label base_label, dfsan_label *ret_label) {
- char *tmp_endptr;
- unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- unsigned long int __dfso_strtoul(
- const char *nptr, char **endptr, int base, dfsan_label nptr_label,
- dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
- dfsan_origin nptr_origin, dfsan_origin endptr_origin,
- dfsan_origin base_origin, dfsan_origin *ret_origin) {
- char *tmp_endptr;
- unsigned long int ret = dfsan_strtoul(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
- ret_origin);
- return ret;
- }
- static long long unsigned int dfsan_strtoull(const char *nptr, char **endptr,
- int base, char **tmp_endptr) {
- assert(tmp_endptr);
- long long unsigned int ret = strtoull(nptr, tmp_endptr, base);
- if (endptr)
- *endptr = *tmp_endptr;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr,
- int base, dfsan_label nptr_label,
- dfsan_label endptr_label,
- dfsan_label base_label,
- dfsan_label *ret_label) {
- char *tmp_endptr;
- long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- long long unsigned int __dfso_strtoull(
- const char *nptr, char **endptr, int base, dfsan_label nptr_label,
- dfsan_label endptr_label, dfsan_label base_label, dfsan_label *ret_label,
- dfsan_origin nptr_origin, dfsan_origin endptr_origin,
- dfsan_origin base_origin, dfsan_origin *ret_origin) {
- char *tmp_endptr;
- long long unsigned int ret = dfsan_strtoull(nptr, endptr, base, &tmp_endptr);
- dfsan_strtolong_label(nptr, tmp_endptr, base_label, ret_label);
- dfsan_strtolong_origin(nptr, tmp_endptr, base_label, ret_label, base_origin,
- ret_origin);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- time_t __dfsw_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label) {
- time_t ret = time(t);
- if (ret != (time_t) -1 && t) {
- dfsan_set_label(0, t, sizeof(time_t));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- time_t __dfso_time(time_t *t, dfsan_label t_label, dfsan_label *ret_label,
- dfsan_origin t_origin, dfsan_origin *ret_origin) {
- return __dfsw_time(t, t_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
- dfsan_label src_label, dfsan_label dst_label,
- dfsan_label *ret_label) {
- int ret = inet_pton(af, src, dst);
- if (ret == 1) {
- dfsan_set_label(dfsan_read_label(src, strlen(src) + 1), dst,
- af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_inet_pton(int af, const char *src, void *dst, dfsan_label af_label,
- dfsan_label src_label, dfsan_label dst_label,
- dfsan_label *ret_label, dfsan_origin af_origin,
- dfsan_origin src_origin, dfsan_origin dst_origin,
- dfsan_origin *ret_origin) {
- int ret = inet_pton(af, src, dst);
- if (ret == 1) {
- int src_len = strlen(src) + 1;
- dfsan_set_label_origin(
- dfsan_read_label(src, src_len),
- dfsan_read_origin_of_first_taint(src, src_len), dst,
- af == AF_INET ? sizeof(struct in_addr) : sizeof(in6_addr));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- struct tm *__dfsw_localtime_r(const time_t *timep, struct tm *result,
- dfsan_label timep_label, dfsan_label result_label,
- dfsan_label *ret_label) {
- struct tm *ret = localtime_r(timep, result);
- if (ret) {
- dfsan_set_label(dfsan_read_label(timep, sizeof(time_t)), result,
- sizeof(struct tm));
- *ret_label = result_label;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- struct tm *__dfso_localtime_r(const time_t *timep, struct tm *result,
- dfsan_label timep_label, dfsan_label result_label,
- dfsan_label *ret_label, dfsan_origin timep_origin,
- dfsan_origin result_origin,
- dfsan_origin *ret_origin) {
- struct tm *ret = localtime_r(timep, result);
- if (ret) {
- dfsan_set_label_origin(
- dfsan_read_label(timep, sizeof(time_t)),
- dfsan_read_origin_of_first_taint(timep, sizeof(time_t)), result,
- sizeof(struct tm));
- *ret_label = result_label;
- *ret_origin = result_origin;
- } else {
- *ret_label = 0;
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_getpwuid_r(id_t uid, struct passwd *pwd,
- char *buf, size_t buflen, struct passwd **result,
- dfsan_label uid_label, dfsan_label pwd_label,
- dfsan_label buf_label, dfsan_label buflen_label,
- dfsan_label result_label, dfsan_label *ret_label) {
- // Store the data in pwd, the strings referenced from pwd in buf, and the
- // address of pwd in *result. On failure, NULL is stored in *result.
- int ret = getpwuid_r(uid, pwd, buf, buflen, result);
- if (ret == 0) {
- dfsan_set_label(0, pwd, sizeof(struct passwd));
- dfsan_set_label(0, buf, strlen(buf) + 1);
- }
- *ret_label = 0;
- dfsan_set_label(0, result, sizeof(struct passwd*));
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_getpwuid_r(id_t uid, struct passwd *pwd, char *buf, size_t buflen,
- struct passwd **result, dfsan_label uid_label,
- dfsan_label pwd_label, dfsan_label buf_label,
- dfsan_label buflen_label, dfsan_label result_label,
- dfsan_label *ret_label, dfsan_origin uid_origin,
- dfsan_origin pwd_origin, dfsan_origin buf_origin,
- dfsan_origin buflen_origin, dfsan_origin result_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_getpwuid_r(uid, pwd, buf, buflen, result, uid_label, pwd_label,
- buf_label, buflen_label, result_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
- int timeout, dfsan_label epfd_label,
- dfsan_label events_label, dfsan_label maxevents_label,
- dfsan_label timeout_label, dfsan_label *ret_label) {
- int ret = epoll_wait(epfd, events, maxevents, timeout);
- if (ret > 0)
- dfsan_set_label(0, events, ret * sizeof(*events));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
- int timeout, dfsan_label epfd_label,
- dfsan_label events_label, dfsan_label maxevents_label,
- dfsan_label timeout_label, dfsan_label *ret_label,
- dfsan_origin epfd_origin, dfsan_origin events_origin,
- dfsan_origin maxevents_origin,
- dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
- return __dfsw_epoll_wait(epfd, events, maxevents, timeout, epfd_label,
- events_label, maxevents_label, timeout_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_poll(struct pollfd *fds, nfds_t nfds, int timeout,
- dfsan_label dfs_label, dfsan_label nfds_label,
- dfsan_label timeout_label, dfsan_label *ret_label) {
- int ret = poll(fds, nfds, timeout);
- if (ret >= 0) {
- for (; nfds > 0; --nfds) {
- dfsan_set_label(0, &fds[nfds - 1].revents, sizeof(fds[nfds - 1].revents));
- }
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_poll(struct pollfd *fds, nfds_t nfds, int timeout,
- dfsan_label dfs_label, dfsan_label nfds_label,
- dfsan_label timeout_label, dfsan_label *ret_label,
- dfsan_origin dfs_origin, dfsan_origin nfds_origin,
- dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
- return __dfsw_poll(fds, nfds, timeout, dfs_label, nfds_label, timeout_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout,
- dfsan_label nfds_label, dfsan_label readfds_label,
- dfsan_label writefds_label, dfsan_label exceptfds_label,
- dfsan_label timeout_label, dfsan_label *ret_label) {
- int ret = select(nfds, readfds, writefds, exceptfds, timeout);
- // Clear everything (also on error) since their content is either set or
- // undefined.
- if (readfds) {
- dfsan_set_label(0, readfds, sizeof(fd_set));
- }
- if (writefds) {
- dfsan_set_label(0, writefds, sizeof(fd_set));
- }
- if (exceptfds) {
- dfsan_set_label(0, exceptfds, sizeof(fd_set));
- }
- dfsan_set_label(0, timeout, sizeof(struct timeval));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_select(int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout,
- dfsan_label nfds_label, dfsan_label readfds_label,
- dfsan_label writefds_label, dfsan_label exceptfds_label,
- dfsan_label timeout_label, dfsan_label *ret_label,
- dfsan_origin nfds_origin, dfsan_origin readfds_origin,
- dfsan_origin writefds_origin, dfsan_origin exceptfds_origin,
- dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
- return __dfsw_select(nfds, readfds, writefds, exceptfds, timeout, nfds_label,
- readfds_label, writefds_label, exceptfds_label,
- timeout_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
- dfsan_label pid_label,
- dfsan_label cpusetsize_label,
- dfsan_label mask_label, dfsan_label *ret_label) {
- int ret = sched_getaffinity(pid, cpusetsize, mask);
- if (ret == 0) {
- dfsan_set_label(0, mask, cpusetsize);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask,
- dfsan_label pid_label,
- dfsan_label cpusetsize_label,
- dfsan_label mask_label, dfsan_label *ret_label,
- dfsan_origin pid_origin,
- dfsan_origin cpusetsize_origin,
- dfsan_origin mask_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_sched_getaffinity(pid, cpusetsize, mask, pid_label,
- cpusetsize_label, mask_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_sigemptyset(sigset_t *set, dfsan_label set_label,
- dfsan_label *ret_label) {
- int ret = sigemptyset(set);
- dfsan_set_label(0, set, sizeof(sigset_t));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_sigemptyset(sigset_t *set, dfsan_label set_label,
- dfsan_label *ret_label, dfsan_origin set_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_sigemptyset(set, set_label, ret_label);
- }
- class SignalHandlerScope {
- public:
- SignalHandlerScope() {
- if (DFsanThread *t = GetCurrentThread())
- t->EnterSignalHandler();
- }
- ~SignalHandlerScope() {
- if (DFsanThread *t = GetCurrentThread())
- t->LeaveSignalHandler();
- }
- };
- // Clear DFSan runtime TLS state at the end of a scope.
- //
- // Implementation must be async-signal-safe and use small data size, because
- // instances of this class may live on the signal handler stack.
- //
- // DFSan uses TLS to pass metadata of arguments and return values. When an
- // instrumented function accesses the TLS, if a signal callback happens, and the
- // callback calls other instrumented functions with updating the same TLS, the
- // TLS is in an inconsistent state after the callback ends. This may cause
- // either under-tainting or over-tainting.
- //
- // The current implementation simply resets TLS at restore. This prevents from
- // over-tainting. Although under-tainting may still happen, a taint flow can be
- // found eventually if we run a DFSan-instrumented program multiple times. The
- // alternative option is saving the entire TLS. However the TLS storage takes
- // 2k bytes, and signal calls could be nested. So it does not seem worth.
- class ScopedClearThreadLocalState {
- public:
- ScopedClearThreadLocalState() {}
- ~ScopedClearThreadLocalState() { dfsan_clear_thread_local_state(); }
- };
- // SignalSpinLocker::sigactions_mu guarantees atomicity of sigaction() calls.
- const int kMaxSignals = 1024;
- static atomic_uintptr_t sigactions[kMaxSignals];
- static void SignalHandler(int signo) {
- SignalHandlerScope signal_handler_scope;
- ScopedClearThreadLocalState scoped_clear_tls;
- // Clear shadows for all inputs provided by system. This is why DFSan
- // instrumentation generates a trampoline function to each function pointer,
- // and uses the trampoline to clear shadows. However sigaction does not use
- // a function pointer directly, so we have to do this manually.
- dfsan_clear_arg_tls(0, sizeof(dfsan_label));
- typedef void (*signal_cb)(int x);
- signal_cb cb =
- (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- cb(signo);
- }
- static void SignalAction(int signo, siginfo_t *si, void *uc) {
- SignalHandlerScope signal_handler_scope;
- ScopedClearThreadLocalState scoped_clear_tls;
- // Clear shadows for all inputs provided by system. Similar to SignalHandler.
- dfsan_clear_arg_tls(0, 3 * sizeof(dfsan_label));
- dfsan_set_label(0, si, sizeof(*si));
- dfsan_set_label(0, uc, sizeof(ucontext_t));
- typedef void (*sigaction_cb)(int, siginfo_t *, void *);
- sigaction_cb cb =
- (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- cb(signo, si, uc);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_sigaction(int signum, const struct sigaction *act,
- struct sigaction *oldact, dfsan_label signum_label,
- dfsan_label act_label, dfsan_label oldact_label,
- dfsan_label *ret_label) {
- CHECK_LT(signum, kMaxSignals);
- SignalSpinLocker lock;
- uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
- struct sigaction new_act;
- struct sigaction *pnew_act = act ? &new_act : nullptr;
- if (act) {
- internal_memcpy(pnew_act, act, sizeof(struct sigaction));
- if (pnew_act->sa_flags & SA_SIGINFO) {
- uptr cb = (uptr)(pnew_act->sa_sigaction);
- if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
- atomic_store(&sigactions[signum], cb, memory_order_relaxed);
- pnew_act->sa_sigaction = SignalAction;
- }
- } else {
- uptr cb = (uptr)(pnew_act->sa_handler);
- if (cb != (uptr)SIG_IGN && cb != (uptr)SIG_DFL) {
- atomic_store(&sigactions[signum], cb, memory_order_relaxed);
- pnew_act->sa_handler = SignalHandler;
- }
- }
- }
- int ret = sigaction(signum, pnew_act, oldact);
- if (ret == 0 && oldact) {
- if (oldact->sa_flags & SA_SIGINFO) {
- if (oldact->sa_sigaction == SignalAction)
- oldact->sa_sigaction = (decltype(oldact->sa_sigaction))old_cb;
- } else {
- if (oldact->sa_handler == SignalHandler)
- oldact->sa_handler = (decltype(oldact->sa_handler))old_cb;
- }
- }
- if (oldact) {
- dfsan_set_label(0, oldact, sizeof(struct sigaction));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_sigaction(int signum, const struct sigaction *act,
- struct sigaction *oldact, dfsan_label signum_label,
- dfsan_label act_label, dfsan_label oldact_label,
- dfsan_label *ret_label, dfsan_origin signum_origin,
- dfsan_origin act_origin, dfsan_origin oldact_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_sigaction(signum, act, oldact, signum_label, act_label,
- oldact_label, ret_label);
- }
- static sighandler_t dfsan_signal(int signum, sighandler_t handler,
- dfsan_label *ret_label) {
- CHECK_LT(signum, kMaxSignals);
- SignalSpinLocker lock;
- uptr old_cb = atomic_load(&sigactions[signum], memory_order_relaxed);
- if (handler != SIG_IGN && handler != SIG_DFL) {
- atomic_store(&sigactions[signum], (uptr)handler, memory_order_relaxed);
- handler = &SignalHandler;
- }
- sighandler_t ret = signal(signum, handler);
- if (ret == SignalHandler)
- ret = (sighandler_t)old_cb;
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- sighandler_t __dfsw_signal(int signum,
- void *(*handler_trampoline)(void *, int, dfsan_label,
- dfsan_label *),
- sighandler_t handler, dfsan_label signum_label,
- dfsan_label handler_label, dfsan_label *ret_label) {
- return dfsan_signal(signum, handler, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- sighandler_t __dfso_signal(
- int signum,
- void *(*handler_trampoline)(void *, int, dfsan_label, dfsan_label *,
- dfsan_origin, dfsan_origin *),
- sighandler_t handler, dfsan_label signum_label, dfsan_label handler_label,
- dfsan_label *ret_label, dfsan_origin signum_origin,
- dfsan_origin handler_origin, dfsan_origin *ret_origin) {
- return dfsan_signal(signum, handler, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
- dfsan_label old_ss_label, dfsan_label *ret_label) {
- int ret = sigaltstack(ss, old_ss);
- if (ret != -1 && old_ss)
- dfsan_set_label(0, old_ss, sizeof(*old_ss));
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_sigaltstack(const stack_t *ss, stack_t *old_ss, dfsan_label ss_label,
- dfsan_label old_ss_label, dfsan_label *ret_label,
- dfsan_origin ss_origin, dfsan_origin old_ss_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_sigaltstack(ss, old_ss, ss_label, old_ss_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_gettimeofday(struct timeval *tv, struct timezone *tz,
- dfsan_label tv_label, dfsan_label tz_label,
- dfsan_label *ret_label) {
- int ret = gettimeofday(tv, tz);
- if (tv) {
- dfsan_set_label(0, tv, sizeof(struct timeval));
- }
- if (tz) {
- dfsan_set_label(0, tz, sizeof(struct timezone));
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_gettimeofday(struct timeval *tv, struct timezone *tz,
- dfsan_label tv_label, dfsan_label tz_label,
- dfsan_label *ret_label, dfsan_origin tv_origin,
- dfsan_origin tz_origin, dfsan_origin *ret_origin) {
- return __dfsw_gettimeofday(tv, tz, tv_label, tz_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_memchr(void *s, int c, size_t n,
- dfsan_label s_label,
- dfsan_label c_label,
- dfsan_label n_label,
- dfsan_label *ret_label) {
- void *ret = memchr(s, c, n);
- if (flags().strict_data_dependencies) {
- *ret_label = ret ? s_label : 0;
- } else {
- size_t len =
- ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
- : n;
- *ret_label =
- dfsan_union(dfsan_read_label(s, len), dfsan_union(s_label, c_label));
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE void *__dfso_memchr(
- void *s, int c, size_t n, dfsan_label s_label, dfsan_label c_label,
- dfsan_label n_label, dfsan_label *ret_label, dfsan_origin s_origin,
- dfsan_origin c_origin, dfsan_origin n_origin, dfsan_origin *ret_origin) {
- void *ret = __dfsw_memchr(s, c, n, s_label, c_label, n_label, ret_label);
- if (flags().strict_data_dependencies) {
- if (ret)
- *ret_origin = s_origin;
- } else {
- size_t len =
- ret ? reinterpret_cast<char *>(ret) - reinterpret_cast<char *>(s) + 1
- : n;
- dfsan_origin o = dfsan_read_origin_of_first_taint(s, len);
- *ret_origin = o ? o : (s_label ? s_origin : c_origin);
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strrchr(char *s, int c,
- dfsan_label s_label,
- dfsan_label c_label,
- dfsan_label *ret_label) {
- char *ret = strrchr(s, c);
- if (flags().strict_data_dependencies) {
- *ret_label = ret ? s_label : 0;
- } else {
- *ret_label =
- dfsan_union(dfsan_read_label(s, strlen(s) + 1),
- dfsan_union(s_label, c_label));
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strrchr(
- char *s, int c, dfsan_label s_label, dfsan_label c_label,
- dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
- dfsan_origin *ret_origin) {
- char *ret = __dfsw_strrchr(s, c, s_label, c_label, ret_label);
- if (flags().strict_data_dependencies) {
- if (ret)
- *ret_origin = s_origin;
- } else {
- size_t s_len = strlen(s) + 1;
- dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_len);
- *ret_origin = o ? o : (s_label ? s_origin : c_origin);
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strstr(char *haystack, char *needle,
- dfsan_label haystack_label,
- dfsan_label needle_label,
- dfsan_label *ret_label) {
- char *ret = strstr(haystack, needle);
- if (flags().strict_data_dependencies) {
- *ret_label = ret ? haystack_label : 0;
- } else {
- size_t len = ret ? ret + strlen(needle) - haystack : strlen(haystack) + 1;
- *ret_label =
- dfsan_union(dfsan_read_label(haystack, len),
- dfsan_union(dfsan_read_label(needle, strlen(needle) + 1),
- dfsan_union(haystack_label, needle_label)));
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strstr(char *haystack, char *needle,
- dfsan_label haystack_label,
- dfsan_label needle_label,
- dfsan_label *ret_label,
- dfsan_origin haystack_origin,
- dfsan_origin needle_origin,
- dfsan_origin *ret_origin) {
- char *ret =
- __dfsw_strstr(haystack, needle, haystack_label, needle_label, ret_label);
- if (flags().strict_data_dependencies) {
- if (ret)
- *ret_origin = haystack_origin;
- } else {
- size_t needle_len = strlen(needle);
- size_t len = ret ? ret + needle_len - haystack : strlen(haystack) + 1;
- dfsan_origin o = dfsan_read_origin_of_first_taint(haystack, len);
- if (o) {
- *ret_origin = o;
- } else {
- o = dfsan_read_origin_of_first_taint(needle, needle_len + 1);
- *ret_origin = o ? o : (haystack_label ? haystack_origin : needle_origin);
- }
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_nanosleep(const struct timespec *req,
- struct timespec *rem,
- dfsan_label req_label,
- dfsan_label rem_label,
- dfsan_label *ret_label) {
- int ret = nanosleep(req, rem);
- *ret_label = 0;
- if (ret == -1) {
- // Interrupted by a signal, rem is filled with the remaining time.
- dfsan_set_label(0, rem, sizeof(struct timespec));
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_nanosleep(
- const struct timespec *req, struct timespec *rem, dfsan_label req_label,
- dfsan_label rem_label, dfsan_label *ret_label, dfsan_origin req_origin,
- dfsan_origin rem_origin, dfsan_origin *ret_origin) {
- return __dfsw_nanosleep(req, rem, req_label, rem_label, ret_label);
- }
- static void clear_msghdr_labels(size_t bytes_written, struct msghdr *msg) {
- dfsan_set_label(0, msg, sizeof(*msg));
- dfsan_set_label(0, msg->msg_name, msg->msg_namelen);
- dfsan_set_label(0, msg->msg_control, msg->msg_controllen);
- for (size_t i = 0; bytes_written > 0; ++i) {
- assert(i < msg->msg_iovlen);
- struct iovec *iov = &msg->msg_iov[i];
- size_t iov_written =
- bytes_written < iov->iov_len ? bytes_written : iov->iov_len;
- dfsan_set_label(0, iov->iov_base, iov_written);
- bytes_written -= iov_written;
- }
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_recvmmsg(
- int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
- struct timespec *timeout, dfsan_label sockfd_label,
- dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
- dfsan_label timeout_label, dfsan_label *ret_label) {
- int ret = recvmmsg(sockfd, msgvec, vlen, flags, timeout);
- for (int i = 0; i < ret; ++i) {
- dfsan_set_label(0, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len));
- clear_msghdr_labels(msgvec[i].msg_len, &msgvec[i].msg_hdr);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_recvmmsg(
- int sockfd, struct mmsghdr *msgvec, unsigned int vlen, int flags,
- struct timespec *timeout, dfsan_label sockfd_label,
- dfsan_label msgvec_label, dfsan_label vlen_label, dfsan_label flags_label,
- dfsan_label timeout_label, dfsan_label *ret_label,
- dfsan_origin sockfd_origin, dfsan_origin msgvec_origin,
- dfsan_origin vlen_origin, dfsan_origin flags_origin,
- dfsan_origin timeout_origin, dfsan_origin *ret_origin) {
- return __dfsw_recvmmsg(sockfd, msgvec, vlen, flags, timeout, sockfd_label,
- msgvec_label, vlen_label, flags_label, timeout_label,
- ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfsw_recvmsg(
- int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
- dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label) {
- ssize_t ret = recvmsg(sockfd, msg, flags);
- if (ret >= 0)
- clear_msghdr_labels(ret, msg);
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE ssize_t __dfso_recvmsg(
- int sockfd, struct msghdr *msg, int flags, dfsan_label sockfd_label,
- dfsan_label msg_label, dfsan_label flags_label, dfsan_label *ret_label,
- dfsan_origin sockfd_origin, dfsan_origin msg_origin,
- dfsan_origin flags_origin, dfsan_origin *ret_origin) {
- return __dfsw_recvmsg(sockfd, msg, flags, sockfd_label, msg_label,
- flags_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int
- __dfsw_socketpair(int domain, int type, int protocol, int sv[2],
- dfsan_label domain_label, dfsan_label type_label,
- dfsan_label protocol_label, dfsan_label sv_label,
- dfsan_label *ret_label) {
- int ret = socketpair(domain, type, protocol, sv);
- *ret_label = 0;
- if (ret == 0) {
- dfsan_set_label(0, sv, sizeof(*sv) * 2);
- }
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_socketpair(
- int domain, int type, int protocol, int sv[2], dfsan_label domain_label,
- dfsan_label type_label, dfsan_label protocol_label, dfsan_label sv_label,
- dfsan_label *ret_label, dfsan_origin domain_origin,
- dfsan_origin type_origin, dfsan_origin protocol_origin,
- dfsan_origin sv_origin, dfsan_origin *ret_origin) {
- return __dfsw_socketpair(domain, type, protocol, sv, domain_label, type_label,
- protocol_label, sv_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockopt(
- int sockfd, int level, int optname, void *optval, socklen_t *optlen,
- dfsan_label sockfd_label, dfsan_label level_label,
- dfsan_label optname_label, dfsan_label optval_label,
- dfsan_label optlen_label, dfsan_label *ret_label) {
- int ret = getsockopt(sockfd, level, optname, optval, optlen);
- if (ret != -1 && optval && optlen) {
- dfsan_set_label(0, optlen, sizeof(*optlen));
- dfsan_set_label(0, optval, *optlen);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockopt(
- int sockfd, int level, int optname, void *optval, socklen_t *optlen,
- dfsan_label sockfd_label, dfsan_label level_label,
- dfsan_label optname_label, dfsan_label optval_label,
- dfsan_label optlen_label, dfsan_label *ret_label,
- dfsan_origin sockfd_origin, dfsan_origin level_origin,
- dfsan_origin optname_origin, dfsan_origin optval_origin,
- dfsan_origin optlen_origin, dfsan_origin *ret_origin) {
- return __dfsw_getsockopt(sockfd, level, optname, optval, optlen, sockfd_label,
- level_label, optname_label, optval_label,
- optlen_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getsockname(
- int sockfd, struct sockaddr *addr, socklen_t *addrlen,
- dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
- dfsan_label *ret_label) {
- socklen_t origlen = addrlen ? *addrlen : 0;
- int ret = getsockname(sockfd, addr, addrlen);
- if (ret != -1 && addr && addrlen) {
- socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
- dfsan_set_label(0, addrlen, sizeof(*addrlen));
- dfsan_set_label(0, addr, written_bytes);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getsockname(
- int sockfd, struct sockaddr *addr, socklen_t *addrlen,
- dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
- dfsan_label *ret_label, dfsan_origin sockfd_origin,
- dfsan_origin addr_origin, dfsan_origin addrlen_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_getsockname(sockfd, addr, addrlen, sockfd_label, addr_label,
- addrlen_label, ret_label);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_getpeername(
- int sockfd, struct sockaddr *addr, socklen_t *addrlen,
- dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
- dfsan_label *ret_label) {
- socklen_t origlen = addrlen ? *addrlen : 0;
- int ret = getpeername(sockfd, addr, addrlen);
- if (ret != -1 && addr && addrlen) {
- socklen_t written_bytes = origlen < *addrlen ? origlen : *addrlen;
- dfsan_set_label(0, addrlen, sizeof(*addrlen));
- dfsan_set_label(0, addr, written_bytes);
- }
- *ret_label = 0;
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_getpeername(
- int sockfd, struct sockaddr *addr, socklen_t *addrlen,
- dfsan_label sockfd_label, dfsan_label addr_label, dfsan_label addrlen_label,
- dfsan_label *ret_label, dfsan_origin sockfd_origin,
- dfsan_origin addr_origin, dfsan_origin addrlen_origin,
- dfsan_origin *ret_origin) {
- return __dfsw_getpeername(sockfd, addr, addrlen, sockfd_label, addr_label,
- addrlen_label, ret_label);
- }
- // Type of the trampoline function passed to the custom version of
- // dfsan_set_write_callback.
- typedef void (*write_trampoline_t)(
- void *callback,
- int fd, const void *buf, ssize_t count,
- dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label);
- typedef void (*write_origin_trampoline_t)(
- void *callback, int fd, const void *buf, ssize_t count,
- dfsan_label fd_label, dfsan_label buf_label, dfsan_label count_label,
- dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin);
- // Calls to dfsan_set_write_callback() set the values in this struct.
- // Calls to the custom version of write() read (and invoke) them.
- static struct {
- write_trampoline_t write_callback_trampoline = nullptr;
- void *write_callback = nullptr;
- } write_callback_info;
- static struct {
- write_origin_trampoline_t write_callback_trampoline = nullptr;
- void *write_callback = nullptr;
- } write_origin_callback_info;
- SANITIZER_INTERFACE_ATTRIBUTE void
- __dfsw_dfsan_set_write_callback(
- write_trampoline_t write_callback_trampoline,
- void *write_callback,
- dfsan_label write_callback_label,
- dfsan_label *ret_label) {
- write_callback_info.write_callback_trampoline = write_callback_trampoline;
- write_callback_info.write_callback = write_callback;
- }
- SANITIZER_INTERFACE_ATTRIBUTE void __dfso_dfsan_set_write_callback(
- write_origin_trampoline_t write_callback_trampoline, void *write_callback,
- dfsan_label write_callback_label, dfsan_label *ret_label,
- dfsan_origin write_callback_origin, dfsan_origin *ret_origin) {
- write_origin_callback_info.write_callback_trampoline =
- write_callback_trampoline;
- write_origin_callback_info.write_callback = write_callback;
- }
- SANITIZER_INTERFACE_ATTRIBUTE int
- __dfsw_write(int fd, const void *buf, size_t count,
- dfsan_label fd_label, dfsan_label buf_label,
- dfsan_label count_label, dfsan_label *ret_label) {
- if (write_callback_info.write_callback) {
- write_callback_info.write_callback_trampoline(
- write_callback_info.write_callback,
- fd, buf, count,
- fd_label, buf_label, count_label);
- }
- *ret_label = 0;
- return write(fd, buf, count);
- }
- SANITIZER_INTERFACE_ATTRIBUTE int __dfso_write(
- int fd, const void *buf, size_t count, dfsan_label fd_label,
- dfsan_label buf_label, dfsan_label count_label, dfsan_label *ret_label,
- dfsan_origin fd_origin, dfsan_origin buf_origin, dfsan_origin count_origin,
- dfsan_origin *ret_origin) {
- if (write_origin_callback_info.write_callback) {
- write_origin_callback_info.write_callback_trampoline(
- write_origin_callback_info.write_callback, fd, buf, count, fd_label,
- buf_label, count_label, fd_origin, buf_origin, count_origin);
- }
- *ret_label = 0;
- return write(fd, buf, count);
- }
- } // namespace __dfsan
- // Type used to extract a dfsan_label with va_arg()
- typedef int dfsan_label_va;
- // Formats a chunk either a constant string or a single format directive (e.g.,
- // '%.3f').
- struct Formatter {
- Formatter(char *str_, const char *fmt_, size_t size_)
- : str(str_), str_off(0), size(size_), fmt_start(fmt_), fmt_cur(fmt_),
- width(-1) {}
- int format() {
- char *tmp_fmt = build_format_string();
- int retval =
- snprintf(str + str_off, str_off < size ? size - str_off : 0, tmp_fmt,
- 0 /* used only to avoid warnings */);
- free(tmp_fmt);
- return retval;
- }
- template <typename T> int format(T arg) {
- char *tmp_fmt = build_format_string();
- int retval;
- if (width >= 0) {
- retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
- tmp_fmt, width, arg);
- } else {
- retval = snprintf(str + str_off, str_off < size ? size - str_off : 0,
- tmp_fmt, arg);
- }
- free(tmp_fmt);
- return retval;
- }
- char *build_format_string() {
- size_t fmt_size = fmt_cur - fmt_start + 1;
- char *new_fmt = (char *)malloc(fmt_size + 1);
- assert(new_fmt);
- internal_memcpy(new_fmt, fmt_start, fmt_size);
- new_fmt[fmt_size] = '\0';
- return new_fmt;
- }
- char *str_cur() { return str + str_off; }
- size_t num_written_bytes(int retval) {
- if (retval < 0) {
- return 0;
- }
- size_t num_avail = str_off < size ? size - str_off : 0;
- if (num_avail == 0) {
- return 0;
- }
- size_t num_written = retval;
- // A return value of {v,}snprintf of size or more means that the output was
- // truncated.
- if (num_written >= num_avail) {
- num_written -= num_avail;
- }
- return num_written;
- }
- char *str;
- size_t str_off;
- size_t size;
- const char *fmt_start;
- const char *fmt_cur;
- int width;
- };
- // Formats the input and propagates the input labels to the output. The output
- // is stored in 'str'. 'size' bounds the number of output bytes. 'format' and
- // 'ap' are the format string and the list of arguments for formatting. Returns
- // the return value vsnprintf would return.
- //
- // The function tokenizes the format string in chunks representing either a
- // constant string or a single format directive (e.g., '%.3f') and formats each
- // chunk independently into the output string. This approach allows to figure
- // out which bytes of the output string depends on which argument and thus to
- // propagate labels more precisely.
- //
- // WARNING: This implementation does not support conversion specifiers with
- // positional arguments.
- static int format_buffer(char *str, size_t size, const char *fmt,
- dfsan_label *va_labels, dfsan_label *ret_label,
- dfsan_origin *va_origins, dfsan_origin *ret_origin,
- va_list ap) {
- Formatter formatter(str, fmt, size);
- while (*formatter.fmt_cur) {
- formatter.fmt_start = formatter.fmt_cur;
- formatter.width = -1;
- int retval = 0;
- if (*formatter.fmt_cur != '%') {
- // Ordinary character. Consume all the characters until a '%' or the end
- // of the string.
- for (; *(formatter.fmt_cur + 1) && *(formatter.fmt_cur + 1) != '%';
- ++formatter.fmt_cur) {}
- retval = formatter.format();
- dfsan_set_label(0, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- } else {
- // Conversion directive. Consume all the characters until a conversion
- // specifier or the end of the string.
- bool end_fmt = false;
- for (; *formatter.fmt_cur && !end_fmt; ) {
- switch (*++formatter.fmt_cur) {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- switch (*(formatter.fmt_cur - 1)) {
- case 'h':
- // Also covers the 'hh' case (since the size of the arg is still
- // an int).
- retval = formatter.format(va_arg(ap, int));
- break;
- case 'l':
- if (formatter.fmt_cur - formatter.fmt_start >= 2 &&
- *(formatter.fmt_cur - 2) == 'l') {
- retval = formatter.format(va_arg(ap, long long int));
- } else {
- retval = formatter.format(va_arg(ap, long int));
- }
- break;
- case 'q':
- retval = formatter.format(va_arg(ap, long long int));
- break;
- case 'j':
- retval = formatter.format(va_arg(ap, intmax_t));
- break;
- case 'z':
- case 't':
- retval = formatter.format(va_arg(ap, size_t));
- break;
- default:
- retval = formatter.format(va_arg(ap, int));
- }
- if (va_origins == nullptr)
- dfsan_set_label(*va_labels++, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- else
- dfsan_set_label_origin(*va_labels++, *va_origins++,
- formatter.str_cur(),
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- case 'a':
- case 'A':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- if (*(formatter.fmt_cur - 1) == 'L') {
- retval = formatter.format(va_arg(ap, long double));
- } else {
- retval = formatter.format(va_arg(ap, double));
- }
- if (va_origins == nullptr)
- dfsan_set_label(*va_labels++, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- else
- dfsan_set_label_origin(*va_labels++, *va_origins++,
- formatter.str_cur(),
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- case 'c':
- retval = formatter.format(va_arg(ap, int));
- if (va_origins == nullptr)
- dfsan_set_label(*va_labels++, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- else
- dfsan_set_label_origin(*va_labels++, *va_origins++,
- formatter.str_cur(),
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- case 's': {
- char *arg = va_arg(ap, char *);
- retval = formatter.format(arg);
- if (va_origins) {
- va_origins++;
- dfsan_mem_origin_transfer(formatter.str_cur(), arg,
- formatter.num_written_bytes(retval));
- }
- va_labels++;
- dfsan_mem_shadow_transfer(formatter.str_cur(), arg,
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- }
- case 'p':
- retval = formatter.format(va_arg(ap, void *));
- if (va_origins == nullptr)
- dfsan_set_label(*va_labels++, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- else
- dfsan_set_label_origin(*va_labels++, *va_origins++,
- formatter.str_cur(),
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- case 'n': {
- int *ptr = va_arg(ap, int *);
- *ptr = (int)formatter.str_off;
- va_labels++;
- if (va_origins)
- va_origins++;
- dfsan_set_label(0, ptr, sizeof(ptr));
- end_fmt = true;
- break;
- }
- case '%':
- retval = formatter.format();
- dfsan_set_label(0, formatter.str_cur(),
- formatter.num_written_bytes(retval));
- end_fmt = true;
- break;
- case '*':
- formatter.width = va_arg(ap, int);
- va_labels++;
- if (va_origins)
- va_origins++;
- break;
- default:
- break;
- }
- }
- }
- if (retval < 0) {
- return retval;
- }
- formatter.fmt_cur++;
- formatter.str_off += retval;
- }
- *ret_label = 0;
- if (ret_origin)
- *ret_origin = 0;
- // Number of bytes written in total.
- return formatter.str_off;
- }
- extern "C" {
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_sprintf(char *str, const char *format, dfsan_label str_label,
- dfsan_label format_label, dfsan_label *va_labels,
- dfsan_label *ret_label, ...) {
- va_list ap;
- va_start(ap, ret_label);
- int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, nullptr,
- nullptr, ap);
- va_end(ap);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_sprintf(char *str, const char *format, dfsan_label str_label,
- dfsan_label format_label, dfsan_label *va_labels,
- dfsan_label *ret_label, dfsan_origin str_origin,
- dfsan_origin format_origin, dfsan_origin *va_origins,
- dfsan_origin *ret_origin, ...) {
- va_list ap;
- va_start(ap, ret_origin);
- int ret = format_buffer(str, ~0ul, format, va_labels, ret_label, va_origins,
- ret_origin, ap);
- va_end(ap);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfsw_snprintf(char *str, size_t size, const char *format,
- dfsan_label str_label, dfsan_label size_label,
- dfsan_label format_label, dfsan_label *va_labels,
- dfsan_label *ret_label, ...) {
- va_list ap;
- va_start(ap, ret_label);
- int ret = format_buffer(str, size, format, va_labels, ret_label, nullptr,
- nullptr, ap);
- va_end(ap);
- return ret;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- int __dfso_snprintf(char *str, size_t size, const char *format,
- dfsan_label str_label, dfsan_label size_label,
- dfsan_label format_label, dfsan_label *va_labels,
- dfsan_label *ret_label, dfsan_origin str_origin,
- dfsan_origin size_origin, dfsan_origin format_origin,
- dfsan_origin *va_origins, dfsan_origin *ret_origin, ...) {
- va_list ap;
- va_start(ap, ret_origin);
- int ret = format_buffer(str, size, format, va_labels, ret_label, va_origins,
- ret_origin, ap);
- va_end(ap);
- return ret;
- }
- static void BeforeFork() {
- StackDepotLockAll();
- GetChainedOriginDepot()->LockAll();
- }
- static void AfterFork() {
- GetChainedOriginDepot()->UnlockAll();
- StackDepotUnlockAll();
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- pid_t __dfsw_fork(dfsan_label *ret_label) {
- pid_t pid = fork();
- *ret_label = 0;
- return pid;
- }
- SANITIZER_INTERFACE_ATTRIBUTE
- pid_t __dfso_fork(dfsan_label *ret_label, dfsan_origin *ret_origin) {
- BeforeFork();
- pid_t pid = __dfsw_fork(ret_label);
- AfterFork();
- return pid;
- }
- // Default empty implementations (weak). Users should redefine them.
- SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard, u32 *) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_guard_init, u32 *,
- u32 *) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_pcs_init, const uptr *beg,
- const uptr *end) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_cov_trace_pc_indir, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp1, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp2, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp4, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_cmp8, void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp1,
- void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp2,
- void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp4,
- void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_const_cmp8,
- void) {}
- SANITIZER_INTERFACE_WEAK_DEF(void, __dfsw___sanitizer_cov_trace_switch, void) {}
- } // extern "C"
|