//===-- 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" usingnamespace__dfsan; #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) … #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) … #define WRAPPER_ALIAS(fun, real) … // Async-safe, non-reentrant spin lock. namespace { class SignalSpinLocker { … }; } // namespace StaticSpinMutex SignalSpinLocker::sigactions_mu; extern … template <typename Fn> static ALWAYS_INLINE auto dfsan_strtol_impl( Fn real, const char *nptr, char **endptr, int base, char **tmp_endptr) -> decltype(real(nullptr, nullptr, 0)) { … } extern … // namespace __dfsan // Type used to extract a dfsan_label with va_arg() dfsan_label_va; // Formats a chunk either a constant string or a single format directive (e.g., // '%.3f'). struct Formatter { … }; // 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) { … } // Scans a chunk either a constant string or a single format directive (e.g., // '%.3f'). struct Scanner { … }; // This function is an inverse of format_buffer: we take the input buffer, // scan it in search for format strings and store the results in the varargs. // The labels are propagated from the input buffer to the varargs. static int scan_buffer(char *str, size_t size, const char *fmt, dfsan_label *va_labels, dfsan_label *ret_label, dfsan_origin *str_origin, dfsan_origin *ret_origin, va_list ap) { … } extern … // extern "C"