diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-07 19:55:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-07 19:55:37 +0000 |
commit | ca9211ecdede9bdedb812b2243a4abdb8dacd1b9 (patch) | |
tree | 9b19e801150082c33e9152275829a6ce90614b55 /lib/dfsan | |
parent | 8ef50bf3d1c287b5013c3168de77a462dfce3495 (diff) |
Notes
Diffstat (limited to 'lib/dfsan')
-rw-r--r-- | lib/dfsan/CMakeLists.txt | 48 | ||||
-rw-r--r-- | lib/dfsan/dfsan.cc | 119 | ||||
-rw-r--r-- | lib/dfsan/dfsan.h | 12 | ||||
-rw-r--r-- | lib/dfsan/dfsan_custom.cc | 833 | ||||
-rw-r--r-- | lib/dfsan/done_abilist.txt | 255 | ||||
-rw-r--r-- | lib/dfsan/libc_ubuntu1404_abilist.txt (renamed from lib/dfsan/libc_ubuntu1204_abilist.txt) | 340 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/CMakeLists.txt | 21 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/Inputs/flags_abilist.txt | 10 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/basic.c | 21 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/custom.c | 154 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/flags.c | 24 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/fncall.c | 26 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/lit.cfg | 69 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/lit.site.cfg.in | 5 | ||||
-rw-r--r-- | lib/dfsan/lit_tests/propagate.c | 47 | ||||
-rwxr-xr-x | lib/dfsan/scripts/build-libc-list.py | 36 | ||||
-rwxr-xr-x | lib/dfsan/scripts/check_custom_wrappers.sh | 50 |
17 files changed, 1271 insertions, 799 deletions
diff --git a/lib/dfsan/CMakeLists.txt b/lib/dfsan/CMakeLists.txt index b952799ffb5b6..257a15a933011 100644 --- a/lib/dfsan/CMakeLists.txt +++ b/lib/dfsan/CMakeLists.txt @@ -5,40 +5,44 @@ set(DFSAN_RTL_SOURCES dfsan.cc dfsan_custom.cc dfsan_interceptors.cc) -set(DFSAN_RTL_CFLAGS - ${SANITIZER_COMMON_CFLAGS} - # Prevent clang from generating libc calls. - -ffreestanding) +set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) +# Prevent clang from generating libc calls. +append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CFLAGS) # Static runtime library. -set(DFSAN_RUNTIME_LIBRARIES) -set(arch "x86_64") -if(CAN_TARGET_${arch}) - add_compiler_rt_static_runtime(clang_rt.dfsan-${arch} ${arch} +add_custom_target(dfsan) +foreach(arch ${DFSAN_SUPPORTED_ARCH}) + set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS}) + append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS) + add_compiler_rt_runtime(clang_rt.dfsan-${arch} ${arch} STATIC SOURCES ${DFSAN_RTL_SOURCES} $<TARGET_OBJECTS:RTInterception.${arch}> $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> - CFLAGS ${DFSAN_RTL_CFLAGS} -fPIE) - add_compiler_rt_static_runtime(clang_rt.dfsan-libc-${arch} ${arch} + CFLAGS ${DFSAN_CFLAGS}) + set(DFSAN_NOLIBC_CFLAGS ${DFSAN_COMMON_CFLAGS} -DDFSAN_NOLIBC) + add_compiler_rt_runtime(clang_rt.dfsan-libc-${arch} ${arch} STATIC SOURCES ${DFSAN_RTL_SOURCES} $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> - CFLAGS ${DFSAN_RTL_CFLAGS} -fPIC -DDFSAN_NOLIBC) + CFLAGS ${DFSAN_NOLIBC_CFLAGS}) add_sanitizer_rt_symbols(clang_rt.dfsan-${arch} dfsan.syms.extra) - list(APPEND DFSAN_RUNTIME_LIBRARIES clang_rt.dfsan-${arch} - clang_rt.dfsan-${arch}-symbols) -endif() + add_dependencies(dfsan + clang_rt.dfsan-${arch} + clang_rt.dfsan-${arch}-symbols) +endforeach() +set(dfsan_abilist_filename ${COMPILER_RT_OUTPUT_DIR}/dfsan_abilist.txt) add_custom_target(dfsan_abilist ALL - SOURCES ${CLANG_RESOURCE_DIR}/dfsan_abilist.txt) -add_custom_command(OUTPUT ${CLANG_RESOURCE_DIR}/dfsan_abilist.txt + DEPENDS ${dfsan_abilist_filename}) +add_custom_command(OUTPUT ${dfsan_abilist_filename} VERBATIM COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt - ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1204_abilist.txt - > ${CLANG_RESOURCE_DIR}/dfsan_abilist.txt - DEPENDS done_abilist.txt libc_ubuntu1204_abilist.txt) -install(FILES ${CLANG_RESOURCE_DIR}/dfsan_abilist.txt - DESTINATION ${LIBCLANG_INSTALL_PATH}) + ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1404_abilist.txt + > ${dfsan_abilist_filename} + DEPENDS done_abilist.txt libc_ubuntu1404_abilist.txt) +add_dependencies(dfsan dfsan_abilist) +install(FILES ${dfsan_abilist_filename} + DESTINATION ${COMPILER_RT_INSTALL_PATH}) -add_subdirectory(lit_tests) +add_dependencies(compiler-rt dfsan) diff --git a/lib/dfsan/dfsan.cc b/lib/dfsan/dfsan.cc index 72d05c68604b6..941edc5eba7ad 100644 --- a/lib/dfsan/dfsan.cc +++ b/lib/dfsan/dfsan.cc @@ -63,17 +63,50 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64]; // account for the double byte representation of shadow labels and move the // address into the shadow memory range. See the function shadow_for below. +// On Linux/MIPS64, memory is laid out as follows: +// +// +--------------------+ 0x10000000000 (top of memory) +// | application memory | +// +--------------------+ 0xF000008000 (kAppAddr) +// | | +// | unused | +// | | +// +--------------------+ 0x2200000000 (kUnusedAddr) +// | union table | +// +--------------------+ 0x2000000000 (kUnionTableAddr) +// | shadow memory | +// +--------------------+ 0x0000010000 (kShadowAddr) +// | reserved by kernel | +// +--------------------+ 0x0000000000 + typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels]; +#if defined(__x86_64__) static const uptr kShadowAddr = 0x10000; static const uptr kUnionTableAddr = 0x200000000000; static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t); static const uptr kAppAddr = 0x700000008000; +#elif defined(__mips64) +static const uptr kShadowAddr = 0x10000; +static const uptr kUnionTableAddr = 0x2000000000; +static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t); +static const uptr kAppAddr = 0xF000008000; +#else +# error "DFSan not supported for this platform!" +#endif static atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) { return &(*(dfsan_union_table_t *) kUnionTableAddr)[l1][l2]; } +// Checks we do not run out of labels. +static void dfsan_check_label(dfsan_label label) { + if (label == kInitializingLabel) { + Report("FATAL: DataFlowSanitizer: out of labels\n"); + Die(); + } +} + // Resolves the union of two unequal labels. Nonequality is a precondition for // this function (the instrumentation pass inlines the equality test). extern "C" SANITIZER_INTERFACE_ATTRIBUTE @@ -106,7 +139,7 @@ dfsan_label __dfsan_union(dfsan_label l1, dfsan_label l2) { } else { label = atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1; - CHECK_NE(label, kInitializingLabel); + dfsan_check_label(label); __dfsan_label_info[label].l1 = l1; __dfsan_label_info[label].l2 = l2; } @@ -147,6 +180,15 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_nonzero_label() { Report("WARNING: DataFlowSanitizer: saw nonzero label\n"); } +// Indirect call to an uninstrumented vararg function. We don't have a way of +// handling these at the moment. +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__dfsan_vararg_wrapper(const char *fname) { + Report("FATAL: DataFlowSanitizer: unsupported indirect call to vararg " + "function %s\n", fname); + Die(); +} + // Like __dfsan_union, but for use from the client or custom functions. Hence // the equality comparison is done here before calling __dfsan_union. SANITIZER_INTERFACE_ATTRIBUTE dfsan_label @@ -160,7 +202,7 @@ extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label dfsan_create_label(const char *desc, void *userdata) { dfsan_label label = atomic_fetch_add(&__dfsan_last_label, 1, memory_order_relaxed) + 1; - CHECK_NE(label, kInitializingLabel); + dfsan_check_label(label); __dfsan_label_info[label].l1 = __dfsan_label_info[label].l2 = 0; __dfsan_label_info[label].desc = desc; __dfsan_label_info[label].userdata = userdata; @@ -169,8 +211,20 @@ dfsan_label dfsan_create_label(const char *desc, void *userdata) { extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __dfsan_set_label(dfsan_label label, void *addr, uptr size) { - for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) + for (dfsan_label *labelp = shadow_for(addr); size != 0; --size, ++labelp) { + // Don't write the label if it is already the value we need it to be. + // In a program where most addresses are not labeled, it is common that + // a page of shadow memory is entirely zeroed. The Linux copy-on-write + // implementation will share all of the zeroed pages, making a copy of a + // page when any value is written. The un-sharing will happen even if + // the value written does not change the value in memory. Avoiding the + // write when both |label| and |*labelp| are zero dramatically reduces + // the amount of real memory used by large programs. + if (label == *labelp) + continue; + *labelp = label; + } } SANITIZER_INTERFACE_ATTRIBUTE @@ -230,12 +284,58 @@ dfsan_has_label_with_desc(dfsan_label label, const char *desc) { } } +extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr +dfsan_get_label_count(void) { + dfsan_label max_label_allocated = + atomic_load(&__dfsan_last_label, memory_order_relaxed); + + return static_cast<uptr>(max_label_allocated); +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +dfsan_dump_labels(int fd) { + dfsan_label last_label = + atomic_load(&__dfsan_last_label, memory_order_relaxed); + + for (uptr l = 1; l <= last_label; ++l) { + char buf[64]; + internal_snprintf(buf, sizeof(buf), "%u %u %u ", l, + __dfsan_label_info[l].l1, __dfsan_label_info[l].l2); + internal_write(fd, buf, internal_strlen(buf)); + if (__dfsan_label_info[l].l1 == 0 && __dfsan_label_info[l].desc) { + internal_write(fd, __dfsan_label_info[l].desc, + internal_strlen(__dfsan_label_info[l].desc)); + } + internal_write(fd, "\n", 1); + } +} + static void InitializeFlags(Flags &f, const char *env) { f.warn_unimplemented = true; f.warn_nonzero_labels = false; + f.strict_data_dependencies = true; + f.dump_labels_at_exit = ""; + + ParseFlag(env, &f.warn_unimplemented, "warn_unimplemented", ""); + ParseFlag(env, &f.warn_nonzero_labels, "warn_nonzero_labels", ""); + ParseFlag(env, &f.strict_data_dependencies, "strict_data_dependencies", ""); + ParseFlag(env, &f.dump_labels_at_exit, "dump_labels_at_exit", ""); +} + +static void dfsan_fini() { + if (internal_strcmp(flags().dump_labels_at_exit, "") != 0) { + fd_t fd = OpenFile(flags().dump_labels_at_exit, true /* write */); + if (fd == kInvalidFd) { + Report("WARNING: DataFlowSanitizer: unable to open output file %s\n", + flags().dump_labels_at_exit); + return; + } - ParseFlag(env, &f.warn_unimplemented, "warn_unimplemented"); - ParseFlag(env, &f.warn_nonzero_labels, "warn_nonzero_labels"); + Report("INFO: DataFlowSanitizer: dumping labels to %s\n", + flags().dump_labels_at_exit); + dfsan_dump_labels(fd); + internal_close(fd); + } } #ifdef DFSAN_NOLIBC @@ -257,9 +357,16 @@ static void dfsan_init(int argc, char **argv, char **envp) { InitializeFlags(flags(), GetEnv("DFSAN_OPTIONS")); InitializeInterceptors(); + + // Register the fini callback to run when the program terminates successfully + // or it is killed by the runtime. + Atexit(dfsan_fini); + SetDieCallback(dfsan_fini); + + __dfsan_label_info[kInitializingLabel].desc = "<init label>"; } -#ifndef DFSAN_NOLIBC +#if !defined(DFSAN_NOLIBC) && SANITIZER_CAN_USE_PREINIT_ARRAY __attribute__((section(".preinit_array"), used)) static void (*dfsan_init_ptr)(int, char **, char **) = dfsan_init; #endif diff --git a/lib/dfsan/dfsan.h b/lib/dfsan/dfsan.h index 693e0c5efe04f..bc38be08c9cd8 100644 --- a/lib/dfsan/dfsan.h +++ b/lib/dfsan/dfsan.h @@ -28,6 +28,7 @@ struct dfsan_label_info { }; extern "C" { +void dfsan_add_label(dfsan_label label, void *addr, uptr size); void dfsan_set_label(dfsan_label label, void *addr, uptr size); dfsan_label dfsan_read_label(const void *addr, uptr size); dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2); @@ -43,7 +44,11 @@ namespace __dfsan { void InitializeInterceptors(); inline dfsan_label *shadow_for(void *ptr) { +#if defined(__x86_64__) return (dfsan_label *) ((((uptr) ptr) & ~0x700000000000) << 1); +#elif defined(__mips64) + return (dfsan_label *) ((((uptr) ptr) & ~0xF000000000) << 1); +#endif } inline const dfsan_label *shadow_for(const void *ptr) { @@ -55,6 +60,13 @@ struct Flags { bool warn_unimplemented; // Whether to warn on non-zero labels. bool warn_nonzero_labels; + // Whether to propagate labels only when there is an obvious data dependency + // (e.g., when comparing strings, ignore the fact that the output of the + // comparison might be data-dependent on the content of the strings). This + // applies only to the custom functions defined in 'custom.c'. + bool strict_data_dependencies; + // The path of the file where to dump the labels when the program terminates. + const char* dump_labels_at_exit; }; extern Flags flags_data; diff --git a/lib/dfsan/dfsan_custom.cc b/lib/dfsan/dfsan_custom.cc index 6a132db062b35..839a399faae0b 100644 --- a/lib/dfsan/dfsan_custom.cc +++ b/lib/dfsan/dfsan_custom.cc @@ -11,26 +11,39 @@ // // This file defines the custom functions listed in done_abilist.txt. //===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_linux.h" #include "dfsan/dfsan.h" +#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/types.h> +#include <sys/resource.h> +#include <sys/select.h> #include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> #include <time.h> #include <unistd.h> using namespace __dfsan; 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) { @@ -58,7 +71,12 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c, dfsan_label *ret_label) { for (size_t i = 0;; ++i) { if (s[i] == c || s[i] == 0) { - *ret_label = dfsan_union(dfsan_read_label(s, i+1), c_label); + if (flags().strict_data_dependencies) { + *ret_label = s_label; + } else { + *ret_label = dfsan_union(dfsan_read_label(s, i + 1), + dfsan_union(s_label, c_label)); + } return s[i] == 0 ? 0 : const_cast<char *>(s+i); } } @@ -72,13 +90,22 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2, const char *cs1 = (const char *) s1, *cs2 = (const char *) s2; for (size_t i = 0; i != n; ++i) { if (cs1[i] != cs2[i]) { - *ret_label = dfsan_union(dfsan_read_label(cs1, i+1), - dfsan_read_label(cs2, i+1)); + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1), + dfsan_read_label(cs2, i + 1)); + } return cs1[i] - cs2[i]; } } - *ret_label = dfsan_union(dfsan_read_label(cs1, n), - dfsan_read_label(cs2, n)); + + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(cs1, n), + dfsan_read_label(cs2, n)); + } return 0; } @@ -88,8 +115,12 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2, dfsan_label *ret_label) { for (size_t i = 0;; ++i) { if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) { - *ret_label = dfsan_union(dfsan_read_label(s1, i+1), - dfsan_read_label(s2, i+1)); + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), + dfsan_read_label(s2, i + 1)); + } return s1[i] - s2[i]; } } @@ -101,8 +132,12 @@ __dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label, dfsan_label *ret_label) { for (size_t i = 0;; ++i) { if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0) { - *ret_label = dfsan_union(dfsan_read_label(s1, i+1), - dfsan_read_label(s2, i+1)); + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), + dfsan_read_label(s2, i + 1)); + } return s1[i] - s2[i]; } } @@ -120,9 +155,13 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2, } for (size_t i = 0;; ++i) { - if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n-1) { - *ret_label = dfsan_union(dfsan_read_label(s1, i+1), - dfsan_read_label(s2, i+1)); + if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) { + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), + dfsan_read_label(s2, i + 1)); + } return s1[i] - s2[i]; } } @@ -141,8 +180,12 @@ __dfsw_strncasecmp(const char *s1, const char *s2, size_t n, for (size_t i = 0;; ++i) { if (tolower(s1[i]) != tolower(s2[i]) || s1[i] == 0 || s2[i] == 0 || i == n - 1) { - *ret_label = dfsan_union(dfsan_read_label(s1, i+1), - dfsan_read_label(s2, i+1)); + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_union(dfsan_read_label(s1, i + 1), + dfsan_read_label(s2, i + 1)); + } return s1[i] - s2[i]; } } @@ -162,14 +205,19 @@ SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size, SANITIZER_INTERFACE_ATTRIBUTE size_t __dfsw_strlen(const char *s, dfsan_label s_label, dfsan_label *ret_label) { size_t ret = strlen(s); - *ret_label = dfsan_read_label(s, ret+1); + if (flags().strict_data_dependencies) { + *ret_label = 0; + } else { + *ret_label = dfsan_read_label(s, ret + 1); + } return ret; } static void *dfsan_memcpy(void *dest, const void *src, size_t n) { - dfsan_label *sdest = shadow_for(dest), *ssrc = shadow_for((void *)src); - internal_memcpy((void *)sdest, (void *)ssrc, n * sizeof(dfsan_label)); + dfsan_label *sdest = shadow_for(dest); + const dfsan_label *ssrc = shadow_for(src); + internal_memcpy((void *)sdest, (const void *)ssrc, n * sizeof(dfsan_label)); return internal_memcpy(dest, src, n); } @@ -182,7 +230,7 @@ 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 = 0; + *ret_label = dest_label; return dfsan_memcpy(dest, src, n); } @@ -191,7 +239,7 @@ 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 = 0; + *ret_label = s_label; return s; } @@ -216,7 +264,7 @@ __dfsw_strncpy(char *s1, const char *s2, size_t n, dfsan_label s1_label, dfsan_memcpy(s1, s2, n); } - *ret_label = 0; + *ret_label = s1_label; return s1; } @@ -318,9 +366,11 @@ struct dl_iterate_phdr_info { 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, (void *)info->dlpi_name, strlen(info->dlpi_name) + 1); - dfsan_set_label(0, (void *)info->dlpi_phdr, - sizeof(*info->dlpi_phdr) * info->dlpi_phnum); + 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); @@ -338,4 +388,737 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_dl_iterate_phdr( return dl_iterate_phdr(dl_iterate_phdr_cb, &dipi); } +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 *__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 *__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 *__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 +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 __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 __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 +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) { + internal_memcpy(shadow_for(dest), shadow_for(src), + sizeof(dfsan_label) * (strlen(src) + 1)); + } + *ret_label = dst_label; + return ret; +} + +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 = strtol(nptr, &tmp_endptr, base); + if (endptr) { + *endptr = tmp_endptr; + } + 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; + } + return ret; +} + +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 = strtod(nptr, &tmp_endptr); + if (endptr) { + *endptr = tmp_endptr; + } + 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; + } + 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 = strtoll(nptr, &tmp_endptr, base); + if (endptr) { + *endptr = tmp_endptr; + } + 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; + } + 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 = strtoul(nptr, &tmp_endptr, base); + if (endptr) { + *endptr = tmp_endptr; + } + 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; + } + return ret; +} + +SANITIZER_INTERFACE_ATTRIBUTE +long long unsigned int __dfsw_strtoull(const char *nptr, char **endptr, + dfsan_label nptr_label, + int base, dfsan_label endptr_label, + dfsan_label base_label, + dfsan_label *ret_label) { + char *tmp_endptr; + long long unsigned int ret = strtoull(nptr, &tmp_endptr, base); + if (endptr) { + *endptr = tmp_endptr; + } + 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; + } + 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 +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 +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 +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 __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 __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 __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 __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)); + return ret; +} + +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) { + int ret = sigaction(signum, act, oldact); + if (oldact) { + dfsan_set_label(0, oldact, sizeof(struct sigaction)); + } + *ret_label = 0; + return ret; +} + +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 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 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 *__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 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 +__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; +} + +// 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); + +// 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 = NULL; + void *write_callback = NULL; +} write_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 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 != NULL) { + 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); +} + +// Type used to extract a dfsan_label with va_arg() +typedef int dfsan_label_va; + +// A chunk of data representing the output of formatting either a constant +// string or a single format directive. +struct Chunk { + // Address of the beginning of the formatted string + const char *ptr; + // Size of the formatted string + size_t size; + + // Type of DFSan label (depends on the format directive) + enum { + // Constant string, no argument and thus no label + NONE = 0, + // Label for an argument of '%n' + IGNORED, + // Label for a '%s' argument + STRING, + // Label for any other type of argument + NUMERIC, + } label_type; + + // Value of the argument (if label_type == STRING) + const char *arg; +}; + +// Formats the input. The output is stored in 'str' starting from offset +// 'off'. The format directive is represented by the first 'format_size' bytes +// of 'format'. If 'has_size' is true, 'size' bounds the number of output +// bytes. Returns the return value of the vsnprintf call used to format the +// input. +static int format_chunk(char *str, size_t off, bool has_size, size_t size, + const char *format, size_t format_size, ...) { + char *chunk_format = (char *) malloc(format_size + 1); + assert(chunk_format); + internal_memcpy(chunk_format, format, format_size); + chunk_format[format_size] = '\0'; + + va_list ap; + va_start(ap, format_size); + int r = 0; + if (has_size) { + r = vsnprintf(str + off, off < size ? size - off : 0, chunk_format, ap); + } else { + r = vsprintf(str + off, chunk_format, ap); + } + va_end(ap); + + free(chunk_format); + return r; +} + +// Formats the input and propagates the input labels to the output. The output +// is stored in 'str'. If 'has_size' is true, '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. +static int format_buffer(char *str, bool has_size, size_t size, + const char *format, dfsan_label *va_labels, + dfsan_label *ret_label, va_list ap) { + InternalMmapVector<Chunk> chunks(8); + size_t off = 0; + + while (*format) { + chunks.push_back(Chunk()); + Chunk& chunk = chunks.back(); + chunk.ptr = str + off; + chunk.arg = nullptr; + + int status = 0; + + if (*format != '%') { + // Ordinary character. Consume all the characters until a '%' or the end + // of the string. + size_t format_size = 0; + for (; *format && *format != '%'; ++format, ++format_size) {} + status = format_chunk(str, off, has_size, size, format - format_size, + format_size); + chunk.label_type = Chunk::NONE; + } else { + // Conversion directive. Consume all the characters until a conversion + // specifier or the end of the string. + bool end_format = false; +#define FORMAT_CHUNK(t) \ + format_chunk(str, off, has_size, size, format - format_size, \ + format_size + 1, va_arg(ap, t)) + + for (size_t format_size = 1; *++format && !end_format; ++format_size) { + switch (*format) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + switch (*(format - 1)) { + case 'h': + // Also covers the 'hh' case (since the size of the arg is still + // an int). + status = FORMAT_CHUNK(int); + break; + case 'l': + if (format_size >= 2 && *(format - 2) == 'l') { + status = FORMAT_CHUNK(long long int); + } else { + status = FORMAT_CHUNK(long int); + } + break; + case 'q': + status = FORMAT_CHUNK(long long int); + break; + case 'j': + status = FORMAT_CHUNK(intmax_t); + break; + case 'z': + status = FORMAT_CHUNK(size_t); + break; + case 't': + status = FORMAT_CHUNK(size_t); + break; + default: + status = FORMAT_CHUNK(int); + } + chunk.label_type = Chunk::NUMERIC; + end_format = true; + break; + + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + if (*(format - 1) == 'L') { + status = FORMAT_CHUNK(long double); + } else { + status = FORMAT_CHUNK(double); + } + chunk.label_type = Chunk::NUMERIC; + end_format = true; + break; + + case 'c': + status = FORMAT_CHUNK(int); + chunk.label_type = Chunk::NUMERIC; + end_format = true; + break; + + case 's': + chunk.arg = va_arg(ap, char *); + status = + format_chunk(str, off, has_size, size, + format - format_size, format_size + 1, + chunk.arg); + chunk.label_type = Chunk::STRING; + end_format = true; + break; + + case 'p': + status = FORMAT_CHUNK(void *); + chunk.label_type = Chunk::NUMERIC; + end_format = true; + break; + + case 'n': + *(va_arg(ap, int *)) = (int)off; + chunk.label_type = Chunk::IGNORED; + end_format = true; + break; + + case '%': + status = format_chunk(str, off, has_size, size, + format - format_size, format_size + 1); + chunk.label_type = Chunk::NONE; + end_format = true; + break; + + default: + break; + } + } +#undef FORMAT_CHUNK + } + + if (status < 0) { + return status; + } + + // A return value of {v,}snprintf of size or more means that the output was + // truncated. + if (has_size) { + if (off < size) { + size_t ustatus = (size_t) status; + chunk.size = ustatus >= (size - off) ? + ustatus - (size - off) : ustatus; + } else { + chunk.size = 0; + } + } else { + chunk.size = status; + } + off += status; + } + + // TODO(martignlo): Decide how to combine labels (e.g., whether to ignore or + // not the label of the format string). + + // Label each output chunk according to the label supplied as argument to the + // function. We need to go through all the chunks and arguments even if the + // string was only partially printed ({v,}snprintf case). + for (size_t i = 0; i < chunks.size(); ++i) { + const Chunk& chunk = chunks[i]; + void *chunk_ptr = const_cast<char *>(chunk.ptr); + + switch (chunk.label_type) { + case Chunk::NONE: + dfsan_set_label(0, chunk_ptr, chunk.size); + break; + case Chunk::IGNORED: + va_labels++; + dfsan_set_label(0, chunk_ptr, chunk.size); + break; + case Chunk::NUMERIC: { + dfsan_label label = *va_labels++; + dfsan_set_label(label, chunk_ptr, chunk.size); + break; + } + case Chunk::STRING: { + // Consume the label of the pointer to the string + va_labels++; + internal_memcpy(shadow_for(chunk_ptr), + shadow_for(chunk.arg), + sizeof(dfsan_label) * (strlen(chunk.arg))); + break; + } + } + } + + *ret_label = 0; + + // Number of bytes written in total. + return off; +} + +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, false, 0, format, va_labels, ret_label, 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, true, size, format, va_labels, ret_label, ap); + va_end(ap); + return ret; +} } diff --git a/lib/dfsan/done_abilist.txt b/lib/dfsan/done_abilist.txt index 27df3e9b707c9..15c6d1bb2e390 100644 --- a/lib/dfsan/done_abilist.txt +++ b/lib/dfsan/done_abilist.txt @@ -1,38 +1,41 @@ fun:main=uninstrumented fun:main=discard -# DFSan interface functions. +############################################################################### +# DFSan interface functions +############################################################################### fun:dfsan_union=uninstrumented fun:dfsan_union=discard - fun:dfsan_create_label=uninstrumented fun:dfsan_create_label=discard - fun:dfsan_set_label=uninstrumented fun:dfsan_set_label=discard - fun:dfsan_add_label=uninstrumented fun:dfsan_add_label=discard - fun:dfsan_get_label=uninstrumented fun:dfsan_get_label=custom - fun:dfsan_read_label=uninstrumented fun:dfsan_read_label=discard - +fun:dfsan_get_label_count=uninstrumented +fun:dfsan_get_label_count=discard fun:dfsan_get_label_info=uninstrumented fun:dfsan_get_label_info=discard - fun:dfsan_has_label=uninstrumented fun:dfsan_has_label=discard - fun:dfsan_has_label_with_desc=uninstrumented fun:dfsan_has_label_with_desc=discard +fun:dfsan_set_write_callback=uninstrumented +fun:dfsan_set_write_callback=custom -# glibc functions. +############################################################################### +# glibc +############################################################################### fun:malloc=discard fun:realloc=discard fun:free=discard + +# Functions that return a value that depends on the input, but the output might +# not be necessarily data-dependent on the input. fun:isalpha=functional fun:isdigit=functional fun:isprint=functional @@ -42,86 +45,216 @@ fun:ispunct=functional fun:isspace=functional fun:tolower=functional fun:toupper=functional + +# Functions that return a value that is data-dependent on the input. +fun:btowc=functional fun:exp=functional fun:exp2=functional +fun:fabs=functional +fun:finite=functional +fun:floor=functional +fun:fmod=functional +fun:isinf=functional +fun:isnan=functional fun:log=functional +fun:modf=functional +fun:pow=functional +fun:round=functional fun:sqrt=functional -fun:__cxa_atexit=discard -fun:open=discard -fun:pthread_key_create=discard -fun:getenv=discard +fun:wctob=functional + +# Functions that produce an output that does not depend on the input (shadow is +# zeroed automatically). +fun:__assert_fail=discard fun:__ctype_b_loc=discard +fun:__cxa_atexit=discard fun:__errno_location=discard -fun:mmap=discard -fun:munmap=discard -fun:write=discard +fun:__newlocale=discard +fun:__sbrk=discard +fun:__sigsetjmp=discard +fun:__uselocale=discard +fun:__wctype_l=discard +fun:access=discard +fun:alarm=discard +fun:atexit=discard +fun:bind=discard +fun:chdir=discard fun:close=discard -fun:pthread_equal=discard -fun:pthread_getspecific=discard -fun:pthread_setspecific=discard -fun:pthread_mutex_destroy=discard -fun:pthread_mutexattr_init=discard -fun:pthread_mutexattr_settype=discard -fun:pthread_mutex_init=discard -fun:pthread_mutex_lock=discard -fun:pthread_mutex_trylock=discard -fun:pthread_mutex_unlock=discard -fun:pthread_mutexattr_destroy=discard -fun:pthread_once=discard -fun:pthread_key_delete=discard -fun:pthread_self=discard -fun:printf=discard +fun:closedir=discard +fun:connect=discard +fun:dladdr=discard +fun:dlclose=discard +fun:fclose=discard +fun:feof=discard +fun:ferror=discard +fun:fflush=discard +fun:fileno=discard +fun:fopen=discard fun:fprintf=discard -fun:fputs=discard fun:fputc=discard -fun:fopen=discard +fun:fputc=discard +fun:fputs=discard +fun:fputs=discard fun:fseek=discard -fun:lseek=discard fun:ftell=discard -fun:fclose=discard -fun:dladdr=discard +fun:fwrite=discard +fun:getenv=discard +fun:getuid=discard +fun:geteuid=discard fun:getpagesize=discard +fun:getpid=discard +fun:kill=discard +fun:listen=discard +fun:lseek=discard +fun:mkdir=discard +fun:mmap=discard +fun:munmap=discard +fun:open=discard +fun:pipe=discard +fun:posix_fadvise=discard +fun:posix_memalign=discard +fun:prctl=discard +fun:printf=discard +fun:pthread_sigmask=discard +fun:putc=discard +fun:putchar=discard +fun:puts=discard +fun:rand=discard +fun:random=discard +fun:remove=discard fun:sched_getcpu=discard -fun:sched_getaffinity=discard +fun:sched_get_priority_max=discard fun:sched_setaffinity=discard -fun:syscall=discard +fun:sched_yield=discard +fun:sem_destroy=discard fun:sem_init=discard fun:sem_post=discard fun:sem_wait=discard -fun:sched_yield=discard -fun:uselocale=discard -fun:rand=discard -fun:random=discard +fun:send=discard +fun:sendmsg=discard +fun:sendto=discard +fun:setsockopt=discard +fun:shutdown=discard fun:sleep=discard +fun:socket=discard +fun:strerror=discard +fun:strspn=discard +fun:strcspn=discard +fun:symlink=discard +fun:syscall=discard +fun:unlink=discard +fun:uselocale=discard -fun:stat=custom +# Functions that produce output does not depend on the input (need to zero the +# shadow manually). +fun:calloc=custom +fun:clock_gettime=custom +fun:dlopen=custom +fun:fgets=custom fun:fstat=custom -fun:memcmp=custom +fun:getcwd=custom +fun:get_current_dir_name=custom +fun:gethostname=custom +fun:getrlimit=custom +fun:getrusage=custom +fun:nanosleep=custom +fun:pread=custom +fun:read=custom +fun:socketpair=custom +fun:stat=custom +fun:time=custom + +# Functions that produce an output that depend on the input (propagate the +# shadow manually). +fun:ctime_r=custom +fun:inet_pton=custom +fun:localtime_r=custom fun:memcpy=custom fun:memset=custom -fun:strcmp=custom +fun:strcpy=custom fun:strdup=custom -fun:strncmp=custom fun:strncpy=custom +fun:strtod=custom +fun:strtol=custom +fun:strtoll=custom +fun:strtoul=custom +fun:strtoull=custom + +# Functions that produce an output that is computed from the input, but is not +# necessarily data dependent. +fun:memchr=custom +fun:memcmp=custom fun:strcasecmp=custom -fun:strncasecmp=custom fun:strchr=custom +fun:strcmp=custom fun:strlen=custom -fun:calloc=custom -fun:dlopen=custom -fun:read=custom -fun:pread=custom -fun:clock_gettime=custom -fun:pthread_create=custom +fun:strncasecmp=custom +fun:strncmp=custom +fun:strrchr=custom +fun:strstr=custom + +# Functions which take action based on global state, such as running a callback +# set by a sepperate function. +fun:write=custom + +# Functions that take a callback (wrap the callback manually). fun:dl_iterate_phdr=custom +fun:getpwuid_r=custom +fun:poll=custom +fun:sched_getaffinity=custom +fun:select=custom +fun:sigemptyset=custom +fun:sigaction=custom +fun:gettimeofday=custom + +# sprintf-like +fun:sprintf=custom +fun:snprintf=custom + # TODO: custom -fun:snprintf=discard -fun:vsnprintf=discard fun:asprintf=discard fun:qsort=discard -fun:strtoll=discard -fun:strtoull=discard -fun:sigemptyset=discard -fun:sigaction=discard -fun:gettimeofday=discard + +############################################################################### +# pthread +############################################################################### +fun:pthread_equal=discard +fun:pthread_getspecific=discard +fun:pthread_key_create=discard +fun:pthread_key_delete=discard +fun:pthread_mutex_destroy=discard +fun:pthread_mutex_init=discard +fun:pthread_mutex_lock=discard +fun:pthread_mutex_trylock=discard +fun:pthread_mutex_unlock=discard +fun:pthread_mutexattr_destroy=discard +fun:pthread_mutexattr_init=discard +fun:pthread_mutexattr_settype=discard +fun:pthread_once=discard +fun:pthread_self=discard +fun:pthread_setspecific=discard + +# Functions that take a callback (wrap the callback manually). +fun:pthread_create=custom + +############################################################################### +# libffi/libgo +############################################################################### +# Functions that are written in asm or are called from asm. +fun:ffi_call_unix64=uninstrumented +fun:ffi_call_unix64=discard +fun:ffi_closure_unix64_inner=uninstrumented +fun:ffi_closure_unix64_inner=discard +fun:ffi_closure_unix64=uninstrumented +fun:ffi_closure_unix64=discard +fun:__go_get_closure=uninstrumented +fun:__go_get_closure=discard +fun:__go_makefunc_can_recover=uninstrumented +fun:__go_makefunc_can_recover=discard +fun:__go_makefunc_returning=uninstrumented +fun:__go_makefunc_returning=discard +fun:reflect.MakeFuncStubGo=uninstrumented +fun:reflect.MakeFuncStubGo=discard +fun:reflect.makeFuncStub=uninstrumented +fun:reflect.makeFuncStub=discard diff --git a/lib/dfsan/libc_ubuntu1204_abilist.txt b/lib/dfsan/libc_ubuntu1404_abilist.txt index 5fc8194c8f164..a1ea0a06b5375 100644 --- a/lib/dfsan/libc_ubuntu1204_abilist.txt +++ b/lib/dfsan/libc_ubuntu1404_abilist.txt @@ -123,83 +123,6 @@ fun:_IO_wfile_underflow=uninstrumented fun:_IO_wfile_xsputn=uninstrumented fun:_IO_wmarker_delta=uninstrumented fun:_IO_wsetb=uninstrumented -fun:_L_cond_lock_1021=uninstrumented -fun:_L_cond_lock_874=uninstrumented -fun:_L_cond_lock_918=uninstrumented -fun:_L_lock_1006=uninstrumented -fun:_L_lock_125=uninstrumented -fun:_L_lock_1281=uninstrumented -fun:_L_lock_13=uninstrumented -fun:_L_lock_133=uninstrumented -fun:_L_lock_1392=uninstrumented -fun:_L_lock_175=uninstrumented -fun:_L_lock_19=uninstrumented -fun:_L_lock_2009=uninstrumented -fun:_L_lock_21=uninstrumented -fun:_L_lock_211=uninstrumented -fun:_L_lock_2143=uninstrumented -fun:_L_lock_227=uninstrumented -fun:_L_lock_23=uninstrumented -fun:_L_lock_2338=uninstrumented -fun:_L_lock_26=uninstrumented -fun:_L_lock_29=uninstrumented -fun:_L_lock_3116=uninstrumented -fun:_L_lock_32=uninstrumented -fun:_L_lock_3335=uninstrumented -fun:_L_lock_34=uninstrumented -fun:_L_lock_37=uninstrumented -fun:_L_lock_40=uninstrumented -fun:_L_lock_4016=uninstrumented -fun:_L_lock_4410=uninstrumented -fun:_L_lock_451=uninstrumented -fun:_L_lock_4590=uninstrumented -fun:_L_lock_466=uninstrumented -fun:_L_lock_641=uninstrumented -fun:_L_lock_858=uninstrumented -fun:_L_lock_903=uninstrumented -fun:_L_robust_cond_lock_164=uninstrumented -fun:_L_robust_lock_160=uninstrumented -fun:_L_robust_timedlock_361=uninstrumented -fun:_L_robust_unlock_189=uninstrumented -fun:_L_timedlock_1043=uninstrumented -fun:_L_timedlock_108=uninstrumented -fun:_L_timedlock_292=uninstrumented -fun:_L_unlock_114=uninstrumented -fun:_L_unlock_1157=uninstrumented -fun:_L_unlock_1355=uninstrumented -fun:_L_unlock_137=uninstrumented -fun:_L_unlock_157=uninstrumented -fun:_L_unlock_16=uninstrumented -fun:_L_unlock_170=uninstrumented -fun:_L_unlock_174=uninstrumented -fun:_L_unlock_177=uninstrumented -fun:_L_unlock_1946=uninstrumented -fun:_L_unlock_197=uninstrumented -fun:_L_unlock_2117=uninstrumented -fun:_L_unlock_2318=uninstrumented -fun:_L_unlock_2384=uninstrumented -fun:_L_unlock_27=uninstrumented -fun:_L_unlock_3119=uninstrumented -fun:_L_unlock_312=uninstrumented -fun:_L_unlock_3464=uninstrumented -fun:_L_unlock_37=uninstrumented -fun:_L_unlock_3744=uninstrumented -fun:_L_unlock_4037=uninstrumented -fun:_L_unlock_43=uninstrumented -fun:_L_unlock_4353=uninstrumented -fun:_L_unlock_4432=uninstrumented -fun:_L_unlock_4525=uninstrumented -fun:_L_unlock_4619=uninstrumented -fun:_L_unlock_494=uninstrumented -fun:_L_unlock_54=uninstrumented -fun:_L_unlock_544=uninstrumented -fun:_L_unlock_61=uninstrumented -fun:_L_unlock_62=uninstrumented -fun:_L_unlock_64=uninstrumented -fun:_L_unlock_644=uninstrumented -fun:_L_unlock_698=uninstrumented -fun:_L_unlock_708=uninstrumented -fun:_L_unlock_88=uninstrumented fun:_Unwind_Backtrace=uninstrumented fun:_Unwind_DeleteException=uninstrumented fun:_Unwind_FindEnclosingFunction=uninstrumented @@ -218,18 +141,9 @@ fun:_Unwind_Resume=uninstrumented fun:_Unwind_Resume_or_Rethrow=uninstrumented fun:_Unwind_SetGR=uninstrumented fun:_Unwind_SetIP=uninstrumented -fun:__GI___nptl_create_event=uninstrumented -fun:__GI___nptl_death_event=uninstrumented -fun:__GI___pthread_cleanup_upto=uninstrumented -fun:__GI___pthread_register_cancel=uninstrumented -fun:__GI___pthread_unregister_cancel=uninstrumented -fun:__GI___pthread_unwind=uninstrumented -fun:__GI___pthread_unwind_next=uninstrumented fun:__absvdi2=uninstrumented fun:__absvsi2=uninstrumented fun:__absvti2=uninstrumented -fun:__accept=uninstrumented -fun:__accept_nocancel=uninstrumented fun:__acos_finite=uninstrumented fun:__acosf_finite=uninstrumented fun:__acosh_finite=uninstrumented @@ -602,27 +516,31 @@ fun:__bsd_getpgrp=uninstrumented fun:__bswapdi2=uninstrumented fun:__bswapsi2=uninstrumented fun:__bzero=uninstrumented +fun:__call_tls_dtors=uninstrumented fun:__chk_fail=uninstrumented fun:__clear_cache=uninstrumented +fun:__clock_getcpuclockid=uninstrumented +fun:__clock_getres=uninstrumented +fun:__clock_gettime=uninstrumented +fun:__clock_nanosleep=uninstrumented +fun:__clock_settime=uninstrumented fun:__clog10=uninstrumented fun:__clog10f=uninstrumented fun:__clog10l=uninstrumented fun:__clone=uninstrumented fun:__close=uninstrumented -fun:__close_nocancel=uninstrumented +fun:__clrsbdi2=uninstrumented +fun:__clrsbti2=uninstrumented fun:__clzdi2=uninstrumented fun:__clzti2=uninstrumented fun:__cmpti2=uninstrumented fun:__cmsg_nxthdr=uninstrumented -fun:__condvar_cleanup1=uninstrumented -fun:__condvar_cleanup2=uninstrumented fun:__confstr_chk=uninstrumented fun:__connect=uninstrumented -fun:__connect_internal=uninstrumented -fun:__connect_nocancel=uninstrumented fun:__cosh_finite=uninstrumented fun:__coshf_finite=uninstrumented fun:__coshl_finite=uninstrumented +fun:__cpu_indicator_init=uninstrumented fun:__create_ib_request=uninstrumented fun:__ctype_b_loc=uninstrumented fun:__ctype_get_mb_cur_max=uninstrumented @@ -634,15 +552,14 @@ fun:__ctzti2=uninstrumented fun:__cxa_at_quick_exit=uninstrumented fun:__cxa_atexit=uninstrumented fun:__cxa_finalize=uninstrumented +fun:__cxa_thread_atexit_impl=uninstrumented fun:__cyg_profile_func_enter=uninstrumented fun:__cyg_profile_func_exit=uninstrumented fun:__dcgettext=uninstrumented -fun:__deallocate_stack=uninstrumented fun:__default_morecore=uninstrumented fun:__deregister_frame=uninstrumented fun:__deregister_frame_info=uninstrumented fun:__deregister_frame_info_bases=uninstrumented -fun:__determine_cpumask_size=uninstrumented fun:__dfp_clear_except=uninstrumented fun:__dfp_get_round=uninstrumented fun:__dfp_raise_except=uninstrumented @@ -659,13 +576,10 @@ fun:__dn_comp=uninstrumented fun:__dn_count_labels=uninstrumented fun:__dn_expand=uninstrumented fun:__dn_skipname=uninstrumented -fun:__do_global_ctors_aux=uninstrumented -fun:__do_global_dtors_aux=uninstrumented fun:__do_niscall3=uninstrumented fun:__dprintf_chk=uninstrumented fun:__dup2=uninstrumented fun:__duplocale=uninstrumented -fun:__dyn_pthread_atfork=uninstrumented fun:__emutls_get_address=uninstrumented fun:__emutls_register_common=uninstrumented fun:__enable_execute_stack=uninstrumented @@ -687,7 +601,6 @@ fun:__extendsftf2=uninstrumented fun:__extendxftf2=uninstrumented fun:__fbufsize=uninstrumented fun:__fcntl=uninstrumented -fun:__fcntl_nocancel=uninstrumented fun:__fdelt_chk=uninstrumented fun:__fdelt_warn=uninstrumented fun:__fentry__=uninstrumented @@ -698,8 +611,6 @@ fun:__fgets_chk=uninstrumented fun:__fgets_unlocked_chk=uninstrumented fun:__fgetws_chk=uninstrumented fun:__fgetws_unlocked_chk=uninstrumented -fun:__find_in_stack_list=uninstrumented -fun:__find_thread_by_id=uninstrumented fun:__finite=uninstrumented fun:__finitef=uninstrumented fun:__finitel=uninstrumented @@ -731,7 +642,6 @@ fun:__floatuntidf=uninstrumented fun:__floatuntisf=uninstrumented fun:__floatuntitf=uninstrumented fun:__floatuntixf=uninstrumented -fun:__flockfile=uninstrumented fun:__fmod_finite=uninstrumented fun:__fmodf_finite=uninstrumented fun:__fmodl_finite=uninstrumented @@ -752,14 +662,9 @@ fun:__fread_unlocked_chk=uninstrumented fun:__freadable=uninstrumented fun:__freading=uninstrumented fun:__free_fdresult=uninstrumented -fun:__free_stacks=uninstrumented -fun:__free_tcb=uninstrumented fun:__freelocale=uninstrumented fun:__fsetlocking=uninstrumented fun:__fstat=uninstrumented -fun:__fsync_nocancel=uninstrumented -fun:__ftrylockfile=uninstrumented -fun:__funlockfile=uninstrumented fun:__fwprintf_chk=uninstrumented fun:__fwritable=uninstrumented fun:__fwriting=uninstrumented @@ -781,6 +686,7 @@ fun:__generic_morestack=uninstrumented fun:__generic_morestack_set_initial_sp=uninstrumented fun:__generic_releasestack=uninstrumented fun:__get_cpu_features=uninstrumented +fun:__getauxval=uninstrumented fun:__getcwd_chk=uninstrumented fun:__getdelim=uninstrumented fun:__getdomainname_chk=uninstrumented @@ -802,7 +708,6 @@ fun:__hostalias=uninstrumented fun:__hypot_finite=uninstrumented fun:__hypotf_finite=uninstrumented fun:__hypotl_finite=uninstrumented -fun:__init_sched_fifo_prio=uninstrumented fun:__internal_endnetgrent=uninstrumented fun:__internal_getnetgrent_r=uninstrumented fun:__internal_setnetgrent=uninstrumented @@ -835,6 +740,9 @@ fun:__isoc99_vwscanf=uninstrumented fun:__isoc99_wscanf=uninstrumented fun:__isprint_l=uninstrumented fun:__ispunct_l=uninstrumented +fun:__issignaling=uninstrumented +fun:__issignalingf=uninstrumented +fun:__issignalingl=uninstrumented fun:__isspace_l=uninstrumented fun:__isupper_l=uninstrumented fun:__iswalnum_l=uninstrumented @@ -866,14 +774,11 @@ fun:__letf2=uninstrumented fun:__lgamma_r_finite=uninstrumented fun:__lgammaf_r_finite=uninstrumented fun:__lgammal_r_finite=uninstrumented -fun:__libc_accept=uninstrumented fun:__libc_alloca_cutoff=uninstrumented fun:__libc_allocate_rtsig=uninstrumented fun:__libc_allocate_rtsig_private=uninstrumented fun:__libc_calloc=uninstrumented fun:__libc_clntudp_bufcreate=uninstrumented -fun:__libc_close=uninstrumented -fun:__libc_connect=uninstrumented fun:__libc_csu_fini=uninstrumented fun:__libc_csu_init=uninstrumented fun:__libc_current_sigrtmax=uninstrumented @@ -885,62 +790,30 @@ fun:__libc_dlclose=uninstrumented fun:__libc_dlopen_mode=uninstrumented fun:__libc_dlsym=uninstrumented fun:__libc_fatal=uninstrumented -fun:__libc_fcntl=uninstrumented fun:__libc_fork=uninstrumented fun:__libc_free=uninstrumented fun:__libc_freeres=uninstrumented -fun:__libc_fsync=uninstrumented +fun:__libc_ifunc_impl_list=uninstrumented fun:__libc_init_first=uninstrumented fun:__libc_longjmp=uninstrumented -fun:__libc_lseek=uninstrumented -fun:__libc_lseek64=uninstrumented fun:__libc_mallinfo=uninstrumented fun:__libc_malloc=uninstrumented fun:__libc_mallopt=uninstrumented fun:__libc_memalign=uninstrumented -fun:__libc_msync=uninstrumented -fun:__libc_nanosleep=uninstrumented -fun:__libc_open=uninstrumented -fun:__libc_pause=uninstrumented -fun:__libc_pread=uninstrumented -fun:__libc_pread64=uninstrumented fun:__libc_pthread_init=uninstrumented fun:__libc_pvalloc=uninstrumented fun:__libc_pwrite=uninstrumented -fun:__libc_pwrite64=uninstrumented -fun:__libc_read=uninstrumented fun:__libc_realloc=uninstrumented -fun:__libc_recv=uninstrumented -fun:__libc_recvfrom=uninstrumented -fun:__libc_recvmsg=uninstrumented fun:__libc_res_nquery=uninstrumented fun:__libc_res_nsearch=uninstrumented fun:__libc_rpc_getport=uninstrumented fun:__libc_sa_len=uninstrumented -fun:__libc_send=uninstrumented -fun:__libc_sendmsg=uninstrumented -fun:__libc_sendto=uninstrumented -fun:__libc_sigaction=uninstrumented +fun:__libc_secure_getenv=uninstrumented fun:__libc_siglongjmp=uninstrumented -fun:__libc_sigsuspend=uninstrumented -fun:__libc_sigwait=uninstrumented fun:__libc_start_main=uninstrumented fun:__libc_system=uninstrumented -fun:__libc_tcdrain=uninstrumented fun:__libc_thread_freeres=uninstrumented fun:__libc_valloc=uninstrumented -fun:__libc_wait=uninstrumented -fun:__libc_waitpid=uninstrumented -fun:__libc_write=uninstrumented -fun:__lll_lock_wait=uninstrumented -fun:__lll_lock_wait_private=uninstrumented -fun:__lll_robust_lock_wait=uninstrumented -fun:__lll_robust_timedlock_wait=uninstrumented -fun:__lll_timedlock_wait=uninstrumented -fun:__lll_timedwait_tid=uninstrumented -fun:__lll_unlock_wake=uninstrumented -fun:__lll_unlock_wake_private=uninstrumented -fun:__llseek=uninstrumented fun:__loc_aton=uninstrumented fun:__loc_ntoa=uninstrumented fun:__log10_finite=uninstrumented @@ -954,14 +827,12 @@ fun:__logf_finite=uninstrumented fun:__logl_finite=uninstrumented fun:__longjmp_chk=uninstrumented fun:__lseek=uninstrumented -fun:__lseek64=uninstrumented -fun:__lseek_nocancel=uninstrumented fun:__lshrti3=uninstrumented fun:__lstat=uninstrumented fun:__lttf2=uninstrumented fun:__lxstat=uninstrumented fun:__lxstat64=uninstrumented -fun:__make_stacks_executable=uninstrumented +fun:__madvise=uninstrumented fun:__mbrlen=uninstrumented fun:__mbrtowc=uninstrumented fun:__mbsnrtowcs_chk=uninstrumented @@ -974,23 +845,22 @@ fun:__mempcpy_chk=uninstrumented fun:__mempcpy_small=uninstrumented fun:__memset_chk=uninstrumented fun:__mknod=uninstrumented +fun:__mktemp=uninstrumented fun:__modti3=uninstrumented fun:__monstartup=uninstrumented fun:__morestack=uninstrumented fun:__morestack_allocate_stack_space=uninstrumented fun:__morestack_block_signals=uninstrumented fun:__morestack_fail=uninstrumented +fun:__morestack_get_guard=uninstrumented fun:__morestack_large_model=uninstrumented fun:__morestack_load_mmap=uninstrumented +fun:__morestack_make_guard=uninstrumented fun:__morestack_non_split=uninstrumented fun:__morestack_release_segments=uninstrumented +fun:__morestack_set_guard=uninstrumented fun:__morestack_unblock_signals=uninstrumented fun:__mq_open_2=uninstrumented -fun:__msgrcv=uninstrumented -fun:__msgrcv_nocancel=uninstrumented -fun:__msgsnd=uninstrumented -fun:__msgsnd_nocancel=uninstrumented -fun:__msync_nocancel=uninstrumented fun:__muldc3=uninstrumented fun:__mulsc3=uninstrumented fun:__multc3=uninstrumented @@ -1001,16 +871,12 @@ fun:__mulvsi3=uninstrumented fun:__mulvti3=uninstrumented fun:__mulxc3=uninstrumented fun:__nanosleep=uninstrumented -fun:__nanosleep_nocancel=uninstrumented fun:__negtf2=uninstrumented fun:__negti2=uninstrumented fun:__negvdi2=uninstrumented fun:__negvsi2=uninstrumented fun:__negvti2=uninstrumented fun:__netf2=uninstrumented -fun:__new_sem_destroy=uninstrumented -fun:__new_sem_getvalue=uninstrumented -fun:__new_sem_init=uninstrumented fun:__newlocale=uninstrumented fun:__nis_default_access=uninstrumented fun:__nis_default_group=uninstrumented @@ -1023,12 +889,6 @@ fun:__nisbind_create=uninstrumented fun:__nisbind_destroy=uninstrumented fun:__nisbind_next=uninstrumented fun:__nl_langinfo_l=uninstrumented -fun:__nptl_create_event=uninstrumented -fun:__nptl_deallocate_tsd=uninstrumented -fun:__nptl_death_event=uninstrumented -fun:__nptl_main=uninstrumented -fun:__nptl_set_robust=uninstrumented -fun:__nptl_setxid=uninstrumented fun:__ns_get16=uninstrumented fun:__ns_get32=uninstrumented fun:__ns_name_ntop=uninstrumented @@ -1055,7 +915,6 @@ fun:__open64=uninstrumented fun:__open64_2=uninstrumented fun:__open_2=uninstrumented fun:__open_catalog=uninstrumented -fun:__open_nocancel=uninstrumented fun:__openat64_2=uninstrumented fun:__openat_2=uninstrumented fun:__overflow=uninstrumented @@ -1072,9 +931,9 @@ fun:__p_time=uninstrumented fun:__p_type=uninstrumented fun:__paritydi2=uninstrumented fun:__parityti2=uninstrumented -fun:__pause_nocancel=uninstrumented fun:__pipe=uninstrumented fun:__poll=uninstrumented +fun:__poll_chk=uninstrumented fun:__popcountdi2=uninstrumented fun:__popcountti2=uninstrumented fun:__posix_getopt=uninstrumented @@ -1085,121 +944,41 @@ fun:__powisf2=uninstrumented fun:__powitf2=uninstrumented fun:__powixf2=uninstrumented fun:__powl_finite=uninstrumented -fun:__pread=uninstrumented +fun:__ppoll_chk=uninstrumented fun:__pread64=uninstrumented fun:__pread64_chk=uninstrumented fun:__pread_chk=uninstrumented -fun:__pread_nocancel=uninstrumented fun:__prepare_niscall=uninstrumented fun:__printf_chk=uninstrumented fun:__printf_fp=uninstrumented fun:__profile_frequency=uninstrumented fun:__pthread_atfork=uninstrumented -fun:__pthread_attr_destroy=uninstrumented -fun:__pthread_attr_getaffinity_new=uninstrumented -fun:__pthread_attr_getaffinity_old=uninstrumented -fun:__pthread_attr_getdetachstate=uninstrumented -fun:__pthread_attr_getinheritsched=uninstrumented -fun:__pthread_attr_getschedparam=uninstrumented -fun:__pthread_attr_getschedpolicy=uninstrumented -fun:__pthread_attr_getscope=uninstrumented -fun:__pthread_attr_getstack=uninstrumented -fun:__pthread_attr_getstackaddr=uninstrumented -fun:__pthread_attr_getstacksize=uninstrumented -fun:__pthread_attr_init_2_1=uninstrumented -fun:__pthread_attr_setaffinity_new=uninstrumented -fun:__pthread_attr_setaffinity_old=uninstrumented -fun:__pthread_attr_setdetachstate=uninstrumented -fun:__pthread_attr_setinheritsched=uninstrumented -fun:__pthread_attr_setschedparam=uninstrumented -fun:__pthread_attr_setschedpolicy=uninstrumented -fun:__pthread_attr_setscope=uninstrumented -fun:__pthread_attr_setstack=uninstrumented -fun:__pthread_attr_setstackaddr=uninstrumented -fun:__pthread_attr_setstacksize=uninstrumented -fun:__pthread_cleanup_pop=uninstrumented -fun:__pthread_cleanup_pop_restore=uninstrumented -fun:__pthread_cleanup_push=uninstrumented -fun:__pthread_cleanup_push_defer=uninstrumented fun:__pthread_cleanup_routine=uninstrumented -fun:__pthread_cleanup_upto=uninstrumented fun:__pthread_clock_gettime=uninstrumented fun:__pthread_clock_settime=uninstrumented -fun:__pthread_cond_broadcast=uninstrumented -fun:__pthread_cond_broadcast_2_0=uninstrumented -fun:__pthread_cond_destroy=uninstrumented -fun:__pthread_cond_destroy_2_0=uninstrumented -fun:__pthread_cond_init=uninstrumented -fun:__pthread_cond_init_2_0=uninstrumented -fun:__pthread_cond_signal=uninstrumented -fun:__pthread_cond_signal_2_0=uninstrumented -fun:__pthread_cond_timedwait=uninstrumented -fun:__pthread_cond_timedwait_2_0=uninstrumented -fun:__pthread_cond_wait=uninstrumented -fun:__pthread_cond_wait_2_0=uninstrumented -fun:__pthread_condattr_destroy=uninstrumented -fun:__pthread_condattr_init=uninstrumented -fun:__pthread_create_2_1=uninstrumented -fun:__pthread_current_priority=uninstrumented -fun:__pthread_disable_asynccancel=uninstrumented -fun:__pthread_enable_asynccancel=uninstrumented -fun:__pthread_equal=uninstrumented -fun:__pthread_exit=uninstrumented fun:__pthread_get_minstack=uninstrumented -fun:__pthread_getaffinity_new=uninstrumented -fun:__pthread_getaffinity_np=uninstrumented -fun:__pthread_getaffinity_old=uninstrumented -fun:__pthread_getschedparam=uninstrumented fun:__pthread_getspecific=uninstrumented -fun:__pthread_getspecific_internal=uninstrumented -fun:__pthread_init_static_tls=uninstrumented fun:__pthread_initialize_minimal=uninstrumented -fun:__pthread_initialize_minimal_internal=uninstrumented fun:__pthread_key_create=uninstrumented -fun:__pthread_key_create_internal=uninstrumented -fun:__pthread_kill=uninstrumented -fun:__pthread_kill_other_threads_np=uninstrumented -fun:__pthread_mutex_cond_lock=uninstrumented -fun:__pthread_mutex_cond_lock_adjust=uninstrumented -fun:__pthread_mutex_cond_lock_full=uninstrumented fun:__pthread_mutex_destroy=uninstrumented -fun:__pthread_mutex_destroy_internal=uninstrumented fun:__pthread_mutex_init=uninstrumented -fun:__pthread_mutex_init_internal=uninstrumented fun:__pthread_mutex_lock=uninstrumented -fun:__pthread_mutex_lock_full=uninstrumented -fun:__pthread_mutex_lock_internal=uninstrumented fun:__pthread_mutex_trylock=uninstrumented fun:__pthread_mutex_unlock=uninstrumented -fun:__pthread_mutex_unlock_full=uninstrumented -fun:__pthread_mutex_unlock_internal=uninstrumented -fun:__pthread_mutex_unlock_usercnt=uninstrumented fun:__pthread_mutexattr_destroy=uninstrumented fun:__pthread_mutexattr_init=uninstrumented fun:__pthread_mutexattr_settype=uninstrumented fun:__pthread_once=uninstrumented -fun:__pthread_once_internal=uninstrumented fun:__pthread_register_cancel=uninstrumented fun:__pthread_register_cancel_defer=uninstrumented fun:__pthread_rwlock_destroy=uninstrumented fun:__pthread_rwlock_init=uninstrumented fun:__pthread_rwlock_rdlock=uninstrumented -fun:__pthread_rwlock_rdlock_internal=uninstrumented fun:__pthread_rwlock_tryrdlock=uninstrumented fun:__pthread_rwlock_trywrlock=uninstrumented fun:__pthread_rwlock_unlock=uninstrumented -fun:__pthread_rwlock_unlock_internal=uninstrumented fun:__pthread_rwlock_wrlock=uninstrumented -fun:__pthread_rwlock_wrlock_internal=uninstrumented -fun:__pthread_self=uninstrumented -fun:__pthread_setaffinity_new=uninstrumented -fun:__pthread_setaffinity_old=uninstrumented -fun:__pthread_setcancelstate=uninstrumented -fun:__pthread_setcanceltype=uninstrumented -fun:__pthread_setschedparam=uninstrumented fun:__pthread_setspecific=uninstrumented -fun:__pthread_setspecific_internal=uninstrumented -fun:__pthread_tpp_change_priority=uninstrumented fun:__pthread_unregister_cancel=uninstrumented fun:__pthread_unregister_cancel_restore=uninstrumented fun:__pthread_unwind=uninstrumented @@ -1207,24 +986,15 @@ fun:__pthread_unwind_next=uninstrumented fun:__ptsname_r_chk=uninstrumented fun:__putlong=uninstrumented fun:__putshort=uninstrumented -fun:__pwrite=uninstrumented fun:__pwrite64=uninstrumented -fun:__pwrite_nocancel=uninstrumented fun:__rawmemchr=uninstrumented fun:__read=uninstrumented fun:__read_chk=uninstrumented -fun:__read_nocancel=uninstrumented fun:__readlink_chk=uninstrumented fun:__readlinkat_chk=uninstrumented fun:__realpath_chk=uninstrumented -fun:__reclaim_stacks=uninstrumented -fun:__recv=uninstrumented fun:__recv_chk=uninstrumented -fun:__recvfrom=uninstrumented fun:__recvfrom_chk=uninstrumented -fun:__recvfrom_nocancel=uninstrumented -fun:__recvmsg=uninstrumented -fun:__recvmsg_nocancel=uninstrumented fun:__register_atfork=uninstrumented fun:__register_frame=uninstrumented fun:__register_frame_info=uninstrumented @@ -1261,7 +1031,6 @@ fun:__res_randomid=uninstrumented fun:__res_search=uninstrumented fun:__res_send=uninstrumented fun:__res_state=uninstrumented -fun:__restore_rt=uninstrumented fun:__rpc_thread_createerr=uninstrumented fun:__rpc_thread_svc_fdset=uninstrumented fun:__rpc_thread_svc_max_pollfd=uninstrumented @@ -1281,14 +1050,11 @@ fun:__sched_setscheduler=uninstrumented fun:__sched_yield=uninstrumented fun:__secure_getenv=uninstrumented fun:__select=uninstrumented -fun:__sem_search=uninstrumented fun:__send=uninstrumented -fun:__sendmsg=uninstrumented -fun:__sendmsg_nocancel=uninstrumented -fun:__sendto=uninstrumented -fun:__sendto_nocancel=uninstrumented +fun:__sendmmsg=uninstrumented fun:__setmntent=uninstrumented fun:__setpgid=uninstrumented +fun:__sfp_handle_exceptions=uninstrumented fun:__sigaction=uninstrumented fun:__sigaddset=uninstrumented fun:__sigdelset=uninstrumented @@ -1299,13 +1065,19 @@ fun:__signbitl=uninstrumented fun:__sigpause=uninstrumented fun:__sigsetjmp=uninstrumented fun:__sigsuspend=uninstrumented -fun:__sigsuspend_nocancel=uninstrumented -fun:__sigwait=uninstrumented fun:__sinh_finite=uninstrumented fun:__sinhf_finite=uninstrumented fun:__sinhl_finite=uninstrumented fun:__snprintf_chk=uninstrumented +fun:__splitstack_block_signals=uninstrumented +fun:__splitstack_block_signals_context=uninstrumented fun:__splitstack_find=uninstrumented +fun:__splitstack_find_context=uninstrumented +fun:__splitstack_getcontext=uninstrumented +fun:__splitstack_makecontext=uninstrumented +fun:__splitstack_releasecontext=uninstrumented +fun:__splitstack_resetcontext=uninstrumented +fun:__splitstack_setcontext=uninstrumented fun:__sprintf_chk=uninstrumented fun:__sqrt_finite=uninstrumented fun:__sqrtf_finite=uninstrumented @@ -1397,7 +1169,6 @@ fun:__uflow=uninstrumented fun:__umodti3=uninstrumented fun:__underflow=uninstrumented fun:__unordtf2=uninstrumented -fun:__unwind_freeres=uninstrumented fun:__uselocale=uninstrumented fun:__vasprintf_chk=uninstrumented fun:__vdprintf_chk=uninstrumented @@ -1414,7 +1185,6 @@ fun:__vswprintf_chk=uninstrumented fun:__vsyslog_chk=uninstrumented fun:__vwprintf_chk=uninstrumented fun:__wait=uninstrumented -fun:__wait_lookup_done=uninstrumented fun:__waitpid=uninstrumented fun:__warn_memset_zero_len=uninstrumented fun:__wcpcpy_chk=uninstrumented @@ -1449,7 +1219,6 @@ fun:__wcsxfrm_l=uninstrumented fun:__wctomb_chk=uninstrumented fun:__wctrans_l=uninstrumented fun:__wctype_l=uninstrumented -fun:__where_is_shmfs=uninstrumented fun:__wmemcpy_chk=uninstrumented fun:__wmemmove_chk=uninstrumented fun:__wmempcpy_chk=uninstrumented @@ -1458,7 +1227,6 @@ fun:__woverflow=uninstrumented fun:__wprintf_chk=uninstrumented fun:__wrap_pthread_create=uninstrumented fun:__write=uninstrumented -fun:__write_nocancel=uninstrumented fun:__wuflow=uninstrumented fun:__wunderflow=uninstrumented fun:__xmknod=uninstrumented @@ -1484,6 +1252,7 @@ fun:_dl_allocate_tls=uninstrumented fun:_dl_allocate_tls_init=uninstrumented fun:_dl_deallocate_tls=uninstrumented fun:_dl_debug_state=uninstrumented +fun:_dl_find_dso_for_object=uninstrumented fun:_dl_get_tls_static_info=uninstrumented fun:_dl_make_stack_executable=uninstrumented fun:_dl_mcount=uninstrumented @@ -1494,7 +1263,6 @@ fun:_dl_sym=uninstrumented fun:_dl_tls_setup=uninstrumented fun:_dl_vsym=uninstrumented fun:_exit=uninstrumented -fun:_fini=uninstrumented fun:_flushlbf=uninstrumented fun:_gethtbyaddr=uninstrumented fun:_gethtbyname=uninstrumented @@ -1502,7 +1270,6 @@ fun:_gethtbyname2=uninstrumented fun:_gethtent=uninstrumented fun:_getlong=uninstrumented fun:_getshort=uninstrumented -fun:_init=uninstrumented fun:_longjmp=uninstrumented fun:_mcleanup=uninstrumented fun:_mcount=uninstrumented @@ -1542,7 +1309,6 @@ fun:acosh=uninstrumented fun:acoshf=uninstrumented fun:acoshl=uninstrumented fun:acosl=uninstrumented -fun:add_and_round.constprop.0=uninstrumented fun:addmntent=uninstrumented fun:addseverity=uninstrumented fun:adjtime=uninstrumented @@ -1564,6 +1330,7 @@ fun:aio_suspend64=uninstrumented fun:aio_write=uninstrumented fun:aio_write64=uninstrumented fun:alarm=uninstrumented +fun:aligned_alloc=uninstrumented fun:alphasort=uninstrumented fun:alphasort64=uninstrumented fun:arch_prctl=uninstrumented @@ -1622,7 +1389,6 @@ fun:basename=uninstrumented fun:bcmp=uninstrumented fun:bcopy=uninstrumented fun:bdflush=uninstrumented -fun:bid128_ext_fma=uninstrumented fun:bind=uninstrumented fun:bind_textdomain_codeset=uninstrumented fun:bindresvport=uninstrumented @@ -1632,6 +1398,8 @@ fun:bsd_signal=uninstrumented fun:bsearch=uninstrumented fun:btowc=uninstrumented fun:bzero=uninstrumented +fun:c16rtomb=uninstrumented +fun:c32rtomb=uninstrumented fun:cabs=uninstrumented fun:cabsf=uninstrumented fun:cabsl=uninstrumented @@ -1688,7 +1456,6 @@ fun:cfsetispeed=uninstrumented fun:cfsetospeed=uninstrumented fun:cfsetspeed=uninstrumented fun:chdir=uninstrumented -fun:check_add_mapping=uninstrumented fun:chflags=uninstrumented fun:chmod=uninstrumented fun:chown=uninstrumented @@ -1696,8 +1463,6 @@ fun:chroot=uninstrumented fun:cimag=uninstrumented fun:cimagf=uninstrumented fun:cimagl=uninstrumented -fun:cleanup=uninstrumented -fun:clear_once_control=uninstrumented fun:clearenv=uninstrumented fun:clearerr=uninstrumented fun:clearerr_unlocked=uninstrumented @@ -1756,7 +1521,6 @@ fun:crealf=uninstrumented fun:creall=uninstrumented fun:creat=uninstrumented fun:creat64=uninstrumented -fun:create_key=uninstrumented fun:create_module=uninstrumented fun:crypt=uninstrumented fun:crypt_r=uninstrumented @@ -1800,8 +1564,6 @@ fun:dlopen=uninstrumented fun:dlsym=uninstrumented fun:dlvsym=uninstrumented fun:dngettext=uninstrumented -fun:do_clone.constprop.4=uninstrumented -fun:do_sigwait=uninstrumented fun:dprintf=uninstrumented fun:drand48=uninstrumented fun:drand48_r=uninstrumented @@ -2002,12 +1764,9 @@ fun:fputwc=uninstrumented fun:fputwc_unlocked=uninstrumented fun:fputws=uninstrumented fun:fputws_unlocked=uninstrumented -fun:frame_dummy=uninstrumented fun:fread=uninstrumented fun:fread_unlocked=uninstrumented fun:free=uninstrumented -fun:free_dynamic_blocks=uninstrumented -fun:free_segments=uninstrumented fun:freeaddrinfo=uninstrumented fun:freeifaddrs=uninstrumented fun:freelocale=uninstrumented @@ -2065,7 +1824,6 @@ fun:gamma=uninstrumented fun:gammaf=uninstrumented fun:gammal=uninstrumented fun:gcvt=uninstrumented -fun:get_BID128.constprop.5=uninstrumented fun:get_avphys_pages=uninstrumented fun:get_current_dir_name=uninstrumented fun:get_kernel_syms=uninstrumented @@ -2079,6 +1837,7 @@ fun:getaliasbyname=uninstrumented fun:getaliasbyname_r=uninstrumented fun:getaliasent=uninstrumented fun:getaliasent_r=uninstrumented +fun:getauxval=uninstrumented fun:getc=uninstrumented fun:getc_unlocked=uninstrumented fun:getchar=uninstrumented @@ -2492,6 +2251,8 @@ fun:mallopt=uninstrumented fun:matherr=uninstrumented fun:mblen=uninstrumented fun:mbrlen=uninstrumented +fun:mbrtoc16=uninstrumented +fun:mbrtoc32=uninstrumented fun:mbrtowc=uninstrumented fun:mbsinit=uninstrumented fun:mbsnrtowcs=uninstrumented @@ -2653,9 +2414,6 @@ fun:nis_verifygroup=uninstrumented fun:nis_write_obj=uninstrumented fun:nl_langinfo=uninstrumented fun:nl_langinfo_l=uninstrumented -fun:nop=uninstrumented -fun:nptl_freeres=uninstrumented -fun:nr_digits256=uninstrumented fun:nrand48=uninstrumented fun:nrand48_r=uninstrumented fun:ns_datetosecs=uninstrumented @@ -2802,7 +2560,6 @@ fun:pthread_barrierattr_getpshared=uninstrumented fun:pthread_barrierattr_init=uninstrumented fun:pthread_barrierattr_setpshared=uninstrumented fun:pthread_cancel=uninstrumented -fun:pthread_cancel_init=uninstrumented fun:pthread_cond_broadcast=uninstrumented fun:pthread_cond_destroy=uninstrumented fun:pthread_cond_init=uninstrumented @@ -2820,6 +2577,7 @@ fun:pthread_detach=uninstrumented fun:pthread_equal=uninstrumented fun:pthread_exit=uninstrumented fun:pthread_getaffinity_np=uninstrumented +fun:pthread_getattr_default_np=uninstrumented fun:pthread_getattr_np=uninstrumented fun:pthread_getconcurrency=uninstrumented fun:pthread_getcpuclockid=uninstrumented @@ -2875,6 +2633,7 @@ fun:pthread_rwlockattr_setkind_np=uninstrumented fun:pthread_rwlockattr_setpshared=uninstrumented fun:pthread_self=uninstrumented fun:pthread_setaffinity_np=uninstrumented +fun:pthread_setattr_default_np=uninstrumented fun:pthread_setcancelstate=uninstrumented fun:pthread_setcanceltype=uninstrumented fun:pthread_setconcurrency=uninstrumented @@ -3003,7 +2762,6 @@ fun:rintl=uninstrumented fun:rmdir=uninstrumented fun:round=uninstrumented fun:roundf=uninstrumented -fun:rounding_correction.constprop.1=uninstrumented fun:roundl=uninstrumented fun:rpmatch=uninstrumented fun:rresvport=uninstrumented @@ -3038,6 +2796,7 @@ fun:sched_setaffinity=uninstrumented fun:sched_setparam=uninstrumented fun:sched_setscheduler=uninstrumented fun:sched_yield=uninstrumented +fun:secure_getenv=uninstrumented fun:seed48=uninstrumented fun:seed48_r=uninstrumented fun:seekdir=uninstrumented @@ -3049,12 +2808,9 @@ fun:sem_init=uninstrumented fun:sem_open=uninstrumented fun:sem_post=uninstrumented fun:sem_timedwait=uninstrumented -fun:sem_timedwait_cleanup=uninstrumented -fun:sem_timedwait_cleanup2=uninstrumented fun:sem_trywait=uninstrumented fun:sem_unlink=uninstrumented fun:sem_wait=uninstrumented -fun:sem_wait_cleanup=uninstrumented fun:semctl=uninstrumented fun:semget=uninstrumented fun:semop=uninstrumented @@ -3123,7 +2879,6 @@ fun:setutent=uninstrumented fun:setutxent=uninstrumented fun:setvbuf=uninstrumented fun:setxattr=uninstrumented -fun:setxid_mark_thread.isra.1=uninstrumented fun:sgetsgent=uninstrumented fun:sgetsgent_r=uninstrumented fun:sgetspent=uninstrumented @@ -3140,12 +2895,10 @@ fun:sigaddset=uninstrumented fun:sigaltstack=uninstrumented fun:sigandset=uninstrumented fun:sigblock=uninstrumented -fun:sigcancel_handler=uninstrumented fun:sigdelset=uninstrumented fun:sigemptyset=uninstrumented fun:sigfillset=uninstrumented fun:siggetmask=uninstrumented -fun:sighandler_setxid=uninstrumented fun:sighold=uninstrumented fun:sigignore=uninstrumented fun:siginterrupt=uninstrumented @@ -3200,8 +2953,6 @@ fun:srandom_r=uninstrumented fun:sscanf=uninstrumented fun:ssignal=uninstrumented fun:sstk=uninstrumented -fun:stack_split_initialize_thread=uninstrumented -fun:start_thread=uninstrumented fun:stat=uninstrumented fun:stat64=uninstrumented fun:statfs=uninstrumented @@ -3272,7 +3023,6 @@ fun:strverscmp=uninstrumented fun:strxfrm=uninstrumented fun:strxfrm_l=uninstrumented fun:stty=uninstrumented -fun:sub256=uninstrumented fun:svc_exit=uninstrumented fun:svc_getreq=uninstrumented fun:svc_getreq_common=uninstrumented @@ -3392,6 +3142,7 @@ fun:timerfd_create=uninstrumented fun:timerfd_gettime=uninstrumented fun:timerfd_settime=uninstrumented fun:times=uninstrumented +fun:timespec_get=uninstrumented fun:tmpfile=uninstrumented fun:tmpfile64=uninstrumented fun:tmpnam=uninstrumented @@ -3433,8 +3184,6 @@ fun:unlinkat=uninstrumented fun:unlockpt=uninstrumented fun:unsetenv=uninstrumented fun:unshare=uninstrumented -fun:unwind_cleanup=uninstrumented -fun:unwind_stop=uninstrumented fun:updwtmp=uninstrumented fun:updwtmpx=uninstrumented fun:uselib=uninstrumented @@ -3480,7 +3229,6 @@ fun:wait3=uninstrumented fun:wait4=uninstrumented fun:waitid=uninstrumented fun:waitpid=uninstrumented -fun:walker=uninstrumented fun:warn=uninstrumented fun:warnx=uninstrumented fun:wcpcpy=uninstrumented diff --git a/lib/dfsan/lit_tests/CMakeLists.txt b/lib/dfsan/lit_tests/CMakeLists.txt deleted file mode 100644 index d7c5c82ac3c0f..0000000000000 --- a/lib/dfsan/lit_tests/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set(DFSAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) -set(DFSAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..) - -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) - -if(COMPILER_RT_CAN_EXECUTE_TESTS) - # Run DFSan tests only if we're sure we may produce working binaries. - set(DFSAN_TEST_DEPS - ${SANITIZER_COMMON_LIT_TEST_DEPS} - ${DFSAN_RUNTIME_LIBRARIES} - dfsan_abilist) - set(DFSAN_TEST_PARAMS - dfsan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) - add_lit_testsuite(check-dfsan "Running the DataFlowSanitizer tests" - ${CMAKE_CURRENT_BINARY_DIR} - PARAMS ${DFSAN_TEST_PARAMS} - DEPENDS ${DFSAN_TEST_DEPS}) - set_target_properties(check-dfsan PROPERTIES FOLDER "DFSan tests") -endif() diff --git a/lib/dfsan/lit_tests/Inputs/flags_abilist.txt b/lib/dfsan/lit_tests/Inputs/flags_abilist.txt deleted file mode 100644 index 94b1fa2982599..0000000000000 --- a/lib/dfsan/lit_tests/Inputs/flags_abilist.txt +++ /dev/null @@ -1,10 +0,0 @@ -fun:f=uninstrumented - -fun:main=uninstrumented -fun:main=discard - -fun:dfsan_create_label=uninstrumented -fun:dfsan_create_label=discard - -fun:dfsan_set_label=uninstrumented -fun:dfsan_set_label=discard diff --git a/lib/dfsan/lit_tests/basic.c b/lib/dfsan/lit_tests/basic.c deleted file mode 100644 index b566c9271d0b4..0000000000000 --- a/lib/dfsan/lit_tests/basic.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %t - -// Tests that labels are propagated through loads and stores. - -#include <sanitizer/dfsan_interface.h> -#include <assert.h> - -int main(void) { - int i = 1; - dfsan_label i_label = dfsan_create_label("i", 0); - dfsan_set_label(i_label, &i, sizeof(i)); - - dfsan_label new_label = dfsan_get_label(i); - assert(i_label == new_label); - - dfsan_label read_label = dfsan_read_label(&i, sizeof(i)); - assert(i_label == read_label); - - return 0; -} diff --git a/lib/dfsan/lit_tests/custom.c b/lib/dfsan/lit_tests/custom.c deleted file mode 100644 index c9fa9356154df..0000000000000 --- a/lib/dfsan/lit_tests/custom.c +++ /dev/null @@ -1,154 +0,0 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %t - -// Tests custom implementations of various libc functions. - -#define _GNU_SOURCE -#include <sanitizer/dfsan_interface.h> -#include <assert.h> -#include <link.h> -#include <pthread.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -void *ptcb(void *p) { - assert(p == (void *)1); - assert(dfsan_get_label((uintptr_t)p) == 0); - return (void *)2; -} - -int dlcb(struct dl_phdr_info *info, size_t size, void *data) { - assert(data == (void *)3); - assert(dfsan_get_label((uintptr_t)info) == 0); - assert(dfsan_get_label(size) == 0); - assert(dfsan_get_label((uintptr_t)data) == 0); - return 0; -} - -int main(void) { - int i = 1; - dfsan_label i_label = dfsan_create_label("i", 0); - dfsan_set_label(i_label, &i, sizeof(i)); - - int j = 2; - dfsan_label j_label = dfsan_create_label("j", 0); - dfsan_set_label(j_label, &j, sizeof(j)); - - struct stat s; - s.st_dev = i; - int rv = stat("/", &s); - assert(rv == 0); - assert(dfsan_get_label(s.st_dev) == 0); - - s.st_dev = i; - rv = stat("/nonexistent", &s); - assert(rv == -1); - assert(dfsan_get_label(s.st_dev) == i_label); - - int fd = open("/dev/zero", O_RDONLY); - s.st_dev = i; - rv = fstat(fd, &s); - assert(rv == 0); - assert(dfsan_get_label(s.st_dev) == 0); - - char str1[] = "str1", str2[] = "str2"; - dfsan_set_label(i_label, &str1[3], 1); - dfsan_set_label(j_label, &str2[3], 1); - - rv = memcmp(str1, str2, sizeof(str1)); - assert(rv < 0); - assert(dfsan_get_label(rv) == dfsan_union(i_label, j_label)); - - char strc[sizeof(str1)]; - memcpy(strc, str1, sizeof(str1)); - assert(dfsan_get_label(strc[0]) == 0); - assert(dfsan_get_label(strc[3]) == i_label); - - memset(strc, j, sizeof(strc)); - assert(dfsan_get_label(strc[0]) == j_label); - assert(dfsan_get_label(strc[1]) == j_label); - assert(dfsan_get_label(strc[2]) == j_label); - assert(dfsan_get_label(strc[3]) == j_label); - assert(dfsan_get_label(strc[4]) == j_label); - - rv = strcmp(str1, str2); - assert(rv < 0); - assert(dfsan_get_label(rv) == dfsan_union(i_label, j_label)); - - char *strd = strdup(str1); - assert(dfsan_get_label(strd[0]) == 0); - assert(dfsan_get_label(strd[3]) == i_label); - free(strd); - - rv = strncmp(str1, str2, sizeof(str1)); - assert(rv < 0); - assert(dfsan_get_label(rv) == dfsan_union(i_label, j_label)); - - rv = strncmp(str1, str2, 3); - assert(rv == 0); - assert(dfsan_get_label(rv) == 0); - - str1[0] = 'S'; - - rv = strncasecmp(str1, str2, sizeof(str1)); - assert(rv < 0); - assert(dfsan_get_label(rv) == dfsan_union(i_label, j_label)); - - rv = strncasecmp(str1, str2, 3); - assert(rv == 0); - assert(dfsan_get_label(rv) == 0); - - char *crv = strchr(str1, 'r'); - assert(crv == &str1[2]); - assert(dfsan_get_label((uintptr_t)crv) == 0); - - crv = strchr(str1, '1'); - assert(crv == &str1[3]); - assert(dfsan_get_label((uintptr_t)crv) == i_label); - - crv = strchr(str1, 'x'); - assert(crv == 0); - assert(dfsan_get_label((uintptr_t)crv) == i_label); - - // With any luck this sequence of calls will cause calloc to return the same - // pointer both times. This is probably the best we can do to test this - // function. - crv = calloc(4096, 1); - assert(dfsan_get_label(crv[0]) == 0); - free(crv); - - crv = calloc(4096, 1); - assert(dfsan_get_label(crv[0]) == 0); - free(crv); - - char buf[16]; - buf[0] = i; - buf[15] = j; - rv = read(fd, buf, sizeof(buf)); - assert(rv == sizeof(buf)); - assert(dfsan_get_label(buf[0]) == 0); - assert(dfsan_get_label(buf[15]) == 0); - - close(fd); - fd = open("/bin/sh", O_RDONLY); - buf[0] = i; - buf[15] = j; - rv = pread(fd, buf, sizeof(buf), 0); - assert(rv == sizeof(buf)); - assert(dfsan_get_label(buf[0]) == 0); - assert(dfsan_get_label(buf[15]) == 0); - - pthread_t pt; - pthread_create(&pt, 0, ptcb, (void *)1); - void *cbrv; - pthread_join(pt, &cbrv); - assert(cbrv == (void *)2); - - dl_iterate_phdr(dlcb, (void *)3); - - return 0; -} diff --git a/lib/dfsan/lit_tests/flags.c b/lib/dfsan/lit_tests/flags.c deleted file mode 100644 index 5cf970dce90df..0000000000000 --- a/lib/dfsan/lit_tests/flags.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && %t 2>&1 | FileCheck %s -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_unimplemented=0 %t 2>&1 | count 0 -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_nonzero_labels=1 %t 2>&1 | FileCheck --check-prefix=CHECK-NONZERO %s - -// Tests that flags work correctly. - -#include <sanitizer/dfsan_interface.h> - -int f(int i) { - return i; -} - -int main(void) { - int i = 1; - dfsan_label i_label = dfsan_create_label("i", 0); - dfsan_set_label(i_label, &i, sizeof(i)); - - // CHECK: WARNING: DataFlowSanitizer: call to uninstrumented function f - // CHECK-NOT: WARNING: DataFlowSanitizer: saw nonzero label - // CHECK-NONZERO: WARNING: DataFlowSanitizer: saw nonzero label - f(i); - - return 0; -} diff --git a/lib/dfsan/lit_tests/fncall.c b/lib/dfsan/lit_tests/fncall.c deleted file mode 100644 index 15b77bd67902b..0000000000000 --- a/lib/dfsan/lit_tests/fncall.c +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %t - -// Tests that labels are propagated through function calls. - -#include <sanitizer/dfsan_interface.h> -#include <assert.h> - -int f(int x) { - int j = 2; - dfsan_label j_label = dfsan_create_label("j", 0); - dfsan_set_label(j_label, &j, sizeof(j)); - return x + j; -} - -int main(void) { - int i = 1; - dfsan_label i_label = dfsan_create_label("i", 0); - dfsan_set_label(i_label, &i, sizeof(i)); - - dfsan_label ij_label = dfsan_get_label(f(i)); - assert(dfsan_has_label(ij_label, i_label)); - assert(dfsan_has_label_with_desc(ij_label, "j")); - - return 0; -} diff --git a/lib/dfsan/lit_tests/lit.cfg b/lib/dfsan/lit_tests/lit.cfg deleted file mode 100644 index 19bc97690a860..0000000000000 --- a/lib/dfsan/lit_tests/lit.cfg +++ /dev/null @@ -1,69 +0,0 @@ -# -*- Python -*- - -import os - -import lit.util - -def get_required_attr(config, attr_name): - attr_value = getattr(config, attr_name, None) - if not attr_value: - lit_config.fatal( - "No attribute %r in test configuration! You may need to run " - "tests from your build directory or add this attribute " - "to lit.site.cfg " % attr_name) - return attr_value - -# Setup config name. -config.name = 'DataFlowSanitizer' - -# Setup source root. -config.test_source_root = os.path.dirname(__file__) - -def DisplayNoConfigMessage(): - lit_config.fatal("No site specific configuration available! " + - "Try running your test from the build tree or running " + - "make check-dfsan") - -# Figure out LLVM source root. -llvm_src_root = getattr(config, 'llvm_src_root', None) -if llvm_src_root is None: - # We probably haven't loaded the site-specific configuration: the user - # is likely trying to run a test file directly, and the site configuration - # wasn't created by the build system. - dfsan_site_cfg = lit_config.params.get('dfsan_site_config', None) - if (dfsan_site_cfg) and (os.path.exists(dfsan_site_cfg)): - lit_config.load_config(config, dfsan_site_cfg) - raise SystemExit - - # Try to guess the location of site-specific configuration using llvm-config - # util that can point where the build tree is. - llvm_config = lit.util.which("llvm-config", config.environment["PATH"]) - if not llvm_config: - DisplayNoConfigMessage() - - # Find out the presumed location of generated site config. - llvm_obj_root = lit.util.capture(["llvm-config", "--obj-root"]).strip() - dfsan_site_cfg = os.path.join(llvm_obj_root, "projects", "compiler-rt", - "lib", "dfsan", "lit_tests", "lit.site.cfg") - if (not dfsan_site_cfg) or (not os.path.exists(dfsan_site_cfg)): - DisplayNoConfigMessage() - - lit_config.load_config(config, dfsan_site_cfg) - raise SystemExit - -# Setup default compiler flags used with -fsanitize=dataflow option. -clang_dfsan_cflags = ["-fsanitize=dataflow"] -clang_dfsan_cxxflags = ["--driver-mode=g++ "] + clang_dfsan_cflags -config.substitutions.append( ("%clang_dfsan ", - " ".join([config.clang] + clang_dfsan_cflags) + - " ") ) -config.substitutions.append( ("%clangxx_dfsan ", - " ".join([config.clang] + clang_dfsan_cxxflags) + - " ") ) - -# Default test suffixes. -config.suffixes = ['.c', '.cc', '.cpp'] - -# DataFlowSanitizer tests are currently supported on Linux only. -if config.host_os not in ['Linux']: - config.unsupported = True diff --git a/lib/dfsan/lit_tests/lit.site.cfg.in b/lib/dfsan/lit_tests/lit.site.cfg.in deleted file mode 100644 index 0cf6d6b5580f8..0000000000000 --- a/lib/dfsan/lit_tests/lit.site.cfg.in +++ /dev/null @@ -1,5 +0,0 @@ -# Load common config for all compiler-rt lit tests. -lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") - -# Load tool-specific config that would do the real work. -lit_config.load_config(config, "@DFSAN_SOURCE_DIR@/lit_tests/lit.cfg") diff --git a/lib/dfsan/lit_tests/propagate.c b/lib/dfsan/lit_tests/propagate.c deleted file mode 100644 index 86d182b8a7fc2..0000000000000 --- a/lib/dfsan/lit_tests/propagate.c +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %t - -// Tests that labels are propagated through computation and that union labels -// are properly created. - -#include <sanitizer/dfsan_interface.h> -#include <assert.h> - -int main(void) { - assert(dfsan_union(0, 0) == 0); - - int i = 1; - dfsan_label i_label = dfsan_create_label("i", 0); - dfsan_set_label(i_label, &i, sizeof(i)); - - int j = 2; - dfsan_label j_label = dfsan_create_label("j", 0); - dfsan_set_label(j_label, &j, sizeof(j)); - - int k = 3; - dfsan_label k_label = dfsan_create_label("k", 0); - dfsan_set_label(k_label, &k, sizeof(k)); - - int k2 = 4; - dfsan_set_label(k_label, &k2, sizeof(k2)); - - dfsan_label ij_label = dfsan_get_label(i + j); - assert(dfsan_has_label(ij_label, i_label)); - assert(dfsan_has_label(ij_label, j_label)); - assert(!dfsan_has_label(ij_label, k_label)); - // Test uniquing. - assert(dfsan_union(i_label, j_label) == ij_label); - assert(dfsan_union(j_label, i_label) == ij_label); - - dfsan_label ijk_label = dfsan_get_label(i + j + k); - assert(dfsan_has_label(ijk_label, i_label)); - assert(dfsan_has_label(ijk_label, j_label)); - assert(dfsan_has_label(ijk_label, k_label)); - - assert(dfsan_get_label(k + k2) == k_label); - - struct { int i, j; } s = { i, j }; - assert(dfsan_read_label(&s, sizeof(s)) == ij_label); - - return 0; -} diff --git a/lib/dfsan/scripts/build-libc-list.py b/lib/dfsan/scripts/build-libc-list.py index 8f6b8d5136317..eddb6c07e99d8 100755 --- a/lib/dfsan/scripts/build-libc-list.py +++ b/lib/dfsan/scripts/build-libc-list.py @@ -26,27 +26,38 @@ def defined_function_list(object): raise subprocess.CalledProcessError(readelf_proc.returncode, 'readelf') for line in readelf: if (line[31:35] == 'FUNC' or line[31:36] == 'IFUNC') and \ + line[39:44] != 'LOCAL' and \ line[55:58] != 'UND': function_name = line[59:].split('@')[0] functions.append(function_name) return functions p = OptionParser() -p.add_option('--lib', metavar='PATH', - help='path to lib directory to use', + +p.add_option('--libc-dso-path', metavar='PATH', + help='path to libc DSO directory', default='/lib/x86_64-linux-gnu') -p.add_option('--usrlib', metavar='PATH', - help='path to usr/lib directory to use', +p.add_option('--libc-archive-path', metavar='PATH', + help='path to libc archive directory', default='/usr/lib/x86_64-linux-gnu') -p.add_option('--gcclib', metavar='PATH', - help='path to gcc lib directory to use', + +p.add_option('--libgcc-dso-path', metavar='PATH', + help='path to libgcc DSO directory', + default='/lib/x86_64-linux-gnu') +p.add_option('--libgcc-archive-path', metavar='PATH', + help='path to libgcc archive directory', default='/usr/lib/gcc/x86_64-linux-gnu/4.6') + p.add_option('--with-libstdcxx', action='store_true', dest='with_libstdcxx', help='include libstdc++ in the list (inadvisable)') +p.add_option('--libstdcxx-dso-path', metavar='PATH', + help='path to libstdc++ DSO directory', + default='/usr/lib/x86_64-linux-gnu') + (options, args) = p.parse_args() -libs = [os.path.join(options.lib, name) for name in +libs = [os.path.join(options.libc_dso_path, name) for name in ['ld-linux-x86-64.so.2', 'libanl.so.1', 'libBrokenLocale.so.1', @@ -61,14 +72,15 @@ libs = [os.path.join(options.lib, name) for name in 'librt.so.1', 'libthread_db.so.1', 'libutil.so.1']] -libs += [os.path.join(options.usrlib, name) for name in +libs += [os.path.join(options.libc_archive_path, name) for name in ['libc_nonshared.a', 'libpthread_nonshared.a']] -gcclibs = ['libgcc.a', - 'libgcc_s.so'] + +libs.append(os.path.join(options.libgcc_dso_path, 'libgcc_s.so.1')) +libs.append(os.path.join(options.libgcc_archive_path, 'libgcc.a')) + if options.with_libstdcxx: - gcclibs += ['libstdc++.so'] -libs += [os.path.join(options.gcclib, name) for name in gcclibs] + libs.append(os.path.join(options.libstdcxx_dso_path, 'libstdc++.so.6')) functions = [] for l in libs: diff --git a/lib/dfsan/scripts/check_custom_wrappers.sh b/lib/dfsan/scripts/check_custom_wrappers.sh new file mode 100755 index 0000000000000..50bc85d4aef5d --- /dev/null +++ b/lib/dfsan/scripts/check_custom_wrappers.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +DFSAN_DIR=$(dirname "$0")/../ +DFSAN_CUSTOM_TESTS=${DFSAN_DIR}/../../test/dfsan/custom.cc +DFSAN_CUSTOM_WRAPPERS=${DFSAN_DIR}/dfsan_custom.cc +DFSAN_ABI_LIST=${DFSAN_DIR}/done_abilist.txt + +DIFFOUT=$(mktemp -q /tmp/tmp.XXXXXXXXXX) +ERRORLOG=$(mktemp -q /tmp/tmp.XXXXXXXXXX) +DIFF_A=$(mktemp -q /tmp/tmp.XXXXXXXXXX) +DIFF_B=$(mktemp -q /tmp/tmp.XXXXXXXXXX) + +on_exit() { + rm -f ${DIFFOUT} 2> /dev/null + rm -f ${ERRORLOG} 2> /dev/null + rm -f ${DIFF_A} 2> /dev/null + rm -f ${DIFF_B} 2> /dev/null +} + +trap on_exit EXIT +grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} | grep -v "dfsan_get_label" \ + | sed "s/^fun:\(.*\)=custom.*/\1/" | sort > $DIFF_A +grep -E "__dfsw.*\(" ${DFSAN_CUSTOM_WRAPPERS} \ + | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort > $DIFF_B +diff -u $DIFF_A $DIFF_B > ${DIFFOUT} +if [ $? -ne 0 ] +then + echo -n "The following differences between the ABI list and ">> ${ERRORLOG} + echo "the implemented custom wrappers have been found:" >> ${ERRORLOG} + cat ${DIFFOUT} >> ${ERRORLOG} +fi + +grep -E __dfsw_ ${DFSAN_CUSTOM_WRAPPERS} \ + | sed "s/.*__dfsw_\([^(]*\).*/\1/" | sort > $DIFF_A +grep -E "^\\s*test_.*\(\);" ${DFSAN_CUSTOM_TESTS} \ + | sed "s/.*test_\(.*\)();/\1/" | sort > $DIFF_B +diff -u $DIFF_A $DIFF_B > ${DIFFOUT} +if [ $? -ne 0 ] +then + echo -n "The following differences between the implemented " >> ${ERRORLOG} + echo "custom wrappers and the tests have been found:" >> ${ERRORLOG} + cat ${DIFFOUT} >> ${ERRORLOG} +fi + +if [ -s ${ERRORLOG} ] +then + cat ${ERRORLOG} + exit 1 +fi + |