├── .gitignore ├── .vscode └── settings.json ├── CMakeLists.txt ├── README.md ├── clang-alternatives.sh ├── clang-llvm-install.sh ├── src ├── CMakeLists.txt ├── abilist │ ├── CMakeLists.txt │ ├── done_abilist.txt │ ├── hook_abilist.txt │ ├── libc_ubuntu1404_abilist.txt │ └── target │ │ ├── exif_abilist.txt │ │ ├── libexif_abilist.txt │ │ ├── libsixel_abilist.txt │ │ ├── libtiff_abilist.txt │ │ └── openjpeg_abilist.txt ├── afl_rt │ ├── CMakeLists.txt │ ├── afl-compiler-rt.o.c │ ├── include │ │ ├── config.h │ │ ├── snapshot-inl.h │ │ ├── types.h │ │ └── xxhash.h │ └── llvm-alternative-coverage.h ├── compiler │ ├── CMakeLists.txt │ ├── clang_wrapper.c │ └── include │ │ ├── alloc-inl.h │ │ ├── config.h │ │ ├── debug.h │ │ └── types.h ├── dfsan_rt │ ├── CMakeLists.txt │ ├── cmake │ │ ├── AddCompilerRT.cmake │ │ ├── BuiltinTests.cmake │ │ ├── CompilerRTCompile.cmake │ │ ├── CompilerRTDarwinUtils.cmake │ │ ├── CompilerRTLink.cmake │ │ ├── CompilerRTUtils.cmake │ │ ├── HandleCompilerRT.cmake │ │ ├── SanitizerUtils.cmake │ │ └── UseLibtool.cmake │ ├── dfsan │ │ ├── .clang-format │ │ ├── CMakeLists.txt │ │ ├── dfsan.cpp │ │ ├── dfsan.h │ │ ├── dfsan.syms.extra │ │ ├── dfsan_custom.cpp │ │ ├── dfsan_flags.inc │ │ ├── dfsan_interceptors.cpp │ │ ├── dfsan_io.cpp │ │ ├── dfsan_platform.h │ │ ├── event_callback.cpp │ │ └── scripts │ │ │ ├── build-libc-list.py │ │ │ └── check_custom_wrappers.sh │ ├── extension │ │ ├── dfsan_hook.cpp │ │ ├── dfsan_union_t.cpp │ │ └── include │ │ │ ├── dfsan_union_t.h │ │ │ └── dtaint.h │ ├── interception │ │ ├── .clang-format │ │ ├── CMakeLists.txt │ │ ├── interception.h │ │ ├── interception_linux.cpp │ │ ├── interception_linux.h │ │ ├── interception_mac.cpp │ │ ├── interception_mac.h │ │ ├── interception_type_test.cpp │ │ ├── interception_win.cpp │ │ ├── interception_win.h │ │ └── tests │ │ │ ├── CMakeLists.txt │ │ │ ├── interception_linux_test.cpp │ │ │ ├── interception_test_main.cpp │ │ │ └── interception_win_test.cpp │ └── sanitizer_common │ │ ├── .clang-format │ │ ├── .clang-tidy │ │ ├── CMakeLists.txt │ │ ├── sancov_flags.cpp │ │ ├── sancov_flags.h │ │ ├── sancov_flags.inc │ │ ├── sanitizer_addrhashmap.h │ │ ├── sanitizer_allocator.cpp │ │ ├── sanitizer_allocator.h │ │ ├── sanitizer_allocator_bytemap.h │ │ ├── sanitizer_allocator_checks.cpp │ │ ├── sanitizer_allocator_checks.h │ │ ├── sanitizer_allocator_combined.h │ │ ├── sanitizer_allocator_interface.h │ │ ├── sanitizer_allocator_internal.h │ │ ├── sanitizer_allocator_local_cache.h │ │ ├── sanitizer_allocator_primary32.h │ │ ├── sanitizer_allocator_primary64.h │ │ ├── sanitizer_allocator_report.cpp │ │ ├── sanitizer_allocator_report.h │ │ ├── sanitizer_allocator_secondary.h │ │ ├── sanitizer_allocator_size_class_map.h │ │ ├── sanitizer_allocator_stats.h │ │ ├── sanitizer_asm.h │ │ ├── sanitizer_atomic.h │ │ ├── sanitizer_atomic_clang.h │ │ ├── sanitizer_atomic_clang_mips.h │ │ ├── sanitizer_atomic_clang_other.h │ │ ├── sanitizer_atomic_clang_x86.h │ │ ├── sanitizer_atomic_msvc.h │ │ ├── sanitizer_bitvector.h │ │ ├── sanitizer_bvgraph.h │ │ ├── sanitizer_common.cpp │ │ ├── sanitizer_common.h │ │ ├── sanitizer_common_interceptors.inc │ │ ├── sanitizer_common_interceptors_format.inc │ │ ├── sanitizer_common_interceptors_ioctl.inc │ │ ├── sanitizer_common_interceptors_netbsd_compat.inc │ │ ├── sanitizer_common_interceptors_vfork_aarch64.inc.S │ │ ├── sanitizer_common_interceptors_vfork_arm.inc.S │ │ ├── sanitizer_common_interceptors_vfork_i386.inc.S │ │ ├── sanitizer_common_interceptors_vfork_x86_64.inc.S │ │ ├── sanitizer_common_interface.inc │ │ ├── sanitizer_common_interface_posix.inc │ │ ├── sanitizer_common_libcdep.cpp │ │ ├── sanitizer_common_nolibc.cpp │ │ ├── sanitizer_common_syscalls.inc │ │ ├── sanitizer_coverage_fuchsia.cpp │ │ ├── sanitizer_coverage_interface.inc │ │ ├── sanitizer_coverage_libcdep_new.cpp │ │ ├── sanitizer_coverage_win_dll_thunk.cpp │ │ ├── sanitizer_coverage_win_dynamic_runtime_thunk.cpp │ │ ├── sanitizer_coverage_win_sections.cpp │ │ ├── sanitizer_coverage_win_weak_interception.cpp │ │ ├── sanitizer_dbghelp.h │ │ ├── sanitizer_deadlock_detector.h │ │ ├── sanitizer_deadlock_detector1.cpp │ │ ├── sanitizer_deadlock_detector2.cpp │ │ ├── sanitizer_deadlock_detector_interface.h │ │ ├── sanitizer_errno.cpp │ │ ├── sanitizer_errno.h │ │ ├── sanitizer_errno_codes.h │ │ ├── sanitizer_file.cpp │ │ ├── sanitizer_file.h │ │ ├── sanitizer_flag_parser.cpp │ │ ├── sanitizer_flag_parser.h │ │ ├── sanitizer_flags.cpp │ │ ├── sanitizer_flags.h │ │ ├── sanitizer_flags.inc │ │ ├── sanitizer_freebsd.h │ │ ├── sanitizer_fuchsia.cpp │ │ ├── sanitizer_fuchsia.h │ │ ├── sanitizer_getauxval.h │ │ ├── sanitizer_glibc_version.h │ │ ├── sanitizer_hash.h │ │ ├── sanitizer_interceptors_ioctl_netbsd.inc │ │ ├── sanitizer_interface_internal.h │ │ ├── sanitizer_internal_defs.h │ │ ├── sanitizer_lfstack.h │ │ ├── sanitizer_libc.cpp │ │ ├── sanitizer_libc.h │ │ ├── sanitizer_libignore.cpp │ │ ├── sanitizer_libignore.h │ │ ├── sanitizer_linux.cpp │ │ ├── sanitizer_linux.h │ │ ├── sanitizer_linux_libcdep.cpp │ │ ├── sanitizer_linux_s390.cpp │ │ ├── sanitizer_list.h │ │ ├── sanitizer_local_address_space_view.h │ │ ├── sanitizer_mac.cpp │ │ ├── sanitizer_mac.h │ │ ├── sanitizer_mac_libcdep.cpp │ │ ├── sanitizer_malloc_mac.inc │ │ ├── sanitizer_mutex.h │ │ ├── sanitizer_netbsd.cpp │ │ ├── sanitizer_openbsd.cpp │ │ ├── sanitizer_persistent_allocator.cpp │ │ ├── sanitizer_persistent_allocator.h │ │ ├── sanitizer_placement_new.h │ │ ├── sanitizer_platform.h │ │ ├── sanitizer_platform_interceptors.h │ │ ├── sanitizer_platform_limits_freebsd.cpp │ │ ├── sanitizer_platform_limits_freebsd.h │ │ ├── sanitizer_platform_limits_linux.cpp │ │ ├── sanitizer_platform_limits_netbsd.cpp │ │ ├── sanitizer_platform_limits_netbsd.h │ │ ├── sanitizer_platform_limits_openbsd.cpp │ │ ├── sanitizer_platform_limits_openbsd.h │ │ ├── sanitizer_platform_limits_posix.cpp │ │ ├── sanitizer_platform_limits_posix.h │ │ ├── sanitizer_platform_limits_solaris.cpp │ │ ├── sanitizer_platform_limits_solaris.h │ │ ├── sanitizer_posix.cpp │ │ ├── sanitizer_posix.h │ │ ├── sanitizer_posix_libcdep.cpp │ │ ├── sanitizer_printf.cpp │ │ ├── sanitizer_procmaps.h │ │ ├── sanitizer_procmaps_bsd.cpp │ │ ├── sanitizer_procmaps_common.cpp │ │ ├── sanitizer_procmaps_fuchsia.cpp │ │ ├── sanitizer_procmaps_linux.cpp │ │ ├── sanitizer_procmaps_mac.cpp │ │ ├── sanitizer_procmaps_solaris.cpp │ │ ├── sanitizer_ptrauth.h │ │ ├── sanitizer_quarantine.h │ │ ├── sanitizer_report_decorator.h │ │ ├── sanitizer_ring_buffer.h │ │ ├── sanitizer_rtems.cpp │ │ ├── sanitizer_rtems.h │ │ ├── sanitizer_signal_interceptors.inc │ │ ├── sanitizer_solaris.cpp │ │ ├── sanitizer_stackdepot.cpp │ │ ├── sanitizer_stackdepot.h │ │ ├── sanitizer_stackdepotbase.h │ │ ├── sanitizer_stacktrace.cpp │ │ ├── sanitizer_stacktrace.h │ │ ├── sanitizer_stacktrace_libcdep.cpp │ │ ├── sanitizer_stacktrace_printer.cpp │ │ ├── sanitizer_stacktrace_printer.h │ │ ├── sanitizer_stacktrace_sparc.cpp │ │ ├── sanitizer_stoptheworld.h │ │ ├── sanitizer_stoptheworld_fuchsia.cpp │ │ ├── sanitizer_stoptheworld_linux_libcdep.cpp │ │ ├── sanitizer_stoptheworld_mac.cpp │ │ ├── sanitizer_stoptheworld_netbsd_libcdep.cpp │ │ ├── sanitizer_suppressions.cpp │ │ ├── sanitizer_suppressions.h │ │ ├── sanitizer_symbolizer.cpp │ │ ├── sanitizer_symbolizer.h │ │ ├── sanitizer_symbolizer_fuchsia.h │ │ ├── sanitizer_symbolizer_internal.h │ │ ├── sanitizer_symbolizer_libbacktrace.cpp │ │ ├── sanitizer_symbolizer_libbacktrace.h │ │ ├── sanitizer_symbolizer_libcdep.cpp │ │ ├── sanitizer_symbolizer_mac.cpp │ │ ├── sanitizer_symbolizer_mac.h │ │ ├── sanitizer_symbolizer_markup.cpp │ │ ├── sanitizer_symbolizer_posix_libcdep.cpp │ │ ├── sanitizer_symbolizer_report.cpp │ │ ├── sanitizer_symbolizer_rtems.h │ │ ├── sanitizer_symbolizer_win.cpp │ │ ├── sanitizer_syscall_generic.inc │ │ ├── sanitizer_syscall_linux_aarch64.inc │ │ ├── sanitizer_syscall_linux_arm.inc │ │ ├── sanitizer_syscall_linux_x86_64.inc │ │ ├── sanitizer_syscalls_netbsd.inc │ │ ├── sanitizer_termination.cpp │ │ ├── sanitizer_thread_registry.cpp │ │ ├── sanitizer_thread_registry.h │ │ ├── sanitizer_tls_get_addr.cpp │ │ ├── sanitizer_tls_get_addr.h │ │ ├── sanitizer_type_traits.cpp │ │ ├── sanitizer_type_traits.h │ │ ├── sanitizer_unwind_linux_libcdep.cpp │ │ ├── sanitizer_unwind_win.cpp │ │ ├── sanitizer_vector.h │ │ ├── sanitizer_win.cpp │ │ ├── sanitizer_win.h │ │ ├── sanitizer_win_defs.h │ │ ├── sanitizer_win_dll_thunk.cpp │ │ ├── sanitizer_win_dll_thunk.h │ │ ├── sanitizer_win_dynamic_runtime_thunk.cpp │ │ ├── sanitizer_win_weak_interception.cpp │ │ ├── sanitizer_win_weak_interception.h │ │ ├── scripts │ │ ├── check_lint.sh │ │ ├── cpplint.py │ │ ├── gen_dynamic_list.py │ │ ├── litlint.py │ │ ├── litlint_test.py │ │ └── sancov.py │ │ ├── symbolizer │ │ ├── sanitizer_symbolize.cpp │ │ ├── sanitizer_wrappers.cpp │ │ └── scripts │ │ │ ├── ar_to_bc.sh │ │ │ ├── build_symbolizer.sh │ │ │ └── global_symbols.txt │ │ ├── tests │ │ ├── CMakeLists.txt │ │ ├── malloc_stress_transfer_test.cpp │ │ ├── sanitizer_allocator_test.cpp │ │ ├── sanitizer_allocator_testlib.cpp │ │ ├── sanitizer_atomic_test.cpp │ │ ├── sanitizer_bitvector_test.cpp │ │ ├── sanitizer_bvgraph_test.cpp │ │ ├── sanitizer_common_test.cpp │ │ ├── sanitizer_deadlock_detector_test.cpp │ │ ├── sanitizer_flags_test.cpp │ │ ├── sanitizer_format_interceptor_test.cpp │ │ ├── sanitizer_ioctl_test.cpp │ │ ├── sanitizer_libc_test.cpp │ │ ├── sanitizer_linux_test.cpp │ │ ├── sanitizer_list_test.cpp │ │ ├── sanitizer_mac_test.cpp │ │ ├── sanitizer_mutex_test.cpp │ │ ├── sanitizer_nolibc_test.cpp │ │ ├── sanitizer_nolibc_test_main.cpp │ │ ├── sanitizer_posix_test.cpp │ │ ├── sanitizer_printf_test.cpp │ │ ├── sanitizer_procmaps_test.cpp │ │ ├── sanitizer_pthread_wrappers.h │ │ ├── sanitizer_quarantine_test.cpp │ │ ├── sanitizer_ring_buffer_test.cpp │ │ ├── sanitizer_stackdepot_test.cpp │ │ ├── sanitizer_stacktrace_printer_test.cpp │ │ ├── sanitizer_stacktrace_test.cpp │ │ ├── sanitizer_stoptheworld_test.cpp │ │ ├── sanitizer_stoptheworld_testlib.cpp │ │ ├── sanitizer_suppressions_test.cpp │ │ ├── sanitizer_symbolizer_test.cpp │ │ ├── sanitizer_test_config.h │ │ ├── sanitizer_test_main.cpp │ │ ├── sanitizer_test_utils.h │ │ ├── sanitizer_thread_registry_test.cpp │ │ ├── sanitizer_type_traits_test.cpp │ │ ├── sanitizer_vector_test.cpp │ │ └── standalone_malloc_test.cpp │ │ └── weak_symbols.txt ├── memlog_rt │ ├── CMakeLists.txt │ ├── include │ │ └── memlog.h │ └── memlog.c └── pass │ ├── CMakeLists.txt │ ├── DataFlowSanitizer.cpp │ └── MemlogPass.cc ├── test ├── Makefile ├── environment │ ├── atexit_test.cpp │ ├── atexit_test_in_preinit.cpp │ ├── bit_fields_test.c │ ├── color_test.c │ ├── env_child_test.c │ ├── env_test.c │ ├── float_test.c │ ├── fstream_test.cpp │ ├── getElementPtr_example.c │ ├── init_test.c │ ├── mmap_test.c │ ├── opt_priority_test.c │ ├── preinit_test.c │ ├── pthread_test.c │ ├── shm_test.c │ ├── strchr_test.c │ ├── test.c │ ├── typedef_test.c │ ├── union_test.c │ ├── va_test.c │ └── wait_test.c ├── hook_test │ ├── Makefile │ ├── hook3_test.c │ ├── hook4_test.c │ ├── hook5_test.c │ ├── hook6_test.c │ ├── test.txt │ ├── testcases │ │ └── test.txt │ ├── va_arg_hook1_test.c │ └── va_arg_hook1_test_with_constraint.c ├── target.c ├── test.cpp └── test.txt └── tools ├── gen_library_abilist.sh ├── gen_target_abilist.sh ├── gen_udr_abilist.sh ├── instrument_compiler_debug.sh ├── instrument_debug.sh └── instrument_debug_single.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .gdb_history 2 | /target/* 3 | /build/* 4 | .vscode 5 | /.vscode/* 6 | .gitignore 7 | /test/hook_test/*_test 8 | /test/hook_test/*_afl 9 | /test/target 10 | /test/test 11 | /test/environment/*_test 12 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "cctype": "cpp", 4 | "clocale": "cpp", 5 | "cmath": "cpp", 6 | "cstdarg": "cpp", 7 | "cstddef": "cpp", 8 | "cstdio": "cpp", 9 | "cstdlib": "cpp", 10 | "cstring": "cpp", 11 | "ctime": "cpp", 12 | "cwchar": "cpp", 13 | "cwctype": "cpp", 14 | "array": "cpp", 15 | "atomic": "cpp", 16 | "bit": "cpp", 17 | "*.tcc": "cpp", 18 | "bitset": "cpp", 19 | "chrono": "cpp", 20 | "condition_variable": "cpp", 21 | "cstdint": "cpp", 22 | "deque": "cpp", 23 | "map": "cpp", 24 | "unordered_map": "cpp", 25 | "vector": "cpp", 26 | "exception": "cpp", 27 | "algorithm": "cpp", 28 | "functional": "cpp", 29 | "iterator": "cpp", 30 | "memory": "cpp", 31 | "memory_resource": "cpp", 32 | "numeric": "cpp", 33 | "optional": "cpp", 34 | "random": "cpp", 35 | "ratio": "cpp", 36 | "string": "cpp", 37 | "string_view": "cpp", 38 | "system_error": "cpp", 39 | "tuple": "cpp", 40 | "type_traits": "cpp", 41 | "utility": "cpp", 42 | "fstream": "cpp", 43 | "initializer_list": "cpp", 44 | "iosfwd": "cpp", 45 | "istream": "cpp", 46 | "limits": "cpp", 47 | "mutex": "cpp", 48 | "new": "cpp", 49 | "ostream": "cpp", 50 | "shared_mutex": "cpp", 51 | "sstream": "cpp", 52 | "stdexcept": "cpp", 53 | "streambuf": "cpp", 54 | "thread": "cpp", 55 | "cinttypes": "cpp", 56 | "typeinfo": "cpp", 57 | "iostream": "cpp", 58 | "list": "cpp", 59 | "set": "cpp", 60 | "*.inc": "cpp", 61 | "types.h": "c", 62 | "config.h": "c", 63 | "signal.h": "c", 64 | "android-ashmem.h": "c", 65 | "sanitizer_internal_defs.h": "c", 66 | "csignal": "cpp", 67 | "strstream": "cpp", 68 | "complex": "cpp", 69 | "unordered_set": "cpp", 70 | "hash_map": "cpp", 71 | "hash_set": "cpp", 72 | "iomanip": "cpp", 73 | "cfenv": "cpp", 74 | "typeindex": "cpp", 75 | "variant": "cpp", 76 | "stdio.h": "c", 77 | "common_interface_defs.h": "c", 78 | "*.def": "cpp", 79 | "stddef.h": "c", 80 | "snapshot-inl.h": "c", 81 | "fcntl.h": "c", 82 | "wait.h": "c", 83 | "waitflags.h": "c", 84 | "memlog.h": "c", 85 | "hash.h": "c", 86 | "xxhash.h": "c" 87 | } 88 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | project(dtaint) 4 | 5 | set( CMAKE_EXPORT_COMPILE_COMMANDS 1 ) 6 | find_package(LLVM REQUIRED CONFIG) 7 | #add_definitions(${LLVM_DEFINITIONS}) 8 | #include_directories(${LLVM_INCLUDE_DIRS}) 9 | #link_directories(${LLVM_LIBRARY_DIRS}) 10 | 11 | add_subdirectory(src) 12 | 13 | -------------------------------------------------------------------------------- /clang-llvm-install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sudo apt-get install clang-11 4 | sudo apt-get install llvm-11 lldb-11 llvm-11-dev libllvm11 llvm-11-runtime -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1) 2 | 3 | include_directories(dfsan_rt) 4 | 5 | set(DTAINT_BIN_DIR "${CMAKE_BINARY_DIR}") 6 | set(DTAINT_LIB_DIR "${CMAKE_BINARY_DIR}/lib") 7 | set(DTAINT_PASS_DIR "${CMAKE_BINARY_DIR}/pass") 8 | 9 | add_subdirectory(abilist) 10 | add_subdirectory(afl_rt) 11 | add_subdirectory(compiler) 12 | add_subdirectory(dfsan_rt) 13 | add_subdirectory(pass) 14 | add_subdirectory(memlog_rt) 15 | 16 | #dfsan_abilist 17 | set(dfsan_abilist_dir ${DTAINT_LIB_DIR}/share) 18 | set(dfsan_abilist_filename ${dfsan_abilist_dir}/dfsan_abilist.txt) 19 | add_custom_target(dfsan_abilist ALL 20 | DEPENDS ${dfsan_abilist_filename}) 21 | add_custom_command(OUTPUT ${dfsan_abilist_filename} 22 | VERBATIM 23 | COMMAND 24 | ${CMAKE_COMMAND} -E make_directory ${dfsan_abilist_dir} 25 | COMMAND 26 | cat ${CMAKE_CURRENT_SOURCE_DIR}/abilist/done_abilist.txt 27 | ${CMAKE_CURRENT_SOURCE_DIR}/abilist/libc_ubuntu1404_abilist.txt 28 | > ${dfsan_abilist_filename} 29 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/abilist/done_abilist.txt 30 | ${CMAKE_CURRENT_SOURCE_DIR}/abilist/libc_ubuntu1404_abilist.txt) 31 | add_dependencies(dfsan dfsan_abilist) 32 | install(FILES ${dfsan_abilist_filename} 33 | DESTINATION ${DTAINT_LIB_DIR}/share) 34 | #hook_abilist 35 | set(hook_abilist_dir ${DTAINT_LIB_DIR}/share) 36 | set(hook_abilist_filename ${hook_abilist_dir}/hook_abilist.txt) 37 | add_custom_target(hook_abilist ALL 38 | DEPENDS ${hook_abilist_filename}) 39 | add_custom_command(OUTPUT ${hook_abilist_filename} 40 | VERBATIM 41 | COMMAND 42 | ${CMAKE_COMMAND} -E make_directory ${hook_abilist_dir} 43 | COMMAND 44 | cat ${CMAKE_CURRENT_SOURCE_DIR}/abilist/hook_abilist.txt 45 | > ${hook_abilist_filename} 46 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/abilist/hook_abilist.txt) 47 | install(FILES ${hook_abilist_filename} 48 | DESTINATION ${DTAINT_LIB_DIR}/share) -------------------------------------------------------------------------------- /src/abilist/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #target_abilist 2 | set(target_abilist_dir ${DTAINT_LIB_DIR}/share) 3 | set(target_abilist_filename ${target_abilist_dir}/target_abilist.txt) 4 | add_custom_target(target_abilist ALL 5 | DEPENDS ${target_abilist_filename}) 6 | message(STATUS ${CMAKE_CURRENT_SOURCE_DIR}) 7 | add_custom_command(OUTPUT ${target_abilist_filename} 8 | VERBATIM 9 | COMMAND 10 | ${CMAKE_COMMAND} -E make_directory ${target_abilist_dir} 11 | COMMAND 12 | find ${CMAKE_CURRENT_SOURCE_DIR}/target -type f -exec cat {} + 13 | > ${target_abilist_filename} 14 | 15 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/target/*) 16 | install(FILES ${target_abilist_filename} 17 | DESTINATION ${DTAINT_LIB_DIR}/share) -------------------------------------------------------------------------------- /src/abilist/hook_abilist.txt: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Hook functions 3 | ############################################################################### 4 | fun:malloc=hook 5 | fun:malloc=hook5 6 | fun:free=hook 7 | fun:free=hook6 8 | fun:realloc=hook 9 | fun:realloc=hook7 10 | fun:calloc=hook 11 | fun:calloc=hook5 12 | 13 | fun:memcpy=hook 14 | fun:memcpy=hook4 15 | fun:memset=hook 16 | fun:memset=hook3 17 | fun:memmove=hook 18 | fun:memmove=hook4 19 | fun:memcmp=hook 20 | fun:memcmp=hook4 21 | 22 | fun:strncat=hook 23 | fun:strncat=hook4 24 | fun:strncmp=hook 25 | fun:strncmp=hook4 26 | fun:strncpy=hook 27 | fun:strncpy=hook4 -------------------------------------------------------------------------------- /src/abilist/target/exif_abilist.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tl455047/DTaint/5eef3faa1e460f11b447ebce65d86ab0b613a36e/src/abilist/target/exif_abilist.txt -------------------------------------------------------------------------------- /src/abilist/target/libsixel_abilist.txt: -------------------------------------------------------------------------------- 1 | fun:png_sig_cmp=uninstrumented 2 | fun:jpeg_std_error=uninstrumented 3 | fun:jpeg_CreateDecompress=uninstrumented 4 | fun:jpeg_mem_src=uninstrumented 5 | fun:jpeg_read_header=uninstrumented 6 | fun:jpeg_start_decompress=uninstrumented 7 | fun:jpeg_read_scanlines=uninstrumented 8 | fun:jpeg_finish_decompress=uninstrumented 9 | fun:jpeg_destroy_decompress=uninstrumented 10 | fun:png_create_read_struct=uninstrumented 11 | fun:png_set_longjmp_fn=uninstrumented 12 | fun:png_destroy_read_struct=uninstrumented 13 | fun:png_create_info_struct=uninstrumented 14 | fun:png_set_read_fn=uninstrumented 15 | fun:png_read_info=uninstrumented 16 | fun:png_get_image_width=uninstrumented 17 | fun:png_get_image_height=uninstrumented 18 | fun:png_get_bit_depth=uninstrumented 19 | fun:png_set_strip_16=uninstrumented 20 | fun:png_destroy_read_struct=uninstrumented 21 | fun:png_get_bKGD=uninstrumented 22 | fun:png_get_color_type=uninstrumented 23 | fun:png_set_background=uninstrumented 24 | fun:png_get_PLTE=uninstrumented 25 | fun:png_set_background=uninstrumented 26 | fun:png_set_palette_to_rgb=uninstrumented 27 | fun:png_set_strip_alpha=uninstrumented 28 | fun:png_set_background=uninstrumented 29 | fun:png_set_expand_gray_1_2_4_to_8=uninstrumented 30 | fun:png_set_background=uninstrumented 31 | fun:png_set_gray_to_rgb=uninstrumented 32 | fun:png_read_image=uninstrumented 33 | fun:png_set_background=uninstrumented 34 | fun:png_set_palette_to_rgb=uninstrumented 35 | fun:png_get_io_ptr=uninstrumented 36 | fun:png_get_valid=uninstrumented 37 | fun:png_get_tRNS=uninstrumented 38 | fun:png_sig_cmp=discard 39 | fun:jpeg_std_error=discard 40 | fun:jpeg_CreateDecompress=discard 41 | fun:jpeg_mem_src=discard 42 | fun:jpeg_read_header=discard 43 | fun:jpeg_start_decompress=discard 44 | fun:jpeg_read_scanlines=discard 45 | fun:jpeg_finish_decompress=discard 46 | fun:jpeg_destroy_decompress=discard 47 | fun:png_create_read_struct=discard 48 | fun:png_set_longjmp_fn=discard 49 | fun:png_destroy_read_struct=discard 50 | fun:png_create_info_struct=discard 51 | fun:png_set_read_fn=discard 52 | fun:png_read_info=discard 53 | fun:png_get_image_width=discard 54 | fun:png_get_image_height=discard 55 | fun:png_get_bit_depth=discard 56 | fun:png_set_strip_16=discard 57 | fun:png_destroy_read_struct=discard 58 | fun:png_get_bKGD=discard 59 | fun:png_get_color_type=discard 60 | fun:png_set_background=discard 61 | fun:png_get_PLTE=discard 62 | fun:png_set_background=discard 63 | fun:png_set_palette_to_rgb=discard 64 | fun:png_set_strip_alpha=discard 65 | fun:png_set_background=discard 66 | fun:png_set_expand_gray_1_2_4_to_8=discard 67 | fun:png_set_background=discard 68 | fun:png_set_gray_to_rgb=discard 69 | fun:png_read_image=discard 70 | fun:png_set_background=discard 71 | fun:png_set_palette_to_rgb=discard 72 | fun:png_get_io_ptr=discard 73 | fun:png_get_valid=discard 74 | fun:png_get_tRNS=discard 75 | -------------------------------------------------------------------------------- /src/afl_rt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | 3 | add_library(afl_rt STATIC 4 | afl-compiler-rt.o.c) 5 | 6 | include_directories(include) 7 | include_directories(../dfsan_rt/extension/include) 8 | include_directories(../memlog_rt/include) 9 | 10 | set_target_properties(afl_rt 11 | PROPERTIES 12 | ARCHIVE_OUTPUT_DIRECTORY "${DTAINT_LIB_DIR}" 13 | COMPILE_FLAGS "-funroll-loops -fPIC -fPIE -O3 -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign" 14 | ) 15 | -------------------------------------------------------------------------------- /src/afl_rt/llvm-alternative-coverage.h: -------------------------------------------------------------------------------- 1 | #ifndef AFL_NGRAM_CONFIG_H 2 | #define AFL_NGRAM_CONFIG_H 3 | 4 | #include "types.h" 5 | 6 | #if (MAP_SIZE_POW2 <= 16) 7 | typedef u16 PREV_LOC_T; 8 | #elif (MAP_SIZE_POW2 <= 32) 9 | typedef u32 PREV_LOC_T; 10 | #else 11 | typedef u64 PREV_LOC_T; 12 | #endif 13 | 14 | /* Maximum ngram size */ 15 | #define NGRAM_SIZE_MAX 16U 16 | 17 | /* Maximum K for top-K context sensitivity */ 18 | #define CTX_MAX_K 32U 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /src/compiler/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_executable(clang-wrapper clang_wrapper.c) 3 | 4 | include_directories(include) 5 | 6 | set_target_properties(clang-wrapper 7 | PROPERTIES 8 | RUNTIME_OUTPUT_DIRECTORY "${DTAINT_BIN_DIR}" 9 | ) 10 | 11 | add_custom_command(TARGET clang-wrapper POST_BUILD 12 | COMMAND ln -sf "clang-wrapper" "${DTAINT_BIN_DIR}/clang-wrapper++") 13 | -------------------------------------------------------------------------------- /src/compiler/include/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2013 Google LLC All rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at: 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | 18 | /* 19 | american fuzzy lop - type definitions and minor macros 20 | ------------------------------------------------------ 21 | 22 | Written and maintained by Michal Zalewski 23 | */ 24 | 25 | #ifndef _HAVE_TYPES_H 26 | #define _HAVE_TYPES_H 27 | 28 | #include 29 | #include 30 | 31 | typedef uint8_t u8; 32 | typedef uint16_t u16; 33 | typedef uint32_t u32; 34 | 35 | /* 36 | 37 | Ugh. There is an unintended compiler / glibc #include glitch caused by 38 | combining the u64 type an %llu in format strings, necessitating a workaround. 39 | 40 | In essence, the compiler is always looking for 'unsigned long long' for %llu. 41 | On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to 42 | 'unsigned long long' in , so everything checks out. 43 | 44 | But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'. 45 | Now, it only happens in circumstances where the type happens to have the 46 | expected bit width, *but* the compiler does not know that... and complains 47 | about 'unsigned long' being unsafe to pass to %llu. 48 | 49 | */ 50 | 51 | #ifdef __x86_64__ 52 | typedef unsigned long long u64; 53 | #else 54 | typedef uint64_t u64; 55 | #endif /* ^__x86_64__ */ 56 | 57 | typedef int8_t s8; 58 | typedef int16_t s16; 59 | typedef int32_t s32; 60 | typedef int64_t s64; 61 | 62 | #ifndef MIN 63 | # define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a)) 64 | # define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b)) 65 | #endif /* !MIN */ 66 | 67 | #define SWAP16(_x) ({ \ 68 | u16 _ret = (_x); \ 69 | (u16)((_ret << 8) | (_ret >> 8)); \ 70 | }) 71 | 72 | #define SWAP32(_x) ({ \ 73 | u32 _ret = (_x); \ 74 | (u32)((_ret << 24) | (_ret >> 24) | \ 75 | ((_ret << 8) & 0x00FF0000) | \ 76 | ((_ret >> 8) & 0x0000FF00)); \ 77 | }) 78 | 79 | #ifdef AFL_LLVM_PASS 80 | # define AFL_R(x) (random() % (x)) 81 | #else 82 | # define R(x) (random() % (x)) 83 | #endif /* ^AFL_LLVM_PASS */ 84 | 85 | #define STRINGIFY_INTERNAL(x) #x 86 | #define STRINGIFY(x) STRINGIFY_INTERNAL(x) 87 | 88 | #define MEM_BARRIER() \ 89 | __asm__ volatile("" ::: "memory") 90 | 91 | #define likely(_x) __builtin_expect(!!(_x), 1) 92 | #define unlikely(_x) __builtin_expect(!!(_x), 0) 93 | 94 | #endif /* ! _HAVE_TYPES_H */ 95 | -------------------------------------------------------------------------------- /src/dfsan_rt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 2 | 3 | set(COMPILER_RT_OUTPUT_DIR ${DTAINT_LIB_DIR} CACHE PATH 4 | "Path where built compiler-rt libraries should be stored.") 5 | set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH 6 | "Path where built compiler-rt executables should be stored.") 7 | set(COMPILER_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 8 | set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH 9 | "Path where built compiler-rt libraries should be installed.") 10 | 11 | set(COMPILER_RT_LIBRARY_OUTPUT_DIR ${COMPILER_RT_OUTPUT_DIR}) 12 | set(COMPILER_RT_LIBRARY_INSTALL_DIR ${DTAINT_LIB_DIR}) 13 | 14 | 15 | set(ARM64 aarch64) 16 | set(X86_64 x86_64) 17 | set(MIPS64 mips64 mips64el) 18 | 19 | if(APPLE) 20 | set(ARM64 arm64) 21 | set(X86_64 x86_64 x86_64h) 22 | endif() 23 | 24 | set(CAN_TARGET_${X86_64} 1) 25 | set(DFSAN_SUPPORTED_ARCH ${X86_64}) # ${MIPS64} ${ARM64} 26 | set(SANITIZER_COMMON_SUPPORTED_ARCH ${X86_64}) # ${MIPS64} ${ARM64} 27 | 28 | list(APPEND SANITIZER_COMMON_CFLAGS -O3) 29 | list(APPEND SANITIZER_COMMON_CFLAGS -fPIC) 30 | 31 | include(CheckIncludeFile) 32 | check_include_file(rpc/xdr.h HAVE_RPC_XDR_H) 33 | if (NOT HAVE_RPC_XDR_H) 34 | set(HAVE_RPC_XDR_H 0) 35 | endif() 36 | 37 | add_custom_target(compiler-rt ALL) 38 | add_custom_target(install-compiler-rt) 39 | add_custom_target(install-compiler-rt-stripped) 40 | 41 | set_property( 42 | TARGET 43 | compiler-rt 44 | install-compiler-rt 45 | install-compiler-rt-stripped 46 | PROPERTY 47 | FOLDER "Compiler-RT Misc" 48 | ) 49 | 50 | include(AddCompilerRT) 51 | include(SanitizerUtils) 52 | 53 | include_directories(include/sanitizer) 54 | set(CMAKE_CXX_STANDARD 11) 55 | 56 | add_subdirectory(sanitizer_common) 57 | add_subdirectory(interception) 58 | add_subdirectory(dfsan) -------------------------------------------------------------------------------- /src/dfsan_rt/cmake/CompilerRTLink.cmake: -------------------------------------------------------------------------------- 1 | # Link a shared library with COMPILER_RT_TEST_COMPILER. 2 | # clang_link_shared( 3 | # OBJECTS 4 | # LINK_FLAGS 5 | # DEPS ) 6 | macro(clang_link_shared so_file) 7 | cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINK_FLAGS;DEPS" ${ARGN}) 8 | if(NOT COMPILER_RT_STANDALONE_BUILD) 9 | list(APPEND SOURCE_DEPS clang) 10 | endif() 11 | add_custom_command( 12 | OUTPUT ${so_file} 13 | COMMAND ${COMPILER_RT_TEST_COMPILER} -o "${so_file}" -shared 14 | ${SOURCE_LINK_FLAGS} ${SOURCE_OBJECTS} 15 | DEPENDS ${SOURCE_DEPS}) 16 | endmacro() 17 | -------------------------------------------------------------------------------- /src/dfsan_rt/cmake/UseLibtool.cmake: -------------------------------------------------------------------------------- 1 | # if CMAKE_LIBTOOL is not set, try and find it with xcrun or find_program 2 | if(NOT CMAKE_LIBTOOL) 3 | if(NOT CMAKE_XCRUN) 4 | find_program(CMAKE_XCRUN NAMES xcrun) 5 | endif() 6 | if(CMAKE_XCRUN) 7 | execute_process(COMMAND ${CMAKE_XCRUN} -find libtool 8 | OUTPUT_VARIABLE CMAKE_LIBTOOL 9 | OUTPUT_STRIP_TRAILING_WHITESPACE) 10 | endif() 11 | 12 | if(NOT CMAKE_LIBTOOL OR NOT EXISTS CMAKE_LIBTOOL) 13 | find_program(CMAKE_LIBTOOL NAMES libtool) 14 | endif() 15 | endif() 16 | 17 | get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) 18 | if(CMAKE_LIBTOOL) 19 | set(CMAKE_LIBTOOL ${CMAKE_LIBTOOL} CACHE PATH "libtool executable") 20 | message(STATUS "Found libtool - ${CMAKE_LIBTOOL}") 21 | 22 | execute_process(COMMAND ${CMAKE_LIBTOOL} -V 23 | OUTPUT_VARIABLE LIBTOOL_V_OUTPUT 24 | OUTPUT_STRIP_TRAILING_WHITESPACE) 25 | if("${LIBTOOL_V_OUTPUT}" MATCHES ".*cctools-([0-9.]+).*") 26 | string(REGEX REPLACE ".*cctools-([0-9.]+).*" "\\1" LIBTOOL_VERSION 27 | ${LIBTOOL_V_OUTPUT}) 28 | if(NOT LIBTOOL_VERSION VERSION_LESS "862") 29 | set(LIBTOOL_NO_WARNING_FLAG "-no_warning_for_no_symbols") 30 | endif() 31 | endif() 32 | 33 | foreach(lang ${languages}) 34 | set(CMAKE_${lang}_CREATE_STATIC_LIBRARY 35 | "\"${CMAKE_LIBTOOL}\" -static ${LIBTOOL_NO_WARNING_FLAG} -o ") 36 | endforeach() 37 | endif() 38 | 39 | # If DYLD_LIBRARY_PATH is set we need to set it on archiver commands 40 | if(DYLD_LIBRARY_PATH) 41 | set(dyld_envar "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}") 42 | foreach(lang ${languages}) 43 | foreach(cmd ${CMAKE_${lang}_CREATE_STATIC_LIBRARY}) 44 | list(APPEND CMAKE_${lang}_CREATE_STATIC_LIBRARY_NEW 45 | "${dyld_envar} ${cmd}") 46 | endforeach() 47 | set(CMAKE_${lang}_CREATE_STATIC_LIBRARY 48 | ${CMAKE_${lang}_CREATE_STATIC_LIBRARY_NEW}) 49 | endforeach() 50 | endif() 51 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(..) 2 | 3 | include_directories(.) 4 | include_directories(../extension/include) 5 | include_directories(../sanitizer_common) 6 | include_directories(../../afl_rt/include) 7 | 8 | option(DTAINT_DEBUG "DTaint Debugging" OFF) 9 | 10 | # Runtime library sources and build flags. 11 | set(DFSAN_RTL_SOURCES 12 | dfsan.cpp 13 | dfsan_custom.cpp 14 | dfsan_interceptors.cpp 15 | dfsan_io.cpp 16 | event_callback.cpp 17 | ../extension/dfsan_union_t.cpp 18 | ../extension/dfsan_hook.cpp 19 | ) 20 | 21 | set(DFSAN_RTL_HEADERS 22 | dfsan.h 23 | dfsan_flags.inc 24 | dfsan_platform.h 25 | ) 26 | 27 | set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS}) 28 | append_rtti_flag(OFF DFSAN_COMMON_CFLAGS) 29 | # Prevent clang from generating libc calls. 30 | append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CFLAGS) 31 | list(APPEND DFSAN_CFLAGS -g -ggdb) 32 | # Static runtime library. 33 | add_compiler_rt_component(dfsan) 34 | 35 | foreach(arch ${DFSAN_SUPPORTED_ARCH}) 36 | set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS}) 37 | append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS) 38 | append_list_if(DTAINT_DEBUG -DDTAINT_DEBUG DFSAN_CFLAGS) #dtaint debug option 39 | add_compiler_rt_runtime(clang_rt.dfsan 40 | STATIC 41 | ARCHS ${arch} 42 | SOURCES ${DFSAN_RTL_SOURCES} 43 | $ 44 | $ 45 | $ 46 | ADDITIONAL_HEADERS ${DFSAN_RTL_HEADERS} 47 | CFLAGS ${DFSAN_CFLAGS} 48 | PARENT_TARGET dfsan) 49 | add_sanitizer_rt_symbols(clang_rt.dfsan 50 | ARCHS ${arch} 51 | EXTRA dfsan.syms.extra) 52 | add_dependencies(dfsan 53 | clang_rt.dfsan-${arch}-symbols) 54 | endforeach() 55 | 56 | #set(dfsan_abilist_dir ${COMPILER_RT_OUTPUT_DIR}/share) 57 | #set(dfsan_abilist_filename ${dfsan_abilist_dir}/dfsan_abilist.txt) 58 | #add_custom_target(dfsan_abilist ALL 59 | # DEPENDS ${dfsan_abilist_filename}) 60 | #add_custom_command(OUTPUT ${dfsan_abilist_filename} 61 | # VERBATIM 62 | # COMMAND 63 | # ${CMAKE_COMMAND} -E make_directory ${dfsan_abilist_dir} 64 | # COMMAND 65 | # cat ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt 66 | # ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1404_abilist.txt 67 | # > ${dfsan_abilist_filename} 68 | # DEPENDS done_abilist.txt libc_ubuntu1404_abilist.txt) 69 | #add_dependencies(dfsan dfsan_abilist) 70 | #install(FILES ${dfsan_abilist_filename} 71 | # DESTINATION ${COMPILER_RT_INSTALL_PATH}/share) 72 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/dfsan.h: -------------------------------------------------------------------------------- 1 | //===-- dfsan.h -------------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of DataFlowSanitizer. 10 | // 11 | // Private DFSan header. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef DFSAN_H 15 | #define DFSAN_H 16 | 17 | #include "sanitizer_common/sanitizer_internal_defs.h" 18 | #include "dfsan_platform.h" 19 | #include 20 | using __sanitizer::uptr; 21 | using __sanitizer::u16; 22 | using __sanitizer::u32; 23 | 24 | // Copy declarations from public sanitizer/dfsan_interface.h header here. 25 | // Change dfsan_label from u16 -> u32. 26 | typedef u32 dfsan_label; 27 | 28 | /*struct dfsan_label_info { 29 | dfsan_label l1; 30 | dfsan_label l2; 31 | const char *desc; 32 | void *userdata; 33 | };*/ 34 | 35 | extern "C" { 36 | void dfsan_add_label(dfsan_label label, void *addr, uptr size); 37 | void dfsan_set_label(dfsan_label label, void *addr, uptr size); 38 | dfsan_label dfsan_read_label(const void *addr, uptr size); 39 | dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2); 40 | dfsan_label dfsan_create_label(u32 pos); 41 | void dfsan_set_input_label(dfsan_label label, void *addr, uptr size); 42 | } // extern "C" 43 | 44 | template 45 | void dfsan_set_label(dfsan_label label, T &data) { // NOLINT 46 | dfsan_set_label(label, (void *)&data, sizeof(T)); 47 | } 48 | 49 | namespace __dfsan { 50 | 51 | void InitializeInterceptors(); 52 | 53 | inline dfsan_label *shadow_for(void *ptr) { 54 | // return (dfsan_label *) ((((uptr) ptr) & ShadowMask()) << 1); 55 | // 4 byte mapping. 56 | return (dfsan_label *) ((((uptr) ptr) & ShadowMask()) << 2); 57 | } 58 | 59 | inline const dfsan_label *shadow_for(const void *ptr) { 60 | return shadow_for(const_cast(ptr)); 61 | } 62 | 63 | struct Flags { 64 | #define DFSAN_FLAG(Type, Name, DefaultValue, Description) Type Name; 65 | #include "dfsan_flags.inc" 66 | #undef DFSAN_FLAG 67 | 68 | void SetDefaults(); 69 | }; 70 | 71 | extern Flags flags_data; 72 | inline Flags &flags() { 73 | return flags_data; 74 | } 75 | 76 | } // namespace __dfsan 77 | 78 | #endif // DFSAN_H 79 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/dfsan.syms.extra: -------------------------------------------------------------------------------- 1 | dfsan_* 2 | __dfsan_* 3 | __dfsw_* 4 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/dfsan_flags.inc: -------------------------------------------------------------------------------- 1 | //===-- dfsan_flags.inc -----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // DFSan runtime flags. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #ifndef DFSAN_FLAG 13 | # error "Define DFSAN_FLAG prior to including this file!" 14 | #endif 15 | 16 | // DFSAN_FLAG(Type, Name, DefaultValue, Description) 17 | // See COMMON_FLAG in sanitizer_flags.inc for more details. 18 | 19 | DFSAN_FLAG(bool, warn_unimplemented, true, 20 | "Whether to warn on unimplemented functions.") 21 | DFSAN_FLAG(bool, warn_nonzero_labels, false, 22 | "Whether to warn on unimplemented functions.") 23 | DFSAN_FLAG( 24 | bool, strict_data_dependencies, true, 25 | "Whether to propagate labels only when there is an obvious data dependency" 26 | "(e.g., when comparing strings, ignore the fact that the output of the" 27 | "comparison might be data-dependent on the content of the strings). This" 28 | "applies only to the custom functions defined in 'custom.c'.") 29 | DFSAN_FLAG(const char *, dump_labels_at_exit, "", "The path of the file where " 30 | "to dump the labels when the " 31 | "program terminates.") 32 | DFSAN_FLAG(bool, fast16labels, false, 33 | "Enables experimental mode where DFSan supports only 16 power-of-2 labels " 34 | "(1, 2, 4, 8, ... 32768) and the label union is computed as a bit-wise OR." 35 | ) 36 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/dfsan_interceptors.cpp: -------------------------------------------------------------------------------- 1 | //===-- dfsan_interceptors.cpp --------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of DataFlowSanitizer. 10 | // 11 | // Interceptors for standard library functions. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "dfsan/dfsan.h" 15 | #include "interception/interception.h" 16 | #include "sanitizer_common/sanitizer_common.h" 17 | 18 | using namespace __sanitizer; 19 | 20 | INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, 21 | int fd, OFF_T offset) { 22 | void *res = REAL(mmap)(addr, length, prot, flags, fd, offset); 23 | if (res != (void*)-1) 24 | dfsan_set_label(0, res, RoundUpTo(length, GetPageSize())); 25 | return res; 26 | } 27 | 28 | INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, 29 | int fd, OFF64_T offset) { 30 | void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset); 31 | if (res != (void*)-1) 32 | dfsan_set_label(0, res, RoundUpTo(length, GetPageSize())); 33 | return res; 34 | } 35 | 36 | namespace __dfsan { 37 | void InitializeInterceptors() { 38 | static int inited = 0; 39 | CHECK_EQ(inited, 0); 40 | 41 | INTERCEPT_FUNCTION(mmap); 42 | INTERCEPT_FUNCTION(mmap64); 43 | inited = 1; 44 | } 45 | } // namespace __dfsan 46 | -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/event_callback.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dfsan.h" 3 | #include "dfsan_union_t.h" 4 | #include "sanitizer_common/sanitizer_common.h" 5 | 6 | extern struct dfsan_label_info __dfsan_label_info; 7 | //static int total_count = 0, taint_count = 0, total_load_count = 0, taint_load_count = 0; 8 | 9 | extern "C" { 10 | void __dfsan_store_callback(dfsan_label Label) { 11 | if (!Label) 12 | return; 13 | //fprintf(stderr, "Label %u stored to memory\n", Label); 14 | } 15 | 16 | /** 17 | * Origin: 18 | * void __dfsan_load_callback(dfsan_label Label); 19 | * Modified: 20 | * void __dfsan_load_callback(dfsan_label Label, void* ptr, size_t size); 21 | */ 22 | /*void __dfsan_load_callback(dfsan_label Label) { 23 | total_load_count++; 24 | if (!Label) 25 | return; 26 | taint_load_count++; 27 | //dfsan_union_t_output_offset(&__dfsan_label_info, Label); 28 | dfsan_hook_load_inst(&__dfsan_label_info, Label); 29 | //fprintf(stderr, "Label %u loaded from memory %u/%u\n", Label, taint_load_count, total_load_count); 30 | }*/ 31 | 32 | void __dfsan_load_callback(dfsan_label Label, void* ptr, size_t size) { 33 | //total_load_count++; 34 | if (!Label) 35 | return; 36 | //taint_load_count++; 37 | //dfsan_union_t_output_offset(&__dfsan_label_info, Label); 38 | 39 | } 40 | 41 | void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len) { 42 | 43 | //fprintf(stderr, "Label %u copied to memory\n", Start[0]); 44 | } 45 | 46 | void __dfsan_cmp_callback(dfsan_label CombinedLabel) { 47 | //total_count++; 48 | if (!CombinedLabel) 49 | return; 50 | //taint_count++; 51 | //fprintf(stderr, "Label %u used for branching\n", CombinedLabel); 52 | 53 | } 54 | 55 | 56 | } -------------------------------------------------------------------------------- /src/dfsan_rt/dfsan/scripts/check_custom_wrappers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DFSAN_DIR=$(dirname "$0")/../ 4 | DFSAN_CUSTOM_TESTS=${DFSAN_DIR}/../../test/dfsan/custom.cpp 5 | DFSAN_CUSTOM_WRAPPERS=${DFSAN_DIR}/dfsan_custom.cpp 6 | DFSAN_ABI_LIST=${DFSAN_DIR}/done_abilist.txt 7 | 8 | DIFFOUT=$(mktemp -q /tmp/tmp.XXXXXXXXXX) 9 | ERRORLOG=$(mktemp -q /tmp/tmp.XXXXXXXXXX) 10 | DIFF_A=$(mktemp -q /tmp/tmp.XXXXXXXXXX) 11 | DIFF_B=$(mktemp -q /tmp/tmp.XXXXXXXXXX) 12 | 13 | on_exit() { 14 | rm -f ${DIFFOUT} 2> /dev/null 15 | rm -f ${ERRORLOG} 2> /dev/null 16 | rm -f ${DIFF_A} 2> /dev/null 17 | rm -f ${DIFF_B} 2> /dev/null 18 | } 19 | 20 | # Ignore __sanitizer_cov_trace* because they are implemented elsewhere. 21 | trap on_exit EXIT 22 | grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} \ 23 | | grep -v "dfsan_get_label\|__sanitizer_cov_trace" \ 24 | | sed "s/^fun:\(.*\)=custom.*/\1/" | sort > $DIFF_A 25 | grep -E "__dfsw.*\(" ${DFSAN_CUSTOM_WRAPPERS} \ 26 | | grep -v "__sanitizer_cov_trace" \ 27 | | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort > $DIFF_B 28 | diff -u $DIFF_A $DIFF_B > ${DIFFOUT} 29 | if [ $? -ne 0 ] 30 | then 31 | echo -n "The following differences between the ABI list and ">> ${ERRORLOG} 32 | echo "the implemented custom wrappers have been found:" >> ${ERRORLOG} 33 | cat ${DIFFOUT} >> ${ERRORLOG} 34 | fi 35 | 36 | grep -E __dfsw_ ${DFSAN_CUSTOM_WRAPPERS} \ 37 | | grep -v "__sanitizer_cov_trace" \ 38 | | sed "s/.*__dfsw_\([^(]*\).*/\1/" | sort > $DIFF_A 39 | grep -E "^[[:space:]]*test_.*\(\);" ${DFSAN_CUSTOM_TESTS} \ 40 | | sed "s/.*test_\(.*\)();/\1/" | sort > $DIFF_B 41 | diff -u $DIFF_A $DIFF_B > ${DIFFOUT} 42 | if [ $? -ne 0 ] 43 | then 44 | echo -n "The following differences between the implemented " >> ${ERRORLOG} 45 | echo "custom wrappers and the tests have been found:" >> ${ERRORLOG} 46 | cat ${DIFFOUT} >> ${ERRORLOG} 47 | fi 48 | 49 | if [ -s ${ERRORLOG} ] 50 | then 51 | cat ${ERRORLOG} 52 | exit 1 53 | fi 54 | 55 | -------------------------------------------------------------------------------- /src/dfsan_rt/extension/include/dtaint.h: -------------------------------------------------------------------------------- 1 | #ifndef _DTAINT_H_ 2 | #define _DTAINT_H_ 3 | 4 | #define DTAINT_MAP_W 1 << 16 5 | #define DTAINT_MAP_H 32 6 | #define DTAINT_MAXiMUM_IDX_NUM 8 7 | 8 | enum DFSanHookType { 9 | 10 | DFSH_UNKNOWN = 0, 11 | // __dfsan_hook1 (unsigned id, dfsan_label ptr_label); 12 | // ex. load inst. 13 | DFSH_HOOK1 = 1, 14 | // __dfsan_hook2 (unsigned id, dfsan_label value_label, dfsan_label ptr_label); 15 | // ex. store inst. 16 | DFSH_HOOK2 = 2, 17 | // __dfsan_hook2_int128 (unsigned id, dfsan_label value_label, dfsan_label ptr_label); 18 | // deal with 16byte float point value 19 | DFSH_HOOK2_INT128 = 3, 20 | // __dfsan_hook3 (unsigned id, dfsan_label ptr_label, dfsan_label c_label, dfsan_label size_label); 21 | // ex. memset 22 | DFSH_HOOK3 = 4, 23 | // __dfsan_hook4 (unsigned id, dfsan_label dst_label, dfsan_label src_label, dfsan_label size_label); 24 | // ex. memcpy 25 | DFSH_HOOK4 = 5, 26 | // __dfsan_hook5 (unsigned id, dfsan_label size_label); 27 | // ex. malloc 28 | DFSH_HOOK5 = 6, 29 | // __dfsan_hook6 (unsigned id, dfsan_label ptr_label); 30 | // ex. free 31 | DFSH_HOOK6 = 7, 32 | // __dfsan_hook7 (unsigned id, dfsan_label ptr_label, dfsan_label size_label); 33 | // ex. realloc 34 | DFSH_HOOK7 = 8, 35 | // __dfsan_va_arg_hook1 (unsigned id, dfsan_label ptr_label, unsigned num_of_idx, ...); 36 | // ex. get_element_ptr 37 | DFSH_VARARG_HOOK1 = 9 38 | 39 | }; 40 | 41 | struct dtainted { 42 | 43 | unsigned int pos; 44 | unsigned int len; 45 | 46 | } __attribute__((packed)); 47 | 48 | 49 | struct dtaint_offset_node { 50 | 51 | //total tainted bytes 52 | unsigned int len; 53 | // num of node 54 | unsigned int num; 55 | 56 | } __attribute__((packed)); 57 | 58 | struct va_arg_label_t { 59 | 60 | unsigned int num; 61 | unsigned int ptr_label; 62 | unsigned int idx_label[DTAINT_MAXiMUM_IDX_NUM]; 63 | 64 | } __attribute__((packed)); 65 | 66 | struct label_t { 67 | 68 | unsigned int src_label; 69 | unsigned int dst_label; 70 | unsigned int size_label; 71 | unsigned int value_label; 72 | 73 | }; 74 | 75 | union dtaint_label_t { 76 | 77 | struct va_arg_label_t __va_arg_label_t; 78 | struct label_t __label_t; 79 | 80 | }; 81 | 82 | struct dtaint_header { 83 | 84 | // instructions executed 85 | unsigned int hits; 86 | // unique id 87 | unsigned int id; 88 | //type 89 | unsigned int type; 90 | //label array 91 | 92 | } __attribute__((packed)); 93 | 94 | struct dtaint_map { 95 | 96 | struct dtaint_header headers[DTAINT_MAP_W]; 97 | union dtaint_label_t log[DTAINT_MAP_W][DTAINT_MAP_H]; 98 | struct dtaint_offset_node label_info[DTAINT_MAP_W]; 99 | struct dtainted offset_t[DTAINT_MAP_W][DTAINT_MAP_H]; 100 | unsigned int status; 101 | 102 | }; 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Build for the runtime interception helper library. 2 | 3 | set(INTERCEPTION_SOURCES 4 | interception_linux.cpp 5 | interception_mac.cpp 6 | interception_win.cpp 7 | interception_type_test.cpp 8 | ) 9 | 10 | set(INTERCEPTION_HEADERS 11 | interception.h 12 | interception_linux.h 13 | interception_mac.h 14 | interception_win.h 15 | ) 16 | 17 | include_directories(..) 18 | 19 | set(INTERCEPTION_CFLAGS ${SANITIZER_COMMON_CFLAGS}) 20 | append_rtti_flag(OFF INTERCEPTION_CFLAGS) 21 | 22 | add_compiler_rt_object_libraries(RTInterception 23 | OS ${SANITIZER_COMMON_SUPPORTED_OS} 24 | ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH} 25 | SOURCES ${INTERCEPTION_SOURCES} 26 | ADDITIONAL_HEADERS ${INTERCEPTION_HEADERS} 27 | CFLAGS ${INTERCEPTION_CFLAGS}) 28 | 29 | if(COMPILER_RT_INCLUDE_TESTS) 30 | add_subdirectory(tests) 31 | endif() 32 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/interception_linux.cpp: -------------------------------------------------------------------------------- 1 | //===-- interception_linux.cpp ----------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Linux-specific interception methods. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "interception.h" 15 | 16 | #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ 17 | SANITIZER_OPENBSD || SANITIZER_SOLARIS 18 | 19 | #include // for dlsym() and dlvsym() 20 | 21 | namespace __interception { 22 | 23 | #if SANITIZER_NETBSD 24 | static int StrCmp(const char *s1, const char *s2) { 25 | while (true) { 26 | if (*s1 != *s2) 27 | return false; 28 | if (*s1 == 0) 29 | return true; 30 | s1++; 31 | s2++; 32 | } 33 | } 34 | #endif 35 | 36 | static void *GetFuncAddr(const char *name, uptr wrapper_addr) { 37 | #if SANITIZER_NETBSD 38 | // FIXME: Find a better way to handle renames 39 | if (StrCmp(name, "sigaction")) 40 | name = "__sigaction14"; 41 | #endif 42 | void *addr = dlsym(RTLD_NEXT, name); 43 | if (!addr) { 44 | // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is 45 | // later in the library search order than the DSO that we are trying to 46 | // intercept, which means that we cannot intercept this function. We still 47 | // want the address of the real definition, though, so look it up using 48 | // RTLD_DEFAULT. 49 | addr = dlsym(RTLD_DEFAULT, name); 50 | 51 | // In case `name' is not loaded, dlsym ends up finding the actual wrapper. 52 | // We don't want to intercept the wrapper and have it point to itself. 53 | if ((uptr)addr == wrapper_addr) 54 | addr = nullptr; 55 | } 56 | return addr; 57 | } 58 | 59 | bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, 60 | uptr wrapper) { 61 | void *addr = GetFuncAddr(name, wrapper); 62 | *ptr_to_real = (uptr)addr; 63 | return addr && (func == wrapper); 64 | } 65 | 66 | // Android and Solaris do not have dlvsym 67 | #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD 68 | static void *GetFuncAddr(const char *name, const char *ver) { 69 | return dlvsym(RTLD_NEXT, name, ver); 70 | } 71 | 72 | bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, 73 | uptr func, uptr wrapper) { 74 | void *addr = GetFuncAddr(name, ver); 75 | *ptr_to_real = (uptr)addr; 76 | return addr && (func == wrapper); 77 | } 78 | #endif // !SANITIZER_ANDROID 79 | 80 | } // namespace __interception 81 | 82 | #endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || 83 | // SANITIZER_OPENBSD || SANITIZER_SOLARIS 84 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/interception_linux.h: -------------------------------------------------------------------------------- 1 | //===-- interception_linux.h ------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Linux-specific interception methods. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ 15 | SANITIZER_OPENBSD || SANITIZER_SOLARIS 16 | 17 | #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) 18 | # error "interception_linux.h should be included from interception library only" 19 | #endif 20 | 21 | #ifndef INTERCEPTION_LINUX_H 22 | #define INTERCEPTION_LINUX_H 23 | 24 | namespace __interception { 25 | bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, 26 | uptr wrapper); 27 | bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, 28 | uptr func, uptr wrapper); 29 | } // namespace __interception 30 | 31 | #define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ 32 | ::__interception::InterceptFunction( \ 33 | #func, \ 34 | (::__interception::uptr *) & REAL(func), \ 35 | (::__interception::uptr) & (func), \ 36 | (::__interception::uptr) & WRAP(func)) 37 | 38 | // Android, Solaris and OpenBSD do not have dlvsym 39 | #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD 40 | #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ 41 | ::__interception::InterceptFunction( \ 42 | #func, symver, \ 43 | (::__interception::uptr *) & REAL(func), \ 44 | (::__interception::uptr) & (func), \ 45 | (::__interception::uptr) & WRAP(func)) 46 | #else 47 | #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ 48 | INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) 49 | #endif // !SANITIZER_ANDROID && !SANITIZER_SOLARIS 50 | 51 | #endif // INTERCEPTION_LINUX_H 52 | #endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || 53 | // SANITIZER_OPENBSD || SANITIZER_SOLARIS 54 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/interception_mac.cpp: -------------------------------------------------------------------------------- 1 | //===-- interception_mac.cpp ------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Mac-specific interception methods. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "interception.h" 15 | 16 | #if SANITIZER_MAC 17 | 18 | #endif // SANITIZER_MAC 19 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/interception_mac.h: -------------------------------------------------------------------------------- 1 | //===-- interception_mac.h --------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Mac-specific interception methods. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #if SANITIZER_MAC 15 | 16 | #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) 17 | # error "interception_mac.h should be included from interception.h only" 18 | #endif 19 | 20 | #ifndef INTERCEPTION_MAC_H 21 | #define INTERCEPTION_MAC_H 22 | 23 | #define INTERCEPT_FUNCTION_MAC(func) 24 | #define INTERCEPT_FUNCTION_VER_MAC(func, symver) 25 | 26 | #endif // INTERCEPTION_MAC_H 27 | #endif // SANITIZER_MAC 28 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/interception_type_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- interception_type_test.cpp ------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Compile-time tests of the internal type definitions. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "interception.h" 15 | 16 | #if SANITIZER_LINUX || SANITIZER_MAC 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | COMPILER_CHECK(sizeof(::SIZE_T) == sizeof(size_t)); 23 | COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t)); 24 | COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t)); 25 | COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t)); 26 | 27 | #if !SANITIZER_MAC 28 | COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); 29 | #endif 30 | 31 | // The following are the cases when pread (and friends) is used instead of 32 | // pread64. In those cases we need OFF_T to match off_t. We don't care about the 33 | // rest (they depend on _FILE_OFFSET_BITS setting when building an application). 34 | # if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ 35 | _FILE_OFFSET_BITS != 64 36 | COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); 37 | # endif 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/tests/interception_linux_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- interception_linux_test.cpp ---------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // Tests for interception_linux.h. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | // Do not declare isdigit in ctype.h. 15 | #define __NO_CTYPE 16 | 17 | #include "interception/interception.h" 18 | 19 | #include "gtest/gtest.h" 20 | 21 | // Too slow for debug build 22 | #if !SANITIZER_DEBUG 23 | #if SANITIZER_LINUX 24 | 25 | static int InterceptorFunctionCalled; 26 | 27 | DECLARE_REAL(int, isdigit, int); 28 | 29 | INTERCEPTOR(int, isdigit, int d) { 30 | ++InterceptorFunctionCalled; 31 | return d >= '0' && d <= '9'; 32 | } 33 | 34 | namespace __interception { 35 | 36 | TEST(Interception, InterceptFunction) { 37 | uptr malloc_address = 0; 38 | EXPECT_TRUE(InterceptFunction("malloc", &malloc_address, 0, 0)); 39 | EXPECT_NE(0U, malloc_address); 40 | EXPECT_FALSE(InterceptFunction("malloc", &malloc_address, 0, 1)); 41 | 42 | uptr dummy_address = 0; 43 | EXPECT_FALSE(InterceptFunction("dummy_doesnt_exist__", &dummy_address, 0, 0)); 44 | EXPECT_EQ(0U, dummy_address); 45 | } 46 | 47 | TEST(Interception, Basic) { 48 | EXPECT_TRUE(INTERCEPT_FUNCTION(isdigit)); 49 | 50 | // After interception, the counter should be incremented. 51 | InterceptorFunctionCalled = 0; 52 | EXPECT_NE(0, isdigit('1')); 53 | EXPECT_EQ(1, InterceptorFunctionCalled); 54 | EXPECT_EQ(0, isdigit('a')); 55 | EXPECT_EQ(2, InterceptorFunctionCalled); 56 | 57 | // Calling the REAL function should not affect the counter. 58 | InterceptorFunctionCalled = 0; 59 | EXPECT_NE(0, REAL(isdigit)('1')); 60 | EXPECT_EQ(0, REAL(isdigit)('a')); 61 | EXPECT_EQ(0, InterceptorFunctionCalled); 62 | } 63 | 64 | } // namespace __interception 65 | 66 | #endif // SANITIZER_LINUX 67 | #endif // #if !SANITIZER_DEBUG 68 | -------------------------------------------------------------------------------- /src/dfsan_rt/interception/tests/interception_test_main.cpp: -------------------------------------------------------------------------------- 1 | //===-- interception_test_main.cpp ----------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of AddressSanitizer, an address sanity checker. 10 | // 11 | // Testing the machinery for providing replacements/wrappers for system 12 | // functions. 13 | //===----------------------------------------------------------------------===// 14 | 15 | #include "gtest/gtest.h" 16 | 17 | int main(int argc, char **argv) { 18 | testing::GTEST_FLAG(death_test_style) = "threadsafe"; 19 | testing::InitGoogleTest(&argc, argv); 20 | return RUN_ALL_TESTS(); 21 | } 22 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,readability-identifier-naming' 2 | CheckOptions: 3 | - key: readability-identifier-naming.ClassCase 4 | value: CamelCase 5 | - key: readability-identifier-naming.EnumCase 6 | value: CamelCase 7 | - key: readability-identifier-naming.FunctionCase 8 | value: CamelCase 9 | - key: readability-identifier-naming.UnionCase 10 | value: CamelCase 11 | - key: readability-identifier-naming.GlobalConstantCase 12 | value: CamelCase 13 | - key: readability-identifier-naming.GlobalConstantPrefix 14 | value: "k" 15 | - key: readability-identifier-naming.VariableCase 16 | value: lower_case 17 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sancov_flags.cpp: -------------------------------------------------------------------------------- 1 | //===-- sancov_flags.cpp ----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Sanitizer Coverage runtime flags. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sancov_flags.h" 14 | #include "sanitizer_flag_parser.h" 15 | #include "sanitizer_platform.h" 16 | 17 | SANITIZER_INTERFACE_WEAK_DEF(const char*, __sancov_default_options, void) { 18 | return ""; 19 | } 20 | 21 | using namespace __sanitizer; 22 | 23 | namespace __sancov { 24 | 25 | SancovFlags sancov_flags_dont_use_directly; // use via flags(); 26 | 27 | void SancovFlags::SetDefaults() { 28 | #define SANCOV_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 29 | #include "sancov_flags.inc" 30 | #undef SANCOV_FLAG 31 | } 32 | 33 | static void RegisterSancovFlags(FlagParser *parser, SancovFlags *f) { 34 | #define SANCOV_FLAG(Type, Name, DefaultValue, Description) \ 35 | RegisterFlag(parser, #Name, Description, &f->Name); 36 | #include "sancov_flags.inc" 37 | #undef SANCOV_FLAG 38 | } 39 | 40 | static const char *MaybeCallSancovDefaultOptions() { 41 | return (&__sancov_default_options) ? __sancov_default_options() : ""; 42 | } 43 | 44 | void InitializeSancovFlags() { 45 | SancovFlags *f = sancov_flags(); 46 | f->SetDefaults(); 47 | 48 | FlagParser parser; 49 | RegisterSancovFlags(&parser, f); 50 | 51 | parser.ParseString(MaybeCallSancovDefaultOptions()); 52 | parser.ParseStringFromEnv("SANCOV_OPTIONS"); 53 | 54 | ReportUnrecognizedFlags(); 55 | if (f->help) parser.PrintFlagDescriptions(); 56 | } 57 | 58 | } // namespace __sancov 59 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sancov_flags.h: -------------------------------------------------------------------------------- 1 | //===-- sancov_flags.h ------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Sanitizer Coverage runtime flags. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANCOV_FLAGS_H 13 | #define SANCOV_FLAGS_H 14 | 15 | #include "sanitizer_flag_parser.h" 16 | #include "sanitizer_internal_defs.h" 17 | 18 | namespace __sancov { 19 | 20 | struct SancovFlags { 21 | #define SANCOV_FLAG(Type, Name, DefaultValue, Description) Type Name; 22 | #include "sancov_flags.inc" 23 | #undef SANCOV_FLAG 24 | 25 | void SetDefaults(); 26 | }; 27 | 28 | extern SancovFlags sancov_flags_dont_use_directly; 29 | 30 | inline SancovFlags* sancov_flags() { return &sancov_flags_dont_use_directly; } 31 | 32 | void InitializeSancovFlags(); 33 | 34 | } // namespace __sancov 35 | 36 | extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* 37 | __sancov_default_options(); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sancov_flags.inc: -------------------------------------------------------------------------------- 1 | //===-- sancov_flags.inc ----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Sanitizer Coverage runtime flags. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANCOV_FLAG 13 | #error "Defnine SANCOV_FLAG prior to including this file!" 14 | #endif 15 | 16 | SANCOV_FLAG(bool, symbolize, true, 17 | "If set, converage information will be symbolized by sancov tool " 18 | "after dumping.") 19 | 20 | SANCOV_FLAG(bool, help, false, "Print flags help.") 21 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator.h -----------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Specialized memory allocator for ThreadSanitizer, MemorySanitizer, etc. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_ALLOCATOR_H 14 | #define SANITIZER_ALLOCATOR_H 15 | 16 | #include "sanitizer_common.h" 17 | #include "sanitizer_internal_defs.h" 18 | #include "sanitizer_lfstack.h" 19 | #include "sanitizer_libc.h" 20 | #include "sanitizer_list.h" 21 | #include "sanitizer_local_address_space_view.h" 22 | #include "sanitizer_mutex.h" 23 | #include "sanitizer_procmaps.h" 24 | #include "sanitizer_type_traits.h" 25 | 26 | namespace __sanitizer { 27 | 28 | // Allows the tools to name their allocations appropriately. 29 | extern const char *PrimaryAllocatorName; 30 | extern const char *SecondaryAllocatorName; 31 | 32 | // Since flags are immutable and allocator behavior can be changed at runtime 33 | // (unit tests or ASan on Android are some examples), allocator_may_return_null 34 | // flag value is cached here and can be altered later. 35 | bool AllocatorMayReturnNull(); 36 | void SetAllocatorMayReturnNull(bool may_return_null); 37 | 38 | // Returns true if allocator detected OOM condition. Can be used to avoid memory 39 | // hungry operations. 40 | bool IsAllocatorOutOfMemory(); 41 | // Should be called by a particular allocator when OOM is detected. 42 | void SetAllocatorOutOfMemory(); 43 | 44 | void PrintHintAllocatorCannotReturnNull(); 45 | 46 | // Allocators call these callbacks on mmap/munmap. 47 | struct NoOpMapUnmapCallback { 48 | void OnMap(uptr p, uptr size) const { } 49 | void OnUnmap(uptr p, uptr size) const { } 50 | }; 51 | 52 | // Callback type for iterating over chunks. 53 | typedef void (*ForEachChunkCallback)(uptr chunk, void *arg); 54 | 55 | INLINE u32 Rand(u32 *state) { // ANSI C linear congruential PRNG. 56 | return (*state = *state * 1103515245 + 12345) >> 16; 57 | } 58 | 59 | INLINE u32 RandN(u32 *state, u32 n) { return Rand(state) % n; } // [0, n) 60 | 61 | template 62 | INLINE void RandomShuffle(T *a, u32 n, u32 *rand_state) { 63 | if (n <= 1) return; 64 | u32 state = *rand_state; 65 | for (u32 i = n - 1; i > 0; i--) 66 | Swap(a[i], a[RandN(&state, i + 1)]); 67 | *rand_state = state; 68 | } 69 | 70 | #include "sanitizer_allocator_size_class_map.h" 71 | #include "sanitizer_allocator_stats.h" 72 | #include "sanitizer_allocator_primary64.h" 73 | #include "sanitizer_allocator_bytemap.h" 74 | #include "sanitizer_allocator_primary32.h" 75 | #include "sanitizer_allocator_local_cache.h" 76 | #include "sanitizer_allocator_secondary.h" 77 | #include "sanitizer_allocator_combined.h" 78 | 79 | } // namespace __sanitizer 80 | 81 | #endif // SANITIZER_ALLOCATOR_H 82 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator_checks.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator_checks.cpp --------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Various checks shared between ThreadSanitizer, MemorySanitizer, etc. memory 10 | // allocators. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "sanitizer_errno.h" 15 | 16 | namespace __sanitizer { 17 | 18 | void SetErrnoToENOMEM() { 19 | errno = errno_ENOMEM; 20 | } 21 | 22 | } // namespace __sanitizer 23 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator_checks.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator_checks.h ----------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Various checks shared between ThreadSanitizer, MemorySanitizer, etc. memory 10 | // allocators. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef SANITIZER_ALLOCATOR_CHECKS_H 15 | #define SANITIZER_ALLOCATOR_CHECKS_H 16 | 17 | #include "sanitizer_internal_defs.h" 18 | #include "sanitizer_common.h" 19 | #include "sanitizer_platform.h" 20 | 21 | namespace __sanitizer { 22 | 23 | // The following is defined in a separate compilation unit to avoid pulling in 24 | // sanitizer_errno.h in this header, which leads to conflicts when other system 25 | // headers include errno.h. This is usually the result of an unlikely event, 26 | // and as such we do not care as much about having it inlined. 27 | void SetErrnoToENOMEM(); 28 | 29 | // A common errno setting logic shared by almost all sanitizer allocator APIs. 30 | INLINE void *SetErrnoOnNull(void *ptr) { 31 | if (UNLIKELY(!ptr)) 32 | SetErrnoToENOMEM(); 33 | return ptr; 34 | } 35 | 36 | // In case of the check failure, the caller of the following Check... functions 37 | // should "return POLICY::OnBadRequest();" where POLICY is the current allocator 38 | // failure handling policy. 39 | 40 | // Checks aligned_alloc() parameters, verifies that the alignment is a power of 41 | // two and that the size is a multiple of alignment for POSIX implementation, 42 | // and a bit relaxed requirement for non-POSIX ones, that the size is a multiple 43 | // of alignment. 44 | INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) { 45 | #if SANITIZER_POSIX 46 | return alignment != 0 && IsPowerOfTwo(alignment) && 47 | (size & (alignment - 1)) == 0; 48 | #else 49 | return alignment != 0 && size % alignment == 0; 50 | #endif 51 | } 52 | 53 | // Checks posix_memalign() parameters, verifies that alignment is a power of two 54 | // and a multiple of sizeof(void *). 55 | INLINE bool CheckPosixMemalignAlignment(uptr alignment) { 56 | return alignment != 0 && IsPowerOfTwo(alignment) && 57 | (alignment % sizeof(void *)) == 0; 58 | } 59 | 60 | // Returns true if calloc(size, n) call overflows on size*n calculation. 61 | INLINE bool CheckForCallocOverflow(uptr size, uptr n) { 62 | if (!size) 63 | return false; 64 | uptr max = (uptr)-1L; 65 | return (max / size) < n; 66 | } 67 | 68 | // Returns true if the size passed to pvalloc overflows when rounded to the next 69 | // multiple of page_size. 70 | INLINE bool CheckForPvallocOverflow(uptr size, uptr page_size) { 71 | return RoundUpTo(size, page_size) < size; 72 | } 73 | 74 | } // namespace __sanitizer 75 | 76 | #endif // SANITIZER_ALLOCATOR_CHECKS_H 77 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator_interface.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator_interface.h ------------------------- C++ -----===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Re-declaration of functions from public sanitizer allocator interface. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_ALLOCATOR_INTERFACE_H 14 | #define SANITIZER_ALLOCATOR_INTERFACE_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | 18 | using __sanitizer::uptr; 19 | 20 | extern "C" { 21 | SANITIZER_INTERFACE_ATTRIBUTE 22 | uptr __sanitizer_get_estimated_allocated_size(uptr size); 23 | SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_get_ownership(const void *p); 24 | SANITIZER_INTERFACE_ATTRIBUTE uptr 25 | __sanitizer_get_allocated_size(const void *p); 26 | SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_current_allocated_bytes(); 27 | SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_heap_size(); 28 | SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_free_bytes(); 29 | SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_unmapped_bytes(); 30 | 31 | SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_install_malloc_and_free_hooks( 32 | void (*malloc_hook)(const void *, uptr), 33 | void (*free_hook)(const void *)); 34 | 35 | SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 36 | void __sanitizer_malloc_hook(void *ptr, uptr size); 37 | SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 38 | void __sanitizer_free_hook(void *ptr); 39 | 40 | SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void 41 | __sanitizer_purge_allocator(); 42 | 43 | SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void 44 | __sanitizer_print_memory_profile(uptr top_percent, uptr max_number_of_contexts); 45 | } // extern "C" 46 | 47 | #endif // SANITIZER_ALLOCATOR_INTERFACE_H 48 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator_internal.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator_internal.h --------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This allocator is used inside run-times. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_ALLOCATOR_INTERNAL_H 14 | #define SANITIZER_ALLOCATOR_INTERNAL_H 15 | 16 | #include "sanitizer_allocator.h" 17 | #include "sanitizer_internal_defs.h" 18 | 19 | namespace __sanitizer { 20 | 21 | // FIXME: Check if we may use even more compact size class map for internal 22 | // purposes. 23 | typedef CompactSizeClassMap InternalSizeClassMap; 24 | 25 | struct AP32 { 26 | static const uptr kSpaceBeg = 0; 27 | static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; 28 | static const uptr kMetadataSize = 0; 29 | typedef InternalSizeClassMap SizeClassMap; 30 | static const uptr kRegionSizeLog = 20; 31 | using AddressSpaceView = LocalAddressSpaceView; 32 | typedef NoOpMapUnmapCallback MapUnmapCallback; 33 | static const uptr kFlags = 0; 34 | }; 35 | typedef SizeClassAllocator32 PrimaryInternalAllocator; 36 | 37 | typedef CombinedAllocator 39 | InternalAllocator; 40 | typedef InternalAllocator::AllocatorCache InternalAllocatorCache; 41 | 42 | void *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr, 43 | uptr alignment = 0); 44 | void *InternalRealloc(void *p, uptr size, 45 | InternalAllocatorCache *cache = nullptr); 46 | void *InternalReallocArray(void *p, uptr count, uptr size, 47 | InternalAllocatorCache *cache = nullptr); 48 | void *InternalCalloc(uptr count, uptr size, 49 | InternalAllocatorCache *cache = nullptr); 50 | void InternalFree(void *p, InternalAllocatorCache *cache = nullptr); 51 | InternalAllocator *internal_allocator(); 52 | 53 | } // namespace __sanitizer 54 | 55 | #endif // SANITIZER_ALLOCATOR_INTERNAL_H 56 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_allocator_report.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_allocator_report.h ----------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | /// 9 | /// \file 10 | /// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc. 11 | /// 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef SANITIZER_ALLOCATOR_REPORT_H 15 | #define SANITIZER_ALLOCATOR_REPORT_H 16 | 17 | #include "sanitizer_internal_defs.h" 18 | #include "sanitizer_stacktrace.h" 19 | 20 | namespace __sanitizer { 21 | 22 | void NORETURN ReportCallocOverflow(uptr count, uptr size, 23 | const StackTrace *stack); 24 | void NORETURN ReportReallocArrayOverflow(uptr count, uptr size, 25 | const StackTrace *stack); 26 | void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack); 27 | void NORETURN ReportInvalidAllocationAlignment(uptr alignment, 28 | const StackTrace *stack); 29 | void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, 30 | const StackTrace *stack); 31 | void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment, 32 | const StackTrace *stack); 33 | void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size, 34 | const StackTrace *stack); 35 | void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack); 36 | 37 | } // namespace __sanitizer 38 | 39 | #endif // SANITIZER_ALLOCATOR_REPORT_H 40 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_asm.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Various support for assemebler. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | // Some toolchains do not support .cfi asm directives, so we have to hide 14 | // them inside macros. 15 | #if defined(__clang__) || \ 16 | (defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)) 17 | // GCC defined __GCC_HAVE_DWARF2_CFI_ASM if it supports CFI. 18 | // Clang seems to support CFI by default (or not?). 19 | // We need two versions of macros: for inline asm and standalone asm files. 20 | # define CFI_INL_ADJUST_CFA_OFFSET(n) ".cfi_adjust_cfa_offset " #n ";" 21 | 22 | # define CFI_STARTPROC .cfi_startproc 23 | # define CFI_ENDPROC .cfi_endproc 24 | # define CFI_ADJUST_CFA_OFFSET(n) .cfi_adjust_cfa_offset n 25 | # define CFI_DEF_CFA_OFFSET(n) .cfi_def_cfa_offset n 26 | # define CFI_REL_OFFSET(reg, n) .cfi_rel_offset reg, n 27 | # define CFI_OFFSET(reg, n) .cfi_offset reg, n 28 | # define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg 29 | # define CFI_DEF_CFA(reg, n) .cfi_def_cfa reg, n 30 | # define CFI_RESTORE(reg) .cfi_restore reg 31 | 32 | #else // No CFI 33 | # define CFI_INL_ADJUST_CFA_OFFSET(n) 34 | # define CFI_STARTPROC 35 | # define CFI_ENDPROC 36 | # define CFI_ADJUST_CFA_OFFSET(n) 37 | # define CFI_DEF_CFA_OFFSET(n) 38 | # define CFI_REL_OFFSET(reg, n) 39 | # define CFI_OFFSET(reg, n) 40 | # define CFI_DEF_CFA_REGISTER(reg) 41 | # define CFI_DEF_CFA(reg, n) 42 | # define CFI_RESTORE(reg) 43 | #endif 44 | 45 | #if !defined(__APPLE__) 46 | # define ASM_HIDDEN(symbol) .hidden symbol 47 | # define ASM_TYPE_FUNCTION(symbol) .type symbol, %function 48 | # define ASM_SIZE(symbol) .size symbol, .-symbol 49 | # define ASM_SYMBOL(symbol) symbol 50 | # define ASM_SYMBOL_INTERCEPTOR(symbol) symbol 51 | # define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol 52 | #else 53 | # define ASM_HIDDEN(symbol) 54 | # define ASM_TYPE_FUNCTION(symbol) 55 | # define ASM_SIZE(symbol) 56 | # define ASM_SYMBOL(symbol) _##symbol 57 | # define ASM_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol 58 | # define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol 59 | #endif 60 | 61 | #if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \ 62 | defined(__Fuchsia__) || defined(__linux__)) 63 | // clang-format off 64 | #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT 65 | // clang-format on 66 | #else 67 | #define NO_EXEC_STACK_DIRECTIVE 68 | #endif 69 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_atomic.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_atomic.h --------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_ATOMIC_H 14 | #define SANITIZER_ATOMIC_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | 18 | namespace __sanitizer { 19 | 20 | enum memory_order { 21 | memory_order_relaxed = 1 << 0, 22 | memory_order_consume = 1 << 1, 23 | memory_order_acquire = 1 << 2, 24 | memory_order_release = 1 << 3, 25 | memory_order_acq_rel = 1 << 4, 26 | memory_order_seq_cst = 1 << 5 27 | }; 28 | 29 | struct atomic_uint8_t { 30 | typedef u8 Type; 31 | volatile Type val_dont_use; 32 | }; 33 | 34 | struct atomic_uint16_t { 35 | typedef u16 Type; 36 | volatile Type val_dont_use; 37 | }; 38 | 39 | struct atomic_sint32_t { 40 | typedef s32 Type; 41 | volatile Type val_dont_use; 42 | }; 43 | 44 | struct atomic_uint32_t { 45 | typedef u32 Type; 46 | volatile Type val_dont_use; 47 | }; 48 | 49 | struct atomic_uint64_t { 50 | typedef u64 Type; 51 | // On 32-bit platforms u64 is not necessary aligned on 8 bytes. 52 | volatile ALIGNED(8) Type val_dont_use; 53 | }; 54 | 55 | struct atomic_uintptr_t { 56 | typedef uptr Type; 57 | volatile Type val_dont_use; 58 | }; 59 | 60 | } // namespace __sanitizer 61 | 62 | #if defined(__clang__) || defined(__GNUC__) 63 | # include "sanitizer_atomic_clang.h" 64 | #elif defined(_MSC_VER) 65 | # include "sanitizer_atomic_msvc.h" 66 | #else 67 | # error "Unsupported compiler" 68 | #endif 69 | 70 | namespace __sanitizer { 71 | 72 | // Clutter-reducing helpers. 73 | 74 | template 75 | INLINE typename T::Type atomic_load_relaxed(const volatile T *a) { 76 | return atomic_load(a, memory_order_relaxed); 77 | } 78 | 79 | template 80 | INLINE void atomic_store_relaxed(volatile T *a, typename T::Type v) { 81 | atomic_store(a, v, memory_order_relaxed); 82 | } 83 | 84 | } // namespace __sanitizer 85 | 86 | #endif // SANITIZER_ATOMIC_H 87 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S: -------------------------------------------------------------------------------- 1 | #if defined(__aarch64__) && defined(__linux__) 2 | 3 | #include "sanitizer_common/sanitizer_asm.h" 4 | 5 | ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 6 | 7 | .comm _ZN14__interception10real_vforkE,8,8 8 | .globl ASM_WRAPPER_NAME(vfork) 9 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 10 | ASM_WRAPPER_NAME(vfork): 11 | // Save x30 in the off-stack spill area. 12 | stp xzr, x30, [sp, #-16]! 13 | bl COMMON_INTERCEPTOR_SPILL_AREA 14 | ldp xzr, x30, [sp], 16 15 | str x30, [x0] 16 | 17 | // Call real vfork. This may return twice. User code that runs between the first and the second return 18 | // may clobber the stack frame of the interceptor; that's why it does not have a frame. 19 | adrp x0, _ZN14__interception10real_vforkE 20 | ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE] 21 | blr x0 22 | 23 | stp x0, xzr, [sp, #-16]! 24 | cmp x0, #0 25 | b.eq .L_exit 26 | 27 | // x0 != 0 => parent process. Clear stack shadow. 28 | add x0, sp, #16 29 | bl COMMON_INTERCEPTOR_HANDLE_VFORK 30 | 31 | .L_exit: 32 | // Restore x30. 33 | bl COMMON_INTERCEPTOR_SPILL_AREA 34 | ldr x30, [x0] 35 | ldp x0, xzr, [sp], 16 36 | 37 | ret 38 | ASM_SIZE(vfork) 39 | 40 | .weak vfork 41 | .set vfork, ASM_WRAPPER_NAME(vfork) 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S: -------------------------------------------------------------------------------- 1 | #if defined(__arm__) && defined(__linux__) 2 | 3 | #include "sanitizer_common/sanitizer_asm.h" 4 | 5 | ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 6 | 7 | .comm _ZN14__interception10real_vforkE,4,4 8 | .globl ASM_WRAPPER_NAME(vfork) 9 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 10 | ASM_WRAPPER_NAME(vfork): 11 | // Save LR in the off-stack spill area. 12 | push {r4, lr} 13 | bl COMMON_INTERCEPTOR_SPILL_AREA 14 | pop {r4, lr} 15 | str lr, [r0] 16 | 17 | // Call real vfork. This may return twice. User code that runs between the first and the second return 18 | // may clobber the stack frame of the interceptor; that's why it does not have a frame. 19 | ldr r0, .LCPI0_0 20 | .LPC0_0: 21 | ldr r0, [pc, r0] 22 | mov lr, pc 23 | bx r0 24 | 25 | push {r0, r4} 26 | cmp r0, #0 27 | beq .L_exit 28 | 29 | // r0 != 0 => parent process. Clear stack shadow. 30 | add r0, sp, #8 31 | bl COMMON_INTERCEPTOR_HANDLE_VFORK 32 | 33 | .L_exit: 34 | // Restore LR. 35 | bl COMMON_INTERCEPTOR_SPILL_AREA 36 | ldr lr, [r0] 37 | pop {r0, r4} 38 | 39 | mov pc, lr 40 | 41 | .LCPI0_0: 42 | .long _ZN14__interception10real_vforkE - (.LPC0_0+8) 43 | 44 | ASM_SIZE(vfork) 45 | 46 | .weak vfork 47 | .set vfork, ASM_WRAPPER_NAME(vfork) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S: -------------------------------------------------------------------------------- 1 | #if defined(__i386__) && defined(__linux__) 2 | 3 | #include "sanitizer_common/sanitizer_asm.h" 4 | 5 | .comm _ZN14__interception10real_vforkE,4,4 6 | .globl ASM_WRAPPER_NAME(vfork) 7 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 8 | ASM_WRAPPER_NAME(vfork): 9 | // Store return address in the spill area and tear down the stack frame. 10 | sub $12, %esp 11 | call COMMON_INTERCEPTOR_SPILL_AREA 12 | mov 12(%esp), %ecx 13 | mov %ecx, (%eax) 14 | add $16, %esp 15 | 16 | call .L0$pb 17 | .L0$pb: 18 | pop %eax 19 | .Ltmp0: 20 | add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax 21 | call *_ZN14__interception10real_vforkE@GOTOFF(%eax) 22 | 23 | // Restore the stack frame. 24 | // 12(%esp) return address 25 | // 8(%esp) spill %ebx 26 | // 4(%esp) spill REAL(vfork) return value 27 | // (%esp) call frame (arg0) for __*_handle_vfork 28 | sub $16, %esp 29 | mov %ebx, 8(%esp) 30 | mov %eax, 4(%esp) 31 | 32 | // Form GOT address in %ebx. 33 | call .L1$pb 34 | .L1$pb: 35 | pop %ebx 36 | .Ltmp1: 37 | add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx 38 | 39 | // Restore original return address. 40 | call COMMON_INTERCEPTOR_SPILL_AREA 41 | mov (%eax), %ecx 42 | mov %ecx, 12(%esp) 43 | mov 4(%esp), %eax 44 | 45 | // Call handle_vfork in the parent process (%rax != 0). 46 | test %eax, %eax 47 | je .L_exit 48 | 49 | lea 16(%esp), %ecx 50 | mov %ecx, (%esp) 51 | call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT 52 | 53 | .L_exit: 54 | mov 4(%esp), %eax 55 | mov 8(%esp), %ebx 56 | add $12, %esp 57 | ret 58 | ASM_SIZE(vfork) 59 | 60 | .weak vfork 61 | .set vfork, ASM_WRAPPER_NAME(vfork) 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S: -------------------------------------------------------------------------------- 1 | #if defined(__x86_64__) && defined(__linux__) 2 | 3 | #include "sanitizer_common/sanitizer_asm.h" 4 | 5 | .comm _ZN14__interception10real_vforkE,8,8 6 | .globl ASM_WRAPPER_NAME(vfork) 7 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 8 | ASM_WRAPPER_NAME(vfork): 9 | // Store return address in the spill area and tear down the stack frame. 10 | push %rcx 11 | call COMMON_INTERCEPTOR_SPILL_AREA 12 | pop %rcx 13 | pop %rdi 14 | mov %rdi, (%rax) 15 | 16 | call *_ZN14__interception10real_vforkE(%rip) 17 | 18 | // Restore return address from the spill area. 19 | push %rcx 20 | push %rax 21 | call COMMON_INTERCEPTOR_SPILL_AREA 22 | mov (%rax), %rdx 23 | mov %rdx, 8(%rsp) 24 | mov (%rsp), %rax 25 | 26 | // Call handle_vfork in the parent process (%rax != 0). 27 | test %rax, %rax 28 | je .L_exit 29 | 30 | lea 16(%rsp), %rdi 31 | call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT 32 | 33 | .L_exit: 34 | pop %rax 35 | ret 36 | ASM_SIZE(vfork) 37 | 38 | .weak vfork 39 | .set vfork, ASM_WRAPPER_NAME(vfork) 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interface.inc: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_common_interface.inc ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // Sanitizer Common interface list. 9 | //===----------------------------------------------------------------------===// 10 | INTERFACE_FUNCTION(__sanitizer_acquire_crash_state) 11 | INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container) 12 | INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address) 13 | INTERFACE_FUNCTION(__sanitizer_set_death_callback) 14 | INTERFACE_FUNCTION(__sanitizer_set_report_path) 15 | INTERFACE_FUNCTION(__sanitizer_set_report_fd) 16 | INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container) 17 | INTERFACE_WEAK_FUNCTION(__sanitizer_on_print) 18 | INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary) 19 | INTERFACE_WEAK_FUNCTION(__sanitizer_sandbox_on_notify) 20 | // Sanitizer weak hooks 21 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_memcmp) 22 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strcmp) 23 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strncmp) 24 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strstr) 25 | // Stacktrace interface. 26 | INTERFACE_FUNCTION(__sanitizer_get_module_and_offset_for_pc) 27 | INTERFACE_FUNCTION(__sanitizer_symbolize_global) 28 | INTERFACE_FUNCTION(__sanitizer_symbolize_pc) 29 | // Allocator interface. 30 | INTERFACE_FUNCTION(__sanitizer_get_allocated_size) 31 | INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes) 32 | INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size) 33 | INTERFACE_FUNCTION(__sanitizer_get_free_bytes) 34 | INTERFACE_FUNCTION(__sanitizer_get_heap_size) 35 | INTERFACE_FUNCTION(__sanitizer_get_ownership) 36 | INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes) 37 | INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks) 38 | INTERFACE_FUNCTION(__sanitizer_purge_allocator) 39 | INTERFACE_FUNCTION(__sanitizer_print_memory_profile) 40 | INTERFACE_WEAK_FUNCTION(__sanitizer_free_hook) 41 | INTERFACE_WEAK_FUNCTION(__sanitizer_malloc_hook) 42 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_interface_posix.inc: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_common_interface_posix.inc ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // Sanitizer Common interface list only available for Posix systems. 9 | //===----------------------------------------------------------------------===// 10 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_code) 11 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_data) 12 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_demangle) 13 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_flush) 14 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_common_nolibc.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_common_nolibc.cpp ---------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file contains stubs for libc function to facilitate optional use of 10 | // libc in no-libcdep sources. 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_platform.h" 14 | #include "sanitizer_common.h" 15 | #include "sanitizer_libc.h" 16 | 17 | namespace __sanitizer { 18 | 19 | // The Windows implementations of these functions use the win32 API directly, 20 | // bypassing libc. 21 | #if !SANITIZER_WINDOWS 22 | #if SANITIZER_LINUX 23 | void LogMessageOnPrintf(const char *str) {} 24 | #endif 25 | void WriteToSyslog(const char *buffer) {} 26 | void Abort() { internal__exit(1); } 27 | void SleepForSeconds(int seconds) { internal_sleep(seconds); } 28 | #endif // !SANITIZER_WINDOWS 29 | 30 | #if !SANITIZER_WINDOWS && !SANITIZER_MAC 31 | void ListOfModules::init() {} 32 | #endif 33 | 34 | } // namespace __sanitizer 35 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_coverage_interface.inc: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_coverage_interface.inc ----------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // Sanitizer Coverage interface list. 9 | //===----------------------------------------------------------------------===// 10 | INTERFACE_FUNCTION(__sanitizer_cov_dump) 11 | INTERFACE_FUNCTION(__sanitizer_cov_reset) 12 | INTERFACE_FUNCTION(__sanitizer_dump_coverage) 13 | INTERFACE_FUNCTION(__sanitizer_dump_trace_pc_guard_coverage) 14 | INTERFACE_WEAK_FUNCTION(__sancov_default_options) 15 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp) 16 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp1) 17 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp2) 18 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp4) 19 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_cmp8) 20 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_const_cmp1) 21 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_const_cmp2) 22 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_const_cmp4) 23 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_const_cmp8) 24 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_div4) 25 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_div8) 26 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_gep) 27 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_pc_guard) 28 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_pc_guard_init) 29 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_pc_indir) 30 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_trace_switch) 31 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_8bit_counters_init) 32 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_bool_flag_init) 33 | INTERFACE_WEAK_FUNCTION(__sanitizer_cov_pcs_init) 34 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_coverage_win_dll_thunk.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines a family of thunks that should be statically linked into 10 | // the DLLs that have instrumentation in order to delegate the calls to the 11 | // shared runtime that lives in the main binary. 12 | // See https://github.com/google/sanitizers/issues/209 for the details. 13 | //===----------------------------------------------------------------------===// 14 | #ifdef SANITIZER_DLL_THUNK 15 | #include "sanitizer_win_dll_thunk.h" 16 | // Sanitizer Coverage interface functions. 17 | #define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name) 18 | #define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) 19 | #include "sanitizer_coverage_interface.inc" 20 | #endif // SANITIZER_DLL_THUNK 21 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_coverage_win_dynamic_runtime_thunk.cpp ------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines things that need to be present in the application modules 10 | // to interact with Sanitizer Coverage, when it is included in a dll. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | #ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK 14 | #define SANITIZER_IMPORT_INTERFACE 1 15 | #include "sanitizer_win_defs.h" 16 | // Define weak alias for all weak functions imported from sanitizer coverage. 17 | #define INTERFACE_FUNCTION(Name) 18 | #define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name) 19 | #include "sanitizer_coverage_interface.inc" 20 | #endif // SANITIZER_DYNAMIC_RUNTIME_THUNK 21 | 22 | namespace __sanitizer { 23 | // Add one, otherwise unused, external symbol to this object file so that the 24 | // Visual C++ linker includes it and reads the .drective section. 25 | void ForceWholeArchiveIncludeForSanCov() {} 26 | } 27 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_coverage_win_weak_interception.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // This module should be included in Sanitizer Coverage when it implemented as a 9 | // shared library on Windows (dll), in order to delegate the calls of weak 10 | // functions to the implementation in the main executable when a strong 11 | // definition is provided. 12 | //===----------------------------------------------------------------------===// 13 | #ifdef SANITIZER_DYNAMIC 14 | #include "sanitizer_win_weak_interception.h" 15 | #include "sanitizer_interface_internal.h" 16 | #include "sancov_flags.h" 17 | // Check if strong definitions for weak functions are present in the main 18 | // executable. If that is the case, override dll functions to point to strong 19 | // implementations. 20 | #define INTERFACE_FUNCTION(Name) 21 | #define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) 22 | #include "sanitizer_coverage_interface.inc" 23 | #endif // SANITIZER_DYNAMIC 24 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_dbghelp.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_dbghelp.h ------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Wrappers for lazy loaded dbghelp.dll. Provides function pointers and a 10 | // callback to initialize them. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef SANITIZER_SYMBOLIZER_WIN_H 15 | #define SANITIZER_SYMBOLIZER_WIN_H 16 | 17 | #if !SANITIZER_WINDOWS 18 | #error "sanitizer_dbghelp.h is a Windows-only header" 19 | #endif 20 | 21 | #define WIN32_LEAN_AND_MEAN 22 | #include 23 | #include 24 | 25 | namespace __sanitizer { 26 | 27 | extern decltype(::StackWalk64) *StackWalk64; 28 | extern decltype(::SymCleanup) *SymCleanup; 29 | extern decltype(::SymFromAddr) *SymFromAddr; 30 | extern decltype(::SymFunctionTableAccess64) *SymFunctionTableAccess64; 31 | extern decltype(::SymGetLineFromAddr64) *SymGetLineFromAddr64; 32 | extern decltype(::SymGetModuleBase64) *SymGetModuleBase64; 33 | extern decltype(::SymGetSearchPathW) *SymGetSearchPathW; 34 | extern decltype(::SymInitialize) *SymInitialize; 35 | extern decltype(::SymSetOptions) *SymSetOptions; 36 | extern decltype(::SymSetSearchPathW) *SymSetSearchPathW; 37 | extern decltype(::UnDecorateSymbolName) *UnDecorateSymbolName; 38 | 39 | } // namespace __sanitizer 40 | 41 | #endif // SANITIZER_SYMBOLIZER_WIN_H 42 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_deadlock_detector_interface.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of Sanitizer runtime. 10 | // Abstract deadlock detector interface. 11 | // FIXME: this is work in progress, nothing really works yet. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 16 | #define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 17 | 18 | #ifndef SANITIZER_DEADLOCK_DETECTOR_VERSION 19 | # define SANITIZER_DEADLOCK_DETECTOR_VERSION 1 20 | #endif 21 | 22 | #include "sanitizer_internal_defs.h" 23 | #include "sanitizer_atomic.h" 24 | 25 | namespace __sanitizer { 26 | 27 | // dd - deadlock detector. 28 | // lt - logical (user) thread. 29 | // pt - physical (OS) thread. 30 | 31 | struct DDPhysicalThread; 32 | struct DDLogicalThread; 33 | 34 | struct DDMutex { 35 | #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1 36 | uptr id; 37 | u32 stk; // creation stack 38 | #elif SANITIZER_DEADLOCK_DETECTOR_VERSION == 2 39 | u32 id; 40 | u32 recursion; 41 | atomic_uintptr_t owner; 42 | #else 43 | # error "BAD SANITIZER_DEADLOCK_DETECTOR_VERSION" 44 | #endif 45 | u64 ctx; 46 | }; 47 | 48 | struct DDFlags { 49 | bool second_deadlock_stack; 50 | }; 51 | 52 | struct DDReport { 53 | enum { kMaxLoopSize = 20 }; 54 | int n; // number of entries in loop 55 | struct { 56 | u64 thr_ctx; // user thread context 57 | u64 mtx_ctx0; // user mutex context, start of the edge 58 | u64 mtx_ctx1; // user mutex context, end of the edge 59 | u32 stk[2]; // stack ids for the edge 60 | } loop[kMaxLoopSize]; 61 | }; 62 | 63 | struct DDCallback { 64 | DDPhysicalThread *pt; 65 | DDLogicalThread *lt; 66 | 67 | virtual u32 Unwind() { return 0; } 68 | virtual int UniqueTid() { return 0; } 69 | }; 70 | 71 | struct DDetector { 72 | static DDetector *Create(const DDFlags *flags); 73 | 74 | virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; } 75 | virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {} 76 | 77 | virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; } 78 | virtual void DestroyLogicalThread(DDLogicalThread *lt) {} 79 | 80 | virtual void MutexInit(DDCallback *cb, DDMutex *m) {} 81 | virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {} 82 | virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, 83 | bool trylock) {} 84 | virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {} 85 | virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {} 86 | 87 | virtual DDReport *GetReport(DDCallback *cb) { return nullptr; } 88 | }; 89 | 90 | } // namespace __sanitizer 91 | 92 | #endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 93 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_errno.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_errno.cpp -------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between sanitizers run-time libraries. 10 | // 11 | // Defines errno to avoid including errno.h and its dependencies into other 12 | // files (e.g. interceptors are not supposed to include any system headers). 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #include "sanitizer_errno_codes.h" 17 | #include "sanitizer_internal_defs.h" 18 | 19 | #include 20 | 21 | namespace __sanitizer { 22 | 23 | COMPILER_CHECK(errno_ENOMEM == ENOMEM); 24 | COMPILER_CHECK(errno_EBUSY == EBUSY); 25 | COMPILER_CHECK(errno_EINVAL == EINVAL); 26 | 27 | // EOWNERDEAD is not present in some older platforms. 28 | #if defined(EOWNERDEAD) 29 | extern const int errno_EOWNERDEAD = EOWNERDEAD; 30 | #else 31 | extern const int errno_EOWNERDEAD = -1; 32 | #endif 33 | 34 | } // namespace __sanitizer 35 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_errno.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_errno.h ---------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between sanitizers run-time libraries. 10 | // 11 | // Defines errno to avoid including errno.h and its dependencies into sensitive 12 | // files (e.g. interceptors are not supposed to include any system headers). 13 | // It's ok to use errno.h directly when your file already depend on other system 14 | // includes though. 15 | // 16 | //===----------------------------------------------------------------------===// 17 | 18 | #ifndef SANITIZER_ERRNO_H 19 | #define SANITIZER_ERRNO_H 20 | 21 | #include "sanitizer_errno_codes.h" 22 | #include "sanitizer_platform.h" 23 | 24 | #if SANITIZER_FREEBSD || SANITIZER_MAC 25 | # define __errno_location __error 26 | #elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD || \ 27 | SANITIZER_RTEMS 28 | # define __errno_location __errno 29 | #elif SANITIZER_SOLARIS 30 | # define __errno_location ___errno 31 | #elif SANITIZER_WINDOWS 32 | # define __errno_location _errno 33 | #endif 34 | 35 | extern "C" int *__errno_location(); 36 | 37 | #define errno (*__errno_location()) 38 | 39 | #endif // SANITIZER_ERRNO_H 40 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_errno_codes.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_errno_codes.h ---------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between sanitizers run-time libraries. 10 | // 11 | // Defines errno codes to avoid including errno.h and its dependencies into 12 | // sensitive files (e.g. interceptors are not supposed to include any system 13 | // headers). 14 | // It's ok to use errno.h directly when your file already depend on other system 15 | // includes though. 16 | // 17 | //===----------------------------------------------------------------------===// 18 | 19 | #ifndef SANITIZER_ERRNO_CODES_H 20 | #define SANITIZER_ERRNO_CODES_H 21 | 22 | namespace __sanitizer { 23 | 24 | #define errno_ENOMEM 12 25 | #define errno_EBUSY 16 26 | #define errno_EINVAL 22 27 | 28 | // Those might not present or their value differ on different platforms. 29 | extern const int errno_EOWNERDEAD; 30 | 31 | } // namespace __sanitizer 32 | 33 | #endif // SANITIZER_ERRNO_CODES_H 34 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_flags.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_FLAGS_H 14 | #define SANITIZER_FLAGS_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | 18 | namespace __sanitizer { 19 | 20 | enum HandleSignalMode { 21 | kHandleSignalNo, 22 | kHandleSignalYes, 23 | kHandleSignalExclusive, 24 | }; 25 | 26 | struct CommonFlags { 27 | #define COMMON_FLAG(Type, Name, DefaultValue, Description) Type Name; 28 | #include "sanitizer_flags.inc" 29 | #undef COMMON_FLAG 30 | 31 | void SetDefaults(); 32 | void CopyFrom(const CommonFlags &other); 33 | }; 34 | 35 | // Functions to get/set global CommonFlags shared by all sanitizer runtimes: 36 | extern CommonFlags common_flags_dont_use; 37 | inline const CommonFlags *common_flags() { 38 | return &common_flags_dont_use; 39 | } 40 | 41 | inline void SetCommonFlagsDefaults() { 42 | common_flags_dont_use.SetDefaults(); 43 | } 44 | 45 | // This function can only be used to setup tool-specific overrides for 46 | // CommonFlags defaults. Generally, it should only be used right after 47 | // SetCommonFlagsDefaults(), but before ParseCommonFlagsFromString(), and 48 | // only during the flags initialization (i.e. before they are used for 49 | // the first time). 50 | inline void OverrideCommonFlags(const CommonFlags &cf) { 51 | common_flags_dont_use.CopyFrom(cf); 52 | } 53 | 54 | void SubstituteForFlagValue(const char *s, char *out, uptr out_size); 55 | 56 | class FlagParser; 57 | void RegisterCommonFlags(FlagParser *parser, 58 | CommonFlags *cf = &common_flags_dont_use); 59 | void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf); 60 | 61 | // Should be called after parsing all flags. Sets up common flag values 62 | // and perform initializations common to all sanitizers (e.g. setting 63 | // verbosity). 64 | void InitializeCommonFlags(CommonFlags *cf = &common_flags_dont_use); 65 | } // namespace __sanitizer 66 | 67 | #endif // SANITIZER_FLAGS_H 68 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_fuchsia.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_fuchsia.h ------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===---------------------------------------------------------------------===// 8 | // 9 | // Fuchsia-specific sanitizer support. 10 | // 11 | //===---------------------------------------------------------------------===// 12 | #ifndef SANITIZER_FUCHSIA_H 13 | #define SANITIZER_FUCHSIA_H 14 | 15 | #include "sanitizer_platform.h" 16 | #if SANITIZER_FUCHSIA 17 | 18 | #include "sanitizer_common.h" 19 | 20 | #include 21 | #include 22 | 23 | namespace __sanitizer { 24 | 25 | extern uptr MainThreadStackBase, MainThreadStackSize; 26 | extern sanitizer_shadow_bounds_t ShadowBounds; 27 | 28 | struct MemoryMappingLayoutData { 29 | InternalMmapVector data; 30 | size_t current; // Current index into the vector. 31 | }; 32 | 33 | } // namespace __sanitizer 34 | 35 | #endif // SANITIZER_FUCHSIA 36 | #endif // SANITIZER_FUCHSIA_H 37 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_getauxval.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_getauxval.h -----------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Common getauxval() guards and definitions. 10 | // getauxval() is not defined until glibc version 2.16, or until API level 21 11 | // for Android. 12 | // Implement the getauxval() compat function for NetBSD. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef SANITIZER_GETAUXVAL_H 17 | #define SANITIZER_GETAUXVAL_H 18 | 19 | #include "sanitizer_platform.h" 20 | #include "sanitizer_glibc_version.h" 21 | 22 | #if SANITIZER_LINUX || SANITIZER_FUCHSIA 23 | 24 | # if __GLIBC_PREREQ(2, 16) || (SANITIZER_ANDROID && __ANDROID_API__ >= 21) || \ 25 | SANITIZER_FUCHSIA 26 | # define SANITIZER_USE_GETAUXVAL 1 27 | # else 28 | # define SANITIZER_USE_GETAUXVAL 0 29 | # endif 30 | 31 | # if SANITIZER_USE_GETAUXVAL 32 | # include 33 | # else 34 | // The weak getauxval definition allows to check for the function at runtime. 35 | // This is useful for Android, when compiled at a lower API level yet running 36 | // on a more recent platform that offers the function. 37 | extern "C" SANITIZER_WEAK_ATTRIBUTE unsigned long getauxval(unsigned long type); 38 | # endif 39 | 40 | #elif SANITIZER_NETBSD 41 | 42 | #define SANITIZER_USE_GETAUXVAL 1 43 | 44 | #include 45 | #include 46 | 47 | static inline decltype(AuxInfo::a_v) getauxval(decltype(AuxInfo::a_type) type) { 48 | for (const AuxInfo *aux = (const AuxInfo *)_dlauxinfo(); 49 | aux->a_type != AT_NULL; ++aux) { 50 | if (type == aux->a_type) 51 | return aux->a_v; 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | #endif 58 | 59 | #endif // SANITIZER_GETAUXVAL_H 60 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_glibc_version.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_glibc_version.h -----------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of Sanitizer common code. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_GLIBC_VERSION_H 14 | #define SANITIZER_GLIBC_VERSION_H 15 | 16 | #include "sanitizer_platform.h" 17 | 18 | #if SANITIZER_LINUX || SANITIZER_FUCHSIA 19 | #include 20 | #endif 21 | 22 | #ifndef __GLIBC_PREREQ 23 | #define __GLIBC_PREREQ(x, y) 0 24 | #endif 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_hash.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_common.h --------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file implements a simple hash function. 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef SANITIZER_HASH_H 13 | #define SANITIZER_HASH_H 14 | 15 | #include "sanitizer_internal_defs.h" 16 | 17 | namespace __sanitizer { 18 | class MurMur2HashBuilder { 19 | static const u32 m = 0x5bd1e995; 20 | static const u32 seed = 0x9747b28c; 21 | static const u32 r = 24; 22 | u32 h; 23 | 24 | public: 25 | explicit MurMur2HashBuilder(u32 init = 0) { h = seed ^ init; } 26 | void add(u32 k) { 27 | k *= m; 28 | k ^= k >> r; 29 | k *= m; 30 | h *= m; 31 | h ^= k; 32 | } 33 | u32 get() { 34 | u32 x = h; 35 | x ^= x >> 13; 36 | x *= m; 37 | x ^= x >> 15; 38 | return x; 39 | } 40 | }; 41 | } //namespace __sanitizer 42 | 43 | #endif // SANITIZER_HASH_H 44 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_lfstack.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_lfstack.h -=-----------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Lock-free stack. 10 | // Uses 32/17 bits as ABA-counter on 32/64-bit platforms. 11 | // The memory passed to Push() must not be ever munmap'ed. 12 | // The type T must contain T *next field. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef SANITIZER_LFSTACK_H 17 | #define SANITIZER_LFSTACK_H 18 | 19 | #include "sanitizer_internal_defs.h" 20 | #include "sanitizer_common.h" 21 | #include "sanitizer_atomic.h" 22 | 23 | namespace __sanitizer { 24 | 25 | template 26 | struct LFStack { 27 | void Clear() { 28 | atomic_store(&head_, 0, memory_order_relaxed); 29 | } 30 | 31 | bool Empty() const { 32 | return (atomic_load(&head_, memory_order_relaxed) & kPtrMask) == 0; 33 | } 34 | 35 | void Push(T *p) { 36 | u64 cmp = atomic_load(&head_, memory_order_relaxed); 37 | for (;;) { 38 | u64 cnt = (cmp & kCounterMask) + kCounterInc; 39 | u64 xch = (u64)(uptr)p | cnt; 40 | p->next = (T*)(uptr)(cmp & kPtrMask); 41 | if (atomic_compare_exchange_weak(&head_, &cmp, xch, 42 | memory_order_release)) 43 | break; 44 | } 45 | } 46 | 47 | T *Pop() { 48 | u64 cmp = atomic_load(&head_, memory_order_acquire); 49 | for (;;) { 50 | T *cur = (T*)(uptr)(cmp & kPtrMask); 51 | if (!cur) 52 | return nullptr; 53 | T *nxt = cur->next; 54 | u64 cnt = (cmp & kCounterMask); 55 | u64 xch = (u64)(uptr)nxt | cnt; 56 | if (atomic_compare_exchange_weak(&head_, &cmp, xch, 57 | memory_order_acquire)) 58 | return cur; 59 | } 60 | } 61 | 62 | // private: 63 | static const int kCounterBits = FIRST_32_SECOND_64(32, 17); 64 | static const u64 kPtrMask = ((u64)-1) >> kCounterBits; 65 | static const u64 kCounterMask = ~kPtrMask; 66 | static const u64 kCounterInc = kPtrMask + 1; 67 | 68 | atomic_uint64_t head_; 69 | }; 70 | } // namespace __sanitizer 71 | 72 | #endif // SANITIZER_LFSTACK_H 73 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_mac.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_mac.h -----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries and 10 | // provides definitions for OSX-specific functions. 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANITIZER_MAC_H 13 | #define SANITIZER_MAC_H 14 | 15 | #include "sanitizer_common.h" 16 | #include "sanitizer_platform.h" 17 | #if SANITIZER_MAC 18 | #include "sanitizer_posix.h" 19 | 20 | namespace __sanitizer { 21 | 22 | struct MemoryMappingLayoutData { 23 | int current_image; 24 | u32 current_magic; 25 | u32 current_filetype; 26 | ModuleArch current_arch; 27 | u8 current_uuid[kModuleUUIDSize]; 28 | int current_load_cmd_count; 29 | const char *current_load_cmd_addr; 30 | bool current_instrumented; 31 | }; 32 | 33 | template 34 | struct VersionBase { 35 | u16 major; 36 | u16 minor; 37 | 38 | VersionBase(u16 major, u16 minor) : major(major), minor(minor) {} 39 | 40 | bool operator==(const VersionType &other) const { 41 | return major == other.major && minor == other.minor; 42 | } 43 | bool operator>=(const VersionType &other) const { 44 | return major > other.major || 45 | (major == other.major && minor >= other.minor); 46 | } 47 | }; 48 | 49 | struct MacosVersion : VersionBase { 50 | MacosVersion(u16 major, u16 minor) : VersionBase(major, minor) {} 51 | }; 52 | 53 | struct DarwinKernelVersion : VersionBase { 54 | DarwinKernelVersion(u16 major, u16 minor) : VersionBase(major, minor) {} 55 | }; 56 | 57 | MacosVersion GetMacosAlignedVersion(); 58 | DarwinKernelVersion GetDarwinKernelVersion(); 59 | 60 | char **GetEnviron(); 61 | 62 | void RestrictMemoryToMaxAddress(uptr max_address); 63 | 64 | } // namespace __sanitizer 65 | 66 | extern "C" { 67 | static char __crashreporter_info_buff__[__sanitizer::kErrorMessageBufferSize] = 68 | {}; 69 | static const char *__crashreporter_info__ __attribute__((__used__)) = 70 | &__crashreporter_info_buff__[0]; 71 | asm(".desc ___crashreporter_info__, 0x10"); 72 | } // extern "C" 73 | 74 | namespace __sanitizer { 75 | static BlockingMutex crashreporter_info_mutex(LINKER_INITIALIZED); 76 | 77 | INLINE void CRAppendCrashLogMessage(const char *msg) { 78 | BlockingMutexLock l(&crashreporter_info_mutex); 79 | internal_strlcat(__crashreporter_info_buff__, msg, 80 | sizeof(__crashreporter_info_buff__)); } 81 | } // namespace __sanitizer 82 | 83 | #endif // SANITIZER_MAC 84 | #endif // SANITIZER_MAC_H 85 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_mac_libcdep.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_mac_libcdep.cpp -----------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries and 10 | // implements OSX-specific functions. 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_platform.h" 14 | #if SANITIZER_MAC 15 | #include "sanitizer_mac.h" 16 | 17 | #include 18 | 19 | namespace __sanitizer { 20 | 21 | void RestrictMemoryToMaxAddress(uptr max_address) { 22 | uptr size_to_mmap = GetMaxUserVirtualAddress() + 1 - max_address; 23 | void *res = MmapFixedNoAccess(max_address, size_to_mmap, "high gap"); 24 | CHECK(res != MAP_FAILED); 25 | } 26 | 27 | } // namespace __sanitizer 28 | 29 | #endif // SANITIZER_MAC 30 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_persistent_allocator.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_persistent_allocator.cpp ----------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between AddressSanitizer and ThreadSanitizer 10 | // run-time libraries. 11 | //===----------------------------------------------------------------------===// 12 | #include "sanitizer_persistent_allocator.h" 13 | 14 | namespace __sanitizer { 15 | 16 | PersistentAllocator thePersistentAllocator; 17 | 18 | } // namespace __sanitizer 19 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_persistent_allocator.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // A fast memory allocator that does not support free() nor realloc(). 10 | // All allocations are forever. 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_PERSISTENT_ALLOCATOR_H 14 | #define SANITIZER_PERSISTENT_ALLOCATOR_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | #include "sanitizer_mutex.h" 18 | #include "sanitizer_atomic.h" 19 | #include "sanitizer_common.h" 20 | 21 | namespace __sanitizer { 22 | 23 | class PersistentAllocator { 24 | public: 25 | void *alloc(uptr size); 26 | 27 | private: 28 | void *tryAlloc(uptr size); 29 | StaticSpinMutex mtx; // Protects alloc of new blocks for region allocator. 30 | atomic_uintptr_t region_pos; // Region allocator for Node's. 31 | atomic_uintptr_t region_end; 32 | }; 33 | 34 | inline void *PersistentAllocator::tryAlloc(uptr size) { 35 | // Optimisic lock-free allocation, essentially try to bump the region ptr. 36 | for (;;) { 37 | uptr cmp = atomic_load(®ion_pos, memory_order_acquire); 38 | uptr end = atomic_load(®ion_end, memory_order_acquire); 39 | if (cmp == 0 || cmp + size > end) return nullptr; 40 | if (atomic_compare_exchange_weak(®ion_pos, &cmp, cmp + size, 41 | memory_order_acquire)) 42 | return (void *)cmp; 43 | } 44 | } 45 | 46 | inline void *PersistentAllocator::alloc(uptr size) { 47 | // First, try to allocate optimisitically. 48 | void *s = tryAlloc(size); 49 | if (s) return s; 50 | // If failed, lock, retry and alloc new superblock. 51 | SpinMutexLock l(&mtx); 52 | for (;;) { 53 | s = tryAlloc(size); 54 | if (s) return s; 55 | atomic_store(®ion_pos, 0, memory_order_relaxed); 56 | uptr allocsz = 64 * 1024; 57 | if (allocsz < size) allocsz = size; 58 | uptr mem = (uptr)MmapOrDie(allocsz, "stack depot"); 59 | atomic_store(®ion_end, mem + allocsz, memory_order_release); 60 | atomic_store(®ion_pos, mem, memory_order_release); 61 | } 62 | } 63 | 64 | extern PersistentAllocator thePersistentAllocator; 65 | inline void *PersistentAlloc(uptr sz) { 66 | return thePersistentAllocator.alloc(sz); 67 | } 68 | 69 | } // namespace __sanitizer 70 | 71 | #endif // SANITIZER_PERSISTENT_ALLOCATOR_H 72 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_placement_new.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_placement_new.h -------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between AddressSanitizer and ThreadSanitizer 10 | // run-time libraries. 11 | // 12 | // The file provides 'placement new'. 13 | // Do not include it into header files, only into source files. 14 | //===----------------------------------------------------------------------===// 15 | #ifndef SANITIZER_PLACEMENT_NEW_H 16 | #define SANITIZER_PLACEMENT_NEW_H 17 | 18 | #include "sanitizer_internal_defs.h" 19 | 20 | inline void *operator new(__sanitizer::operator_new_size_type sz, void *p) { 21 | return p; 22 | } 23 | 24 | #endif // SANITIZER_PLACEMENT_NEW_H 25 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_procmaps_fuchsia.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_procmaps_fuchsia.cpp 2 | //----------------------------------------===// 3 | // 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 | // See https://llvm.org/LICENSE.txt for license information. 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // Information about the process mappings (Fuchsia-specific parts). 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_platform.h" 14 | #if SANITIZER_FUCHSIA 15 | #include 16 | #include 17 | 18 | #include "sanitizer_common.h" 19 | #include "sanitizer_procmaps.h" 20 | 21 | namespace __sanitizer { 22 | 23 | // The cache flag is ignored on Fuchsia because a process can always get this 24 | // information via its process-self handle. 25 | MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); } 26 | 27 | void MemoryMappingLayout::Reset() { 28 | data_.data.clear(); 29 | data_.current = 0; 30 | 31 | size_t count; 32 | zx_status_t status = _zx_object_get_info( 33 | _zx_process_self(), ZX_INFO_PROCESS_MAPS, nullptr, 0, nullptr, &count); 34 | if (status != ZX_OK) { 35 | return; 36 | } 37 | 38 | size_t filled; 39 | do { 40 | data_.data.resize(count); 41 | status = _zx_object_get_info( 42 | _zx_process_self(), ZX_INFO_PROCESS_MAPS, data_.data.data(), 43 | count * sizeof(zx_info_maps_t), &filled, &count); 44 | if (status != ZX_OK) { 45 | data_.data.clear(); 46 | return; 47 | } 48 | } while (filled < count); 49 | } 50 | 51 | MemoryMappingLayout::~MemoryMappingLayout() {} 52 | 53 | bool MemoryMappingLayout::Error() const { return data_.data.empty(); } 54 | 55 | bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { 56 | while (data_.current < data_.data.size()) { 57 | const auto &entry = data_.data[data_.current++]; 58 | if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) { 59 | segment->start = entry.base; 60 | segment->end = entry.base + entry.size; 61 | segment->offset = entry.u.mapping.vmo_offset; 62 | const auto flags = entry.u.mapping.mmu_flags; 63 | segment->protection = 64 | ((flags & ZX_VM_PERM_READ) ? kProtectionRead : 0) | 65 | ((flags & ZX_VM_PERM_WRITE) ? kProtectionWrite : 0) | 66 | ((flags & ZX_VM_PERM_EXECUTE) ? kProtectionExecute : 0); 67 | if (segment->filename && segment->filename_size > 0) { 68 | uptr len = Min(sizeof(entry.name), segment->filename_size) - 1; 69 | internal_strncpy(segment->filename, entry.name, len); 70 | segment->filename[len] = 0; 71 | } 72 | return true; 73 | } 74 | } 75 | return false; 76 | } 77 | 78 | } // namespace __sanitizer 79 | 80 | #endif // SANITIZER_FUCHSIA 81 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_procmaps_solaris.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_procmaps_solaris.cpp ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Information about the process mappings (Solaris-specific parts). 10 | //===----------------------------------------------------------------------===// 11 | 12 | #include "sanitizer_platform.h" 13 | #if SANITIZER_SOLARIS 14 | #include "sanitizer_common.h" 15 | #include "sanitizer_procmaps.h" 16 | 17 | // Before Solaris 11.4, doesn't work in a largefile environment. 18 | #undef _FILE_OFFSET_BITS 19 | #include 20 | #include 21 | 22 | namespace __sanitizer { 23 | 24 | void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { 25 | if (!ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, 26 | &proc_maps->mmaped_size, &proc_maps->len)) { 27 | proc_maps->data = nullptr; 28 | proc_maps->mmaped_size = 0; 29 | proc_maps->len = 0; 30 | } 31 | } 32 | 33 | bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { 34 | if (Error()) return false; // simulate empty maps 35 | char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; 36 | if (data_.current >= last) return false; 37 | 38 | prxmap_t *xmapentry = (prxmap_t*)data_.current; 39 | 40 | segment->start = (uptr)xmapentry->pr_vaddr; 41 | segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size); 42 | segment->offset = (uptr)xmapentry->pr_offset; 43 | 44 | segment->protection = 0; 45 | if ((xmapentry->pr_mflags & MA_READ) != 0) 46 | segment->protection |= kProtectionRead; 47 | if ((xmapentry->pr_mflags & MA_WRITE) != 0) 48 | segment->protection |= kProtectionWrite; 49 | if ((xmapentry->pr_mflags & MA_EXEC) != 0) 50 | segment->protection |= kProtectionExecute; 51 | 52 | if (segment->filename != NULL && segment->filename_size > 0) { 53 | char proc_path[PATH_MAX + 1]; 54 | 55 | internal_snprintf(proc_path, sizeof(proc_path), "/proc/self/path/%s", 56 | xmapentry->pr_mapname); 57 | internal_readlink(proc_path, segment->filename, segment->filename_size); 58 | } 59 | 60 | data_.current += sizeof(prxmap_t); 61 | 62 | return true; 63 | } 64 | 65 | } // namespace __sanitizer 66 | 67 | #endif // SANITIZER_SOLARIS 68 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_ptrauth.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_ptrauth.h -------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef SANITIZER_PTRAUTH_H 10 | #define SANITIZER_PTRAUTH_H 11 | 12 | #if __has_feature(ptrauth_calls) 13 | #include 14 | #else 15 | // Copied from 16 | #define ptrauth_strip(__value, __key) __value 17 | #define ptrauth_auth_data(__value, __old_key, __old_data) __value 18 | #define ptrauth_string_discriminator(__string) ((int)0) 19 | #endif 20 | 21 | #endif // SANITIZER_PTRAUTH_H 22 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_report_decorator.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_report_decorator.h ----------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Tags to decorate the sanitizer reports. 10 | // Currently supported tags: 11 | // * None. 12 | // * ANSI color sequences. 13 | // 14 | //===----------------------------------------------------------------------===// 15 | 16 | #ifndef SANITIZER_REPORT_DECORATOR_H 17 | #define SANITIZER_REPORT_DECORATOR_H 18 | 19 | #include "sanitizer_common.h" 20 | 21 | namespace __sanitizer { 22 | class SanitizerCommonDecorator { 23 | // FIXME: This is not portable. It assumes the special strings are printed to 24 | // stdout, which is not the case on Windows (see SetConsoleTextAttribute()). 25 | public: 26 | SanitizerCommonDecorator() : ansi_(ColorizeReports()) {} 27 | const char *Bold() const { return ansi_ ? "\033[1m" : ""; } 28 | const char *Default() const { return ansi_ ? "\033[1m\033[0m" : ""; } 29 | const char *Warning() const { return Red(); } 30 | const char *Error() const { return Red(); } 31 | const char *MemoryByte() const { return Magenta(); } 32 | 33 | protected: 34 | const char *Black() const { return ansi_ ? "\033[1m\033[30m" : ""; } 35 | const char *Red() const { return ansi_ ? "\033[1m\033[31m" : ""; } 36 | const char *Green() const { return ansi_ ? "\033[1m\033[32m" : ""; } 37 | const char *Yellow() const { return ansi_ ? "\033[1m\033[33m" : ""; } 38 | const char *Blue() const { return ansi_ ? "\033[1m\033[34m" : ""; } 39 | const char *Magenta() const { return ansi_ ? "\033[1m\033[35m" : ""; } 40 | const char *Cyan() const { return ansi_ ? "\033[1m\033[36m" : ""; } 41 | const char *White() const { return ansi_ ? "\033[1m\033[37m" : ""; } 42 | private: 43 | bool ansi_; 44 | }; 45 | 46 | } // namespace __sanitizer 47 | 48 | #endif // SANITIZER_REPORT_DECORATOR_H 49 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_rtems.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries and 10 | // provides definitions for RTEMS-specific functions. 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANITIZER_RTEMS_H 13 | #define SANITIZER_RTEMS_H 14 | 15 | #include "sanitizer_platform.h" 16 | #if SANITIZER_RTEMS 17 | #include "sanitizer_common.h" 18 | 19 | #endif // SANITIZER_RTEMS 20 | #endif // SANITIZER_RTEMS_H 21 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_stackdepot.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_stackdepot.h ----------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between AddressSanitizer and ThreadSanitizer 10 | // run-time libraries. 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef SANITIZER_STACKDEPOT_H 14 | #define SANITIZER_STACKDEPOT_H 15 | 16 | #include "sanitizer_common.h" 17 | #include "sanitizer_internal_defs.h" 18 | #include "sanitizer_stacktrace.h" 19 | 20 | namespace __sanitizer { 21 | 22 | // StackDepot efficiently stores huge amounts of stack traces. 23 | struct StackDepotNode; 24 | struct StackDepotHandle { 25 | StackDepotNode *node_; 26 | StackDepotHandle() : node_(nullptr) {} 27 | explicit StackDepotHandle(StackDepotNode *node) : node_(node) {} 28 | bool valid() { return node_; } 29 | u32 id(); 30 | int use_count(); 31 | void inc_use_count_unsafe(); 32 | }; 33 | 34 | const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20); 35 | 36 | StackDepotStats *StackDepotGetStats(); 37 | u32 StackDepotPut(StackTrace stack); 38 | StackDepotHandle StackDepotPut_WithHandle(StackTrace stack); 39 | // Retrieves a stored stack trace by the id. 40 | StackTrace StackDepotGet(u32 id); 41 | 42 | void StackDepotLockAll(); 43 | void StackDepotUnlockAll(); 44 | 45 | // Instantiating this class creates a snapshot of StackDepot which can be 46 | // efficiently queried with StackDepotGet(). You can use it concurrently with 47 | // StackDepot, but the snapshot is only guaranteed to contain those stack traces 48 | // which were stored before it was instantiated. 49 | class StackDepotReverseMap { 50 | public: 51 | StackDepotReverseMap(); 52 | StackTrace Get(u32 id); 53 | 54 | private: 55 | struct IdDescPair { 56 | u32 id; 57 | StackDepotNode *desc; 58 | 59 | static bool IdComparator(const IdDescPair &a, const IdDescPair &b); 60 | }; 61 | 62 | InternalMmapVector map_; 63 | 64 | // Disallow evil constructors. 65 | StackDepotReverseMap(const StackDepotReverseMap&); 66 | void operator=(const StackDepotReverseMap&); 67 | }; 68 | 69 | } // namespace __sanitizer 70 | 71 | #endif // SANITIZER_STACKDEPOT_H 72 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_stoptheworld.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Defines the StopTheWorld function which suspends the execution of the current 10 | // process and runs the user-supplied callback in the same address space. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | #ifndef SANITIZER_STOPTHEWORLD_H 14 | #define SANITIZER_STOPTHEWORLD_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | #include "sanitizer_common.h" 18 | 19 | namespace __sanitizer { 20 | 21 | enum PtraceRegistersStatus { 22 | REGISTERS_UNAVAILABLE_FATAL = -1, 23 | REGISTERS_UNAVAILABLE = 0, 24 | REGISTERS_AVAILABLE = 1 25 | }; 26 | 27 | // Holds the list of suspended threads and provides an interface to dump their 28 | // register contexts. 29 | class SuspendedThreadsList { 30 | public: 31 | SuspendedThreadsList() = default; 32 | 33 | // Can't declare pure virtual functions in sanitizer runtimes: 34 | // __cxa_pure_virtual might be unavailable. Use UNIMPLEMENTED() instead. 35 | virtual PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer, 36 | uptr *sp) const { 37 | UNIMPLEMENTED(); 38 | } 39 | 40 | // The buffer in GetRegistersAndSP should be at least this big. 41 | virtual uptr RegisterCount() const { UNIMPLEMENTED(); } 42 | virtual uptr ThreadCount() const { UNIMPLEMENTED(); } 43 | virtual tid_t GetThreadID(uptr index) const { UNIMPLEMENTED(); } 44 | 45 | private: 46 | // Prohibit copy and assign. 47 | SuspendedThreadsList(const SuspendedThreadsList&); 48 | void operator=(const SuspendedThreadsList&); 49 | }; 50 | 51 | typedef void (*StopTheWorldCallback)( 52 | const SuspendedThreadsList &suspended_threads_list, 53 | void *argument); 54 | 55 | // Suspend all threads in the current process and run the callback on the list 56 | // of suspended threads. This function will resume the threads before returning. 57 | // The callback should not call any libc functions. The callback must not call 58 | // exit() nor _exit() and instead return to the caller. 59 | // This function should NOT be called from multiple threads simultaneously. 60 | void StopTheWorld(StopTheWorldCallback callback, void *argument); 61 | 62 | } // namespace __sanitizer 63 | 64 | #endif // SANITIZER_STOPTHEWORLD_H 65 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_stoptheworld_fuchsia.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_stoptheworld_fuchsia.cpp -------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===---------------------------------------------------------------------===// 8 | // 9 | // See sanitizer_stoptheworld.h for details. 10 | // 11 | //===---------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_platform.h" 14 | 15 | #if SANITIZER_FUCHSIA 16 | 17 | #include 18 | 19 | #include "sanitizer_stoptheworld.h" 20 | 21 | namespace __sanitizer { 22 | 23 | // The Fuchsia implementation stops the world but doesn't offer a real 24 | // SuspendedThreadsList argument. This is enough for ASan's use case, 25 | // and LSan does not use this API on Fuchsia. 26 | void StopTheWorld(StopTheWorldCallback callback, void *argument) { 27 | struct Params { 28 | StopTheWorldCallback callback; 29 | void *argument; 30 | } params = {callback, argument}; 31 | __sanitizer_memory_snapshot( 32 | nullptr, nullptr, nullptr, nullptr, 33 | [](zx_status_t, void *data) { 34 | auto params = reinterpret_cast(data); 35 | params->callback({}, params->argument); 36 | }, 37 | ¶ms); 38 | } 39 | 40 | } // namespace __sanitizer 41 | 42 | #endif // SANITIZER_FUCHSIA 43 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_suppressions.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_suppressions.h --------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Suppression parsing/matching code. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANITIZER_SUPPRESSIONS_H 13 | #define SANITIZER_SUPPRESSIONS_H 14 | 15 | #include "sanitizer_common.h" 16 | #include "sanitizer_atomic.h" 17 | #include "sanitizer_internal_defs.h" 18 | 19 | namespace __sanitizer { 20 | 21 | struct Suppression { 22 | Suppression() { internal_memset(this, 0, sizeof(*this)); } 23 | const char *type; 24 | char *templ; 25 | atomic_uint32_t hit_count; 26 | uptr weight; 27 | }; 28 | 29 | class SuppressionContext { 30 | public: 31 | // Create new SuppressionContext capable of parsing given suppression types. 32 | SuppressionContext(const char *supprression_types[], 33 | int suppression_types_num); 34 | 35 | void ParseFromFile(const char *filename); 36 | void Parse(const char *str); 37 | 38 | bool Match(const char *str, const char *type, Suppression **s); 39 | uptr SuppressionCount() const; 40 | bool HasSuppressionType(const char *type) const; 41 | const Suppression *SuppressionAt(uptr i) const; 42 | void GetMatched(InternalMmapVector *matched); 43 | 44 | private: 45 | static const int kMaxSuppressionTypes = 64; 46 | const char **const suppression_types_; 47 | const int suppression_types_num_; 48 | 49 | InternalMmapVector suppressions_; 50 | bool has_suppression_type_[kMaxSuppressionTypes]; 51 | bool can_parse_; 52 | }; 53 | 54 | } // namespace __sanitizer 55 | 56 | #endif // SANITIZER_SUPPRESSIONS_H 57 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_symbolizer_fuchsia.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_symbolizer_fuchsia.h -----------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries. 10 | // 11 | // Define Fuchsia's string formats and limits for the markup symbolizer. 12 | //===----------------------------------------------------------------------===// 13 | #ifndef SANITIZER_SYMBOLIZER_FUCHSIA_H 14 | #define SANITIZER_SYMBOLIZER_FUCHSIA_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | 18 | namespace __sanitizer { 19 | 20 | // See the spec at: 21 | // https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md 22 | 23 | // This is used by UBSan for type names, and by ASan for global variable names. 24 | constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; 25 | constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. 26 | 27 | // Function name or equivalent from PC location. 28 | constexpr const char *kFormatFunction = "{{{pc:%p}}}"; 29 | constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. 30 | 31 | // Global variable name or equivalent from data memory address. 32 | constexpr const char *kFormatData = "{{{data:%p}}}"; 33 | 34 | // One frame in a backtrace (printed on a line by itself). 35 | constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}"; 36 | 37 | // Dump trigger element. 38 | #define FORMAT_DUMPFILE "{{{dumpfile:%s:%s}}}" 39 | 40 | } // namespace __sanitizer 41 | 42 | #endif // SANITIZER_SYMBOLIZER_FUCHSIA_H 43 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_symbolizer_libbacktrace.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_symbolizer_libbacktrace.h ---------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between AddressSanitizer and ThreadSanitizer 10 | // run-time libraries. 11 | // Header for libbacktrace symbolizer. 12 | //===----------------------------------------------------------------------===// 13 | #ifndef SANITIZER_SYMBOLIZER_LIBBACKTRACE_H 14 | #define SANITIZER_SYMBOLIZER_LIBBACKTRACE_H 15 | 16 | #include "sanitizer_platform.h" 17 | #include "sanitizer_common.h" 18 | #include "sanitizer_allocator_internal.h" 19 | #include "sanitizer_symbolizer_internal.h" 20 | 21 | #ifndef SANITIZER_LIBBACKTRACE 22 | # define SANITIZER_LIBBACKTRACE 0 23 | #endif 24 | 25 | #ifndef SANITIZER_CP_DEMANGLE 26 | # define SANITIZER_CP_DEMANGLE 0 27 | #endif 28 | 29 | namespace __sanitizer { 30 | 31 | class LibbacktraceSymbolizer : public SymbolizerTool { 32 | public: 33 | static LibbacktraceSymbolizer *get(LowLevelAllocator *alloc); 34 | 35 | bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; 36 | 37 | bool SymbolizeData(uptr addr, DataInfo *info) override; 38 | 39 | // May return NULL if demangling failed. 40 | const char *Demangle(const char *name) override; 41 | 42 | private: 43 | explicit LibbacktraceSymbolizer(void *state) : state_(state) {} 44 | 45 | void *state_; // Leaked. 46 | }; 47 | 48 | } // namespace __sanitizer 49 | #endif // SANITIZER_SYMBOLIZER_LIBBACKTRACE_H 50 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_symbolizer_mac.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_symbolizer_mac.h ------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries. 10 | // 11 | // Header for Mac-specific "atos" symbolizer. 12 | //===----------------------------------------------------------------------===// 13 | 14 | #ifndef SANITIZER_SYMBOLIZER_MAC_H 15 | #define SANITIZER_SYMBOLIZER_MAC_H 16 | 17 | #include "sanitizer_platform.h" 18 | #if SANITIZER_MAC 19 | 20 | #include "sanitizer_symbolizer_internal.h" 21 | 22 | namespace __sanitizer { 23 | 24 | class DlAddrSymbolizer : public SymbolizerTool { 25 | public: 26 | bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; 27 | bool SymbolizeData(uptr addr, DataInfo *info) override; 28 | }; 29 | 30 | class AtosSymbolizerProcess; 31 | 32 | class AtosSymbolizer : public SymbolizerTool { 33 | public: 34 | explicit AtosSymbolizer(const char *path, LowLevelAllocator *allocator); 35 | 36 | bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; 37 | bool SymbolizeData(uptr addr, DataInfo *info) override; 38 | void LateInitialize() override; 39 | 40 | private: 41 | AtosSymbolizerProcess *process_; 42 | }; 43 | 44 | } // namespace __sanitizer 45 | 46 | #endif // SANITIZER_MAC 47 | 48 | #endif // SANITIZER_SYMBOLIZER_MAC_H 49 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_symbolizer_rtems.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_symbolizer_rtems.h -----------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is shared between various sanitizers' runtime libraries. 10 | // 11 | // Define RTEMS's string formats and limits for the markup symbolizer. 12 | //===----------------------------------------------------------------------===// 13 | #ifndef SANITIZER_SYMBOLIZER_RTEMS_H 14 | #define SANITIZER_SYMBOLIZER_RTEMS_H 15 | 16 | #include "sanitizer_internal_defs.h" 17 | 18 | namespace __sanitizer { 19 | 20 | // The Myriad RTEMS symbolizer currently only parses backtrace lines, 21 | // so use a format that the symbolizer understands. For other 22 | // markups, keep them the same as the Fuchsia's. 23 | 24 | // This is used by UBSan for type names, and by ASan for global variable names. 25 | constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; 26 | constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. 27 | 28 | // Function name or equivalent from PC location. 29 | constexpr const char *kFormatFunction = "{{{pc:%p}}}"; 30 | constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. 31 | 32 | // Global variable name or equivalent from data memory address. 33 | constexpr const char *kFormatData = "{{{data:%p}}}"; 34 | 35 | // One frame in a backtrace (printed on a line by itself). 36 | constexpr const char *kFormatFrame = " [%u] IP: %p"; 37 | 38 | } // namespace __sanitizer 39 | 40 | #endif // SANITIZER_SYMBOLIZER_RTEMS_H 41 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_syscall_generic.inc: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_syscall_generic.inc ---------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Generic implementations of internal_syscall* and internal_iserror. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | // NetBSD uses libc calls directly 14 | #if !SANITIZER_NETBSD 15 | 16 | #if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_SOLARIS 17 | # define SYSCALL(name) SYS_ ## name 18 | #else 19 | # define SYSCALL(name) __NR_ ## name 20 | #endif 21 | 22 | #if defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_MAC) 23 | # define internal_syscall __syscall 24 | # else 25 | # define internal_syscall syscall 26 | #endif 27 | 28 | #endif 29 | 30 | bool internal_iserror(uptr retval, int *rverrno) { 31 | if (retval == (uptr)-1) { 32 | if (rverrno) 33 | *rverrno = errno; 34 | return true; 35 | } else { 36 | return false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_tls_get_addr.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Handle the __tls_get_addr call. 10 | // 11 | // All this magic is specific to glibc and is required to workaround 12 | // the lack of interface that would tell us about the Dynamic TLS (DTLS). 13 | // https://sourceware.org/bugzilla/show_bug.cgi?id=16291 14 | // 15 | // The matters get worse because the glibc implementation changed between 16 | // 2.18 and 2.19: 17 | // https://groups.google.com/forum/#!topic/address-sanitizer/BfwYD8HMxTM 18 | // 19 | // Before 2.19, every DTLS chunk is allocated with __libc_memalign, 20 | // which we intercept and thus know where is the DTLS. 21 | // Since 2.19, DTLS chunks are allocated with __signal_safe_memalign, 22 | // which is an internal function that wraps a mmap call, neither of which 23 | // we can intercept. Luckily, __signal_safe_memalign has a simple parseable 24 | // header which we can use. 25 | // 26 | //===----------------------------------------------------------------------===// 27 | 28 | #ifndef SANITIZER_TLS_GET_ADDR_H 29 | #define SANITIZER_TLS_GET_ADDR_H 30 | 31 | #include "sanitizer_common.h" 32 | 33 | namespace __sanitizer { 34 | 35 | struct DTLS { 36 | // Array of DTLS chunks for the current Thread. 37 | // If beg == 0, the chunk is unused. 38 | struct DTV { 39 | uptr beg, size; 40 | }; 41 | 42 | uptr dtv_size; 43 | DTV *dtv; // dtv_size elements, allocated by MmapOrDie. 44 | 45 | // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cpp 46 | uptr last_memalign_size; 47 | uptr last_memalign_ptr; 48 | }; 49 | 50 | // Returns pointer and size of a linker-allocated TLS block. 51 | // Each block is returned exactly once. 52 | DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, uptr static_tls_begin, 53 | uptr static_tls_end); 54 | void DTLS_on_libc_memalign(void *ptr, uptr size); 55 | DTLS *DTLS_Get(); 56 | void DTLS_Destroy(); // Make sure to call this before the thread is destroyed. 57 | // Returns true if DTLS of suspended thread is in destruction process. 58 | bool DTLSInDestruction(DTLS *dtls); 59 | 60 | } // namespace __sanitizer 61 | 62 | #endif // SANITIZER_TLS_GET_ADDR_H 63 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_type_traits.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_type_traits.cpp -------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Implements a subset of C++ type traits. This is so we can avoid depending 10 | // on system C++ headers. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | #include "sanitizer_type_traits.h" 14 | 15 | namespace __sanitizer { 16 | 17 | const bool true_type::value; 18 | const bool false_type::value; 19 | 20 | } // namespace __sanitizer 21 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_type_traits.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_type_traits.h ---------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Implements a subset of C++ type traits. This is so we can avoid depending 10 | // on system C++ headers. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | #ifndef SANITIZER_TYPE_TRAITS_H 14 | #define SANITIZER_TYPE_TRAITS_H 15 | 16 | namespace __sanitizer { 17 | 18 | struct true_type { 19 | static const bool value = true; 20 | }; 21 | 22 | struct false_type { 23 | static const bool value = false; 24 | }; 25 | 26 | // is_same 27 | // 28 | // Type trait to compare if types are the same. 29 | // E.g. 30 | // 31 | // ``` 32 | // is_same::value - True 33 | // is_same::value - False 34 | // ``` 35 | template 36 | struct is_same : public false_type {}; 37 | 38 | template 39 | struct is_same : public true_type {}; 40 | 41 | // conditional 42 | // 43 | // Defines type as T if B is true or as F otherwise. 44 | // E.g. the following is true 45 | // 46 | // ``` 47 | // is_same::type>::value 48 | // is_same::type>::value 49 | // ``` 50 | template 51 | struct conditional { 52 | using type = T; 53 | }; 54 | 55 | template 56 | struct conditional { 57 | using type = F; 58 | }; 59 | 60 | } // namespace __sanitizer 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_unwind_win.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_unwind_win.cpp ------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | /// Sanitizer unwind Windows specific functions. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_platform.h" 14 | #if SANITIZER_WINDOWS 15 | 16 | #define WIN32_LEAN_AND_MEAN 17 | #define NOGDI 18 | #include 19 | 20 | #include "sanitizer_dbghelp.h" // for StackWalk64 21 | #include "sanitizer_stacktrace.h" 22 | #include "sanitizer_symbolizer.h" // for InitializeDbgHelpIfNeeded 23 | 24 | using namespace __sanitizer; 25 | 26 | #if !SANITIZER_GO 27 | void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { 28 | CHECK_GE(max_depth, 2); 29 | // FIXME: CaptureStackBackTrace might be too slow for us. 30 | // FIXME: Compare with StackWalk64. 31 | // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc 32 | size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax), 33 | (void **)&trace_buffer[0], 0); 34 | if (size == 0) 35 | return; 36 | 37 | // Skip the RTL frames by searching for the PC in the stacktrace. 38 | uptr pc_location = LocatePcInTrace(pc); 39 | PopStackFrames(pc_location); 40 | } 41 | 42 | void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { 43 | CHECK(context); 44 | CHECK_GE(max_depth, 2); 45 | CONTEXT ctx = *(CONTEXT *)context; 46 | STACKFRAME64 stack_frame; 47 | memset(&stack_frame, 0, sizeof(stack_frame)); 48 | 49 | InitializeDbgHelpIfNeeded(); 50 | 51 | size = 0; 52 | #if defined(_WIN64) 53 | int machine_type = IMAGE_FILE_MACHINE_AMD64; 54 | stack_frame.AddrPC.Offset = ctx.Rip; 55 | stack_frame.AddrFrame.Offset = ctx.Rbp; 56 | stack_frame.AddrStack.Offset = ctx.Rsp; 57 | #else 58 | int machine_type = IMAGE_FILE_MACHINE_I386; 59 | stack_frame.AddrPC.Offset = ctx.Eip; 60 | stack_frame.AddrFrame.Offset = ctx.Ebp; 61 | stack_frame.AddrStack.Offset = ctx.Esp; 62 | #endif 63 | stack_frame.AddrPC.Mode = AddrModeFlat; 64 | stack_frame.AddrFrame.Mode = AddrModeFlat; 65 | stack_frame.AddrStack.Mode = AddrModeFlat; 66 | while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(), 67 | &stack_frame, &ctx, NULL, SymFunctionTableAccess64, 68 | SymGetModuleBase64, NULL) && 69 | size < Min(max_depth, kStackTraceMax)) { 70 | trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset; 71 | } 72 | } 73 | #endif // #if !SANITIZER_GO 74 | 75 | #endif // SANITIZER_WINDOWS 76 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_win.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_win.h -----------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Windows-specific declarations. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #ifndef SANITIZER_WIN_H 13 | #define SANITIZER_WIN_H 14 | 15 | #include "sanitizer_platform.h" 16 | #if SANITIZER_WINDOWS 17 | #include "sanitizer_internal_defs.h" 18 | 19 | namespace __sanitizer { 20 | // Check based on flags if we should handle the exception. 21 | bool IsHandledDeadlyException(DWORD exceptionCode); 22 | } // namespace __sanitizer 23 | 24 | #endif // SANITIZER_WINDOWS 25 | #endif // SANITIZER_WIN_H 26 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp: -------------------------------------------------------------------------------- 1 | //===-- santizer_win_dynamic_runtime_thunk.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file defines things that need to be present in the application modules 10 | // to interact with Sanitizer Common, when it is included in a dll. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | #ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK 14 | #define SANITIZER_IMPORT_INTERFACE 1 15 | #include "sanitizer_win_defs.h" 16 | // Define weak alias for all weak functions imported from sanitizer common. 17 | #define INTERFACE_FUNCTION(Name) 18 | #define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name) 19 | #include "sanitizer_common_interface.inc" 20 | #endif // SANITIZER_DYNAMIC_RUNTIME_THUNK 21 | 22 | namespace __sanitizer { 23 | // Add one, otherwise unused, external symbol to this object file so that the 24 | // Visual C++ linker includes it and reads the .drective section. 25 | void ForceWholeArchiveIncludeForSanitizerCommon() {} 26 | } 27 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/sanitizer_win_weak_interception.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_win_weak_interception.h ---------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // This header provide helper macros to delegate calls of weak functions to the 9 | // implementation in the main executable when a strong definition is present. 10 | //===----------------------------------------------------------------------===// 11 | #ifndef SANITIZER_WIN_WEAK_INTERCEPTION_H 12 | #define SANITIZER_WIN_WEAK_INTERCEPTION_H 13 | #include "sanitizer_internal_defs.h" 14 | 15 | namespace __sanitizer { 16 | int interceptWhenPossible(uptr dll_function, const char *real_function); 17 | } 18 | 19 | // ----------------- Function interception helper macros -------------------- // 20 | // Weak functions, could be redefined in the main executable, but that is not 21 | // necessary, so we shouldn't die if we can not find a reference. 22 | #define INTERCEPT_WEAK(Name) interceptWhenPossible((uptr) Name, #Name); 23 | 24 | #define INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) \ 25 | static int intercept_##Name() { \ 26 | return __sanitizer::interceptWhenPossible((__sanitizer::uptr) Name, #Name);\ 27 | } \ 28 | __pragma(section(".WEAK$M", long, read)) \ 29 | __declspec(allocate(".WEAK$M")) int (*__weak_intercept_##Name)() = \ 30 | intercept_##Name; 31 | 32 | #endif // SANITIZER_WIN_WEAK_INTERCEPTION_H 33 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/scripts/litlint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # litlint 4 | # 5 | # Ensure RUN commands in lit tests are free of common errors. 6 | # 7 | # If any errors are detected, litlint returns a nonzero exit code. 8 | # 9 | 10 | import optparse 11 | import re 12 | import sys 13 | 14 | # Compile regex once for all files 15 | runRegex = re.compile(r'(? 0: 72 | sys.exit(1) 73 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/scripts/litlint_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Tests for litlint.py 4 | # 5 | # Usage: python litlint_test.py 6 | # 7 | # Returns nonzero if any test fails 8 | 9 | import litlint 10 | import unittest 11 | 12 | class TestLintLine(unittest.TestCase): 13 | def test_missing_run(self): 14 | f = litlint.LintLine 15 | self.assertEqual(f(' %t '), ('missing %run before %t', 2)) 16 | self.assertEqual(f(' %t\n'), ('missing %run before %t', 2)) 17 | self.assertEqual(f(' %t.so '), (None, None)) 18 | self.assertEqual(f(' %t.o '), (None, None)) 19 | self.assertEqual(f('%run %t '), (None, None)) 20 | self.assertEqual(f('-o %t '), (None, None)) 21 | 22 | if __name__ == '__main__': 23 | unittest.main() 24 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/symbolizer/scripts/ar_to_bc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function usage() { 4 | echo "Usage: $0 INPUT... OUTPUT" 5 | exit 1 6 | } 7 | 8 | if [ "$#" -le 1 ]; then 9 | usage 10 | fi 11 | 12 | [[ $AR == /* ]] || AR=$PWD/$AR 13 | [[ $LINK == /* ]] || LINK=$PWD/$LINK 14 | 15 | INPUTS= 16 | OUTPUT= 17 | for ARG in $@; do 18 | INPUTS="$INPUTS $OUTPUT" 19 | OUTPUT=$(readlink -f $ARG) 20 | done 21 | 22 | echo Inputs: $INPUTS 23 | echo Output: $OUTPUT 24 | 25 | SCRATCH_DIR=$(mktemp -d) 26 | ln -s $INPUTS $SCRATCH_DIR/ 27 | 28 | pushd $SCRATCH_DIR 29 | 30 | for INPUT in *; do 31 | for OBJ in $($AR t $INPUT); do 32 | $AR x $INPUT $OBJ 33 | mv -f $OBJ $(basename $INPUT).$OBJ 34 | done 35 | done 36 | 37 | $LINK *.o -o $OUTPUT 38 | 39 | rm -rf $SCRATCH_DIR 40 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/malloc_stress_transfer_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const size_t kAllocSize = 16; 4 | const size_t kInitialNumAllocs = 1 << 10; 5 | const size_t kPeriodicNumAllocs = 1 << 10; 6 | const size_t kNumIterations = 1 << 7; 7 | const size_t kNumThreads = 16; 8 | 9 | void Thread() { 10 | char *InitialAllocations[kInitialNumAllocs]; 11 | char *PeriodicaAllocations[kPeriodicNumAllocs]; 12 | for (auto &p : InitialAllocations) p = new char[kAllocSize]; 13 | for (size_t i = 0; i < kNumIterations; i++) { 14 | for (size_t j = 0; j < kPeriodicNumAllocs; j++) { 15 | for (auto &p : PeriodicaAllocations) { 16 | p = new char[kAllocSize]; 17 | *p = 0; 18 | } 19 | for (auto p : PeriodicaAllocations) delete [] p; 20 | } 21 | } 22 | for (auto p : InitialAllocations) delete [] p; 23 | } 24 | 25 | int main() { 26 | std::thread *Threads[kNumThreads]; 27 | for (auto &T : Threads) T = new std::thread(&Thread); 28 | for (auto T : Threads) { 29 | T->join(); 30 | delete T; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_mac_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_mac_test.cpp --------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Tests for sanitizer_mac.{h,cpp} 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_common/sanitizer_platform.h" 14 | #if SANITIZER_MAC 15 | 16 | #include "sanitizer_common/sanitizer_mac.h" 17 | 18 | #include "gtest/gtest.h" 19 | 20 | #include // sysctlbyname 21 | #include // KERN_SUCCESS 22 | 23 | namespace __sanitizer { 24 | 25 | TEST(SanitizerMac, GetMacosAlignedVersion) { 26 | MacosVersion vers = GetMacosAlignedVersion(); 27 | u16 kernel_major = GetDarwinKernelVersion().major; 28 | bool macos_11 = (kernel_major >= 20); 29 | u16 expected_major = macos_11 ? (kernel_major - 9) : 10; 30 | u16 expected_minor = macos_11 ? 0 : (kernel_major - 4); 31 | EXPECT_EQ(vers.major, expected_major); 32 | EXPECT_EQ(vers.minor, expected_minor); 33 | } 34 | 35 | void ParseVersion(const char *vers, u16 *major, u16 *minor); 36 | 37 | TEST(SanitizerMac, ParseVersion) { 38 | u16 major, minor; 39 | ParseVersion("11.22.33", &major, &minor); 40 | EXPECT_EQ(major, 11); 41 | EXPECT_EQ(minor, 22); 42 | } 43 | 44 | TEST(SanitizerMac, GetDarwinKernelVersion) { 45 | DarwinKernelVersion vers = GetDarwinKernelVersion(); 46 | std::ostringstream oss; 47 | oss << vers.major << '.' << vers.minor; 48 | std::string actual = oss.str(); 49 | 50 | char buf[100]; 51 | size_t len = sizeof(buf); 52 | int res = sysctlbyname("kern.osrelease", buf, &len, nullptr, 0); 53 | ASSERT_EQ(res, KERN_SUCCESS); 54 | std::string expected(buf); 55 | 56 | // Prefix match 57 | ASSERT_EQ(expected.compare(0, actual.size(), actual), 0); 58 | } 59 | 60 | } // namespace __sanitizer 61 | 62 | #endif // SANITIZER_MAC 63 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_nolibc_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_nolibc_test.cpp -----------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // Tests for libc independence of sanitizer_common. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "sanitizer_common/sanitizer_platform.h" 15 | 16 | #include "gtest/gtest.h" 17 | 18 | #include 19 | 20 | extern const char *argv0; 21 | 22 | #if SANITIZER_LINUX && defined(__x86_64__) 23 | TEST(SanitizerCommon, NolibcMain) { 24 | std::string NolibcTestPath = argv0; 25 | NolibcTestPath += "-Nolibc"; 26 | int status = system(NolibcTestPath.c_str()); 27 | EXPECT_EQ(true, WIFEXITED(status)); 28 | EXPECT_EQ(0, WEXITSTATUS(status)); 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_nolibc_test_main.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_nolibc_test_main.cpp ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // Tests for libc independence of sanitizer_common. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | #include "sanitizer_common/sanitizer_libc.h" 15 | 16 | extern "C" void _start() { 17 | __sanitizer::internal__exit(0); 18 | } 19 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_procmaps_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_procmaps_test.cpp ---------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #if !defined(_WIN32) // There are no /proc/maps on Windows. 13 | 14 | #include "sanitizer_common/sanitizer_procmaps.h" 15 | #include "gtest/gtest.h" 16 | 17 | #include 18 | 19 | static void noop() {} 20 | extern const char *argv0; 21 | 22 | namespace __sanitizer { 23 | 24 | #if SANITIZER_LINUX && !SANITIZER_ANDROID 25 | TEST(MemoryMappingLayout, CodeRange) { 26 | uptr start, end; 27 | bool res = GetCodeRangeForFile("[vdso]", &start, &end); 28 | EXPECT_EQ(res, true); 29 | EXPECT_GT(start, 0U); 30 | EXPECT_LT(start, end); 31 | } 32 | #endif 33 | 34 | TEST(MemoryMappingLayout, DumpListOfModules) { 35 | const char *last_slash = strrchr(argv0, '/'); 36 | const char *binary_name = last_slash ? last_slash + 1 : argv0; 37 | MemoryMappingLayout memory_mapping(false); 38 | const uptr kMaxModules = 100; 39 | InternalMmapVector modules; 40 | modules.reserve(kMaxModules); 41 | memory_mapping.DumpListOfModules(&modules); 42 | EXPECT_GT(modules.size(), 0U); 43 | bool found = false; 44 | for (uptr i = 0; i < modules.size(); ++i) { 45 | if (modules[i].containsAddress((uptr)&noop)) { 46 | // Verify that the module name is sane. 47 | if (strstr(modules[i].full_name(), binary_name) != 0) 48 | found = true; 49 | } 50 | modules[i].clear(); 51 | } 52 | EXPECT_TRUE(found); 53 | } 54 | 55 | TEST(MemoryMapping, LoadedModuleArchAndUUID) { 56 | if (SANITIZER_MAC) { 57 | MemoryMappingLayout memory_mapping(false); 58 | const uptr kMaxModules = 100; 59 | InternalMmapVector modules; 60 | modules.reserve(kMaxModules); 61 | memory_mapping.DumpListOfModules(&modules); 62 | for (uptr i = 0; i < modules.size(); ++i) { 63 | ModuleArch arch = modules[i].arch(); 64 | // Darwin unit tests are only run on i386/x86_64/x86_64h. 65 | if (SANITIZER_WORDSIZE == 32) { 66 | EXPECT_EQ(arch, kModuleArchI386); 67 | } else if (SANITIZER_WORDSIZE == 64) { 68 | EXPECT_TRUE(arch == kModuleArchX86_64 || arch == kModuleArchX86_64H); 69 | } 70 | const u8 *uuid = modules[i].uuid(); 71 | u8 null_uuid[kModuleUUIDSize] = {0}; 72 | EXPECT_NE(memcmp(null_uuid, uuid, kModuleUUIDSize), 0); 73 | } 74 | } 75 | } 76 | 77 | } // namespace __sanitizer 78 | #endif // !defined(_WIN32) 79 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_pthread_wrappers.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of *Sanitizer runtime. 10 | // It provides handy wrappers for thread manipulation, that: 11 | // a) assert on any failure rather than returning an error code 12 | // b) defines pthread-like interface on platforms where where 13 | // is not supplied by default. 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | #ifndef SANITIZER_PTHREAD_WRAPPERS_H 18 | #define SANITIZER_PTHREAD_WRAPPERS_H 19 | 20 | #include "sanitizer_test_utils.h" 21 | 22 | #if !defined(_WIN32) 23 | # include 24 | // Simply forward the arguments and check that the pthread functions succeed. 25 | # define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d)) 26 | # define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b)) 27 | #else 28 | typedef HANDLE pthread_t; 29 | 30 | struct PthreadHelperCreateThreadInfo { 31 | void *(*start_routine)(void *); 32 | void *arg; 33 | }; 34 | 35 | inline DWORD WINAPI PthreadHelperThreadProc(void *arg) { 36 | PthreadHelperCreateThreadInfo *start_data = 37 | reinterpret_cast(arg); 38 | (start_data->start_routine)(start_data->arg); 39 | delete start_data; 40 | return 0; 41 | } 42 | 43 | inline void PTHREAD_CREATE(pthread_t *thread, void *attr, 44 | void *(*start_routine)(void *), void *arg) { 45 | ASSERT_EQ(0, attr) << "Thread attributes are not supported yet."; 46 | PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo; 47 | data->start_routine = start_routine; 48 | data->arg = arg; 49 | *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0); 50 | DWORD err = GetLastError(); 51 | ASSERT_NE(nullptr, *thread) << "Failed to create a thread, got error 0x" 52 | << std::hex << err; 53 | } 54 | 55 | inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) { 56 | ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet."; 57 | ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE)); 58 | ASSERT_NE(0, CloseHandle(thread)); 59 | } 60 | 61 | inline void pthread_exit(void *retval) { 62 | ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet."; 63 | ExitThread(0); 64 | } 65 | #endif // _WIN32 66 | 67 | #endif // SANITIZER_PTHREAD_WRAPPERS_H 68 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_stoptheworld_testlib.cpp --------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // Dynamic library to test StopTheWorld functionality. 9 | // When loaded with LD_PRELOAD, it will periodically suspend all threads. 10 | //===----------------------------------------------------------------------===// 11 | /* Usage: 12 | clang++ -fno-exceptions -g -fPIC -I. \ 13 | sanitizer_common/tests/sanitizer_stoptheworld_testlib.cpp \ 14 | sanitizer_common/sanitizer_*.cpp -shared -lpthread -o teststoptheworld.so 15 | LD_PRELOAD=`pwd`/teststoptheworld.so /your/app 16 | */ 17 | 18 | #include "sanitizer_common/sanitizer_platform.h" 19 | #if SANITIZER_LINUX 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "sanitizer_common/sanitizer_stoptheworld.h" 28 | 29 | namespace { 30 | const uptr kSuspendDuration = 3; 31 | const uptr kRunDuration = 3; 32 | 33 | void Callback(const SuspendedThreadsList &suspended_threads_list, 34 | void *argument) { 35 | sleep(kSuspendDuration); 36 | } 37 | 38 | void *SuspenderThread(void *argument) { 39 | while (true) { 40 | sleep(kRunDuration); 41 | StopTheWorld(Callback, NULL); 42 | } 43 | return NULL; 44 | } 45 | 46 | __attribute__((constructor)) void StopTheWorldTestLibConstructor(void) { 47 | pthread_t thread_id; 48 | pthread_create(&thread_id, NULL, SuspenderThread, NULL); 49 | } 50 | } // namespace 51 | 52 | #endif // SANITIZER_LINUX 53 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_symbolizer_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_symbolizer_test.cpp -------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Tests for sanitizer_symbolizer.h and sanitizer_symbolizer_internal.h 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "sanitizer_common/sanitizer_allocator_internal.h" 14 | #include "sanitizer_common/sanitizer_symbolizer_internal.h" 15 | #include "gtest/gtest.h" 16 | 17 | namespace __sanitizer { 18 | 19 | TEST(Symbolizer, ExtractToken) { 20 | char *token; 21 | const char *rest; 22 | 23 | rest = ExtractToken("a;b;c", ";", &token); 24 | EXPECT_STREQ("a", token); 25 | EXPECT_STREQ("b;c", rest); 26 | InternalFree(token); 27 | 28 | rest = ExtractToken("aaa-bbb.ccc", ";.-*", &token); 29 | EXPECT_STREQ("aaa", token); 30 | EXPECT_STREQ("bbb.ccc", rest); 31 | InternalFree(token); 32 | } 33 | 34 | TEST(Symbolizer, ExtractInt) { 35 | int token; 36 | const char *rest = ExtractInt("123,456;789", ";,", &token); 37 | EXPECT_EQ(123, token); 38 | EXPECT_STREQ("456;789", rest); 39 | } 40 | 41 | TEST(Symbolizer, ExtractUptr) { 42 | uptr token; 43 | const char *rest = ExtractUptr("123,456;789", ";,", &token); 44 | EXPECT_EQ(123U, token); 45 | EXPECT_STREQ("456;789", rest); 46 | } 47 | 48 | TEST(Symbolizer, ExtractTokenUpToDelimiter) { 49 | char *token; 50 | const char *rest = 51 | ExtractTokenUpToDelimiter("aaa-+-bbb-+-ccc", "-+-", &token); 52 | EXPECT_STREQ("aaa", token); 53 | EXPECT_STREQ("bbb-+-ccc", rest); 54 | InternalFree(token); 55 | } 56 | 57 | #if !SANITIZER_WINDOWS 58 | TEST(Symbolizer, DemangleSwiftAndCXX) { 59 | // Swift names are not demangled in default llvm build because Swift 60 | // runtime is not linked in. 61 | EXPECT_STREQ("_TtSd", DemangleSwiftAndCXX("_TtSd")); 62 | // Check that the rest demangles properly. 63 | EXPECT_STREQ("f1(char*, int)", DemangleSwiftAndCXX("_Z2f1Pci")); 64 | #if !SANITIZER_FREEBSD // QoI issue with libcxxrt on FreeBSD 65 | EXPECT_STREQ("foo", DemangleSwiftAndCXX("foo")); 66 | #endif 67 | EXPECT_STREQ("", DemangleSwiftAndCXX("")); 68 | } 69 | #endif 70 | 71 | } // namespace __sanitizer 72 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_test_config.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_test_config.h ---------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of *Sanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #if !defined(INCLUDED_FROM_SANITIZER_TEST_UTILS_H) 13 | # error "This file should be included into sanitizer_test_utils.h only" 14 | #endif 15 | 16 | #ifndef SANITIZER_TEST_CONFIG_H 17 | #define SANITIZER_TEST_CONFIG_H 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #if SANITIZER_USE_DEJAGNU_GTEST 24 | # include "dejagnu-gtest.h" 25 | #else 26 | # include "gtest/gtest.h" 27 | #endif 28 | 29 | #endif // SANITIZER_TEST_CONFIG_H 30 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_test_main.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_test_main.cpp -------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #include "gtest/gtest.h" 13 | #include "sanitizer_common/sanitizer_flags.h" 14 | 15 | const char *argv0; 16 | 17 | int main(int argc, char **argv) { 18 | argv0 = argv[0]; 19 | testing::GTEST_FLAG(death_test_style) = "threadsafe"; 20 | testing::InitGoogleTest(&argc, argv); 21 | __sanitizer::SetCommonFlagsDefaults(); 22 | return RUN_ALL_TESTS(); 23 | } 24 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_type_traits_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_type_traits_test.cpp ------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of ThreadSanitizer/AddressSanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #include "sanitizer_common/sanitizer_type_traits.h" 13 | #include "gtest/gtest.h" 14 | #include "sanitizer_common/sanitizer_internal_defs.h" 15 | 16 | using namespace __sanitizer; 17 | 18 | TEST(SanitizerCommon, IsSame) { 19 | ASSERT_TRUE((is_same::value)); 20 | ASSERT_TRUE((is_same::value)); 21 | ASSERT_TRUE((is_same::value)); 22 | ASSERT_TRUE((is_same::value)); 23 | 24 | ASSERT_FALSE((is_same::value)); 25 | ASSERT_FALSE((is_same::value)); 26 | ASSERT_FALSE((is_same::value)); 27 | } 28 | 29 | TEST(SanitizerCommon, Conditional) { 30 | ASSERT_TRUE((is_same::type>::value)); 31 | ASSERT_TRUE((is_same::type>::value)); 32 | } 33 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/sanitizer_vector_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_vector_test.cpp -----------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This file is a part of *Sanitizer runtime. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #include "sanitizer_common/sanitizer_vector.h" 13 | #include "gtest/gtest.h" 14 | 15 | namespace __sanitizer { 16 | 17 | TEST(Vector, Basic) { 18 | Vector v; 19 | EXPECT_EQ(v.Size(), 0u); 20 | v.PushBack(42); 21 | EXPECT_EQ(v.Size(), 1u); 22 | EXPECT_EQ(v[0], 42); 23 | v.PushBack(43); 24 | EXPECT_EQ(v.Size(), 2u); 25 | EXPECT_EQ(v[0], 42); 26 | EXPECT_EQ(v[1], 43); 27 | } 28 | 29 | TEST(Vector, Stride) { 30 | Vector v; 31 | for (int i = 0; i < 1000; i++) { 32 | v.PushBack(i); 33 | EXPECT_EQ(v.Size(), i + 1u); 34 | EXPECT_EQ(v[i], i); 35 | } 36 | for (int i = 0; i < 1000; i++) { 37 | EXPECT_EQ(v[i], i); 38 | } 39 | } 40 | 41 | TEST(Vector, ResizeReduction) { 42 | Vector v; 43 | v.PushBack(0); 44 | v.PushBack(0); 45 | EXPECT_EQ(v.Size(), 2u); 46 | v.Resize(1); 47 | EXPECT_EQ(v.Size(), 1u); 48 | } 49 | 50 | } // namespace __sanitizer 51 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/tests/standalone_malloc_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | const size_t kNumThreds = 16; 10 | const size_t kNumIters = 1 << 23; 11 | 12 | inline void break_optimization(void *arg) { 13 | __asm__ __volatile__("" : : "r" (arg) : "memory"); 14 | } 15 | 16 | __attribute__((noinline)) 17 | static void *MallocThread(void *t) { 18 | size_t total_malloced = 0, total_freed = 0; 19 | size_t max_in_use = 0; 20 | size_t tid = reinterpret_cast(t); 21 | vector > allocated; 22 | allocated.reserve(kNumIters); 23 | for (size_t i = 1; i < kNumIters; i++) { 24 | if ((i % (kNumIters / 4)) == 0 && tid == 0) 25 | fprintf(stderr, " T[%ld] iter %ld\n", tid, i); 26 | bool allocate = (i % 5) <= 2; // 60% malloc, 40% free 27 | if (i > kNumIters / 4) 28 | allocate = i % 2; // then switch to 50% malloc, 50% free 29 | if (allocate) { 30 | size_t size = 1 + (i % 200); 31 | if ((i % 10001) == 0) 32 | size *= 4096; 33 | total_malloced += size; 34 | char *x = new char[size]; 35 | x[0] = x[size - 1] = x[size / 2] = 0; 36 | allocated.push_back(make_pair(x, size)); 37 | max_in_use = max(max_in_use, total_malloced - total_freed); 38 | } else { 39 | if (allocated.empty()) continue; 40 | size_t slot = i % allocated.size(); 41 | char *p = allocated[slot].first; 42 | p[0] = 0; // emulate last user touch of the block 43 | size_t size = allocated[slot].second; 44 | total_freed += size; 45 | swap(allocated[slot], allocated.back()); 46 | allocated.pop_back(); 47 | delete [] p; 48 | } 49 | } 50 | if (tid == 0) 51 | fprintf(stderr, " T[%ld] total_malloced: %ldM in use %ldM max %ldM\n", 52 | tid, total_malloced >> 20, (total_malloced - total_freed) >> 20, 53 | max_in_use >> 20); 54 | for (size_t i = 0; i < allocated.size(); i++) 55 | delete [] allocated[i].first; 56 | return 0; 57 | } 58 | 59 | template 60 | struct DeepStack { 61 | __attribute__((noinline)) 62 | static void *run(void *t) { 63 | break_optimization(0); 64 | DeepStack::run(t); 65 | break_optimization(0); 66 | return 0; 67 | } 68 | }; 69 | 70 | template<> 71 | struct DeepStack<0> { 72 | static void *run(void *t) { 73 | MallocThread(t); 74 | return 0; 75 | } 76 | }; 77 | 78 | // Build with -Dstandalone_malloc_test=main to make it a separate program. 79 | int standalone_malloc_test() { 80 | pthread_t t[kNumThreds]; 81 | for (size_t i = 0; i < kNumThreds; i++) 82 | pthread_create(&t[i], 0, DeepStack<200>::run, reinterpret_cast(i)); 83 | for (size_t i = 0; i < kNumThreds; i++) 84 | pthread_join(t[i], 0); 85 | malloc_stats(); 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /src/dfsan_rt/sanitizer_common/weak_symbols.txt: -------------------------------------------------------------------------------- 1 | ___sanitizer_free_hook 2 | ___sanitizer_malloc_hook 3 | ___sanitizer_report_error_summary 4 | ___sanitizer_sandbox_on_notify 5 | ___sanitizer_symbolize_code 6 | ___sanitizer_symbolize_data 7 | ___sanitizer_symbolize_demangle 8 | ___sanitizer_symbolize_flush 9 | -------------------------------------------------------------------------------- /src/memlog_rt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 11) 2 | 3 | add_library(memlog_rt STATIC 4 | memlog.c) 5 | 6 | include_directories(include) 7 | include_directories(../afl_rt/include) 8 | 9 | set_target_properties(memlog_rt 10 | PROPERTIES 11 | ARCHIVE_OUTPUT_DIRECTORY "${DTAINT_LIB_DIR}" 12 | COMPILE_FLAGS "-fPIC -O3") 13 | 14 | option(MEMLOG_DEBUG "Memlog Debugging" OFF) 15 | 16 | if(MEMLOG_DEBUG) 17 | target_compile_options(memlog_rt PRIVATE -DMEMLOG_DEBUG) 18 | endif() -------------------------------------------------------------------------------- /src/memlog_rt/include/memlog.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEMLOG_H_ 2 | #define _MEMLOG_H_ 3 | #define MEM_MAP_W (1 << 16) 4 | #define MEM_MAP_H 32 5 | #define MEM_MAP_MAX_IDX 8 6 | 7 | enum HookType { 8 | 9 | HT_UNKNOWN = 0, 10 | // __memlog_hook1 (unsigned id, void* ptr, unsigned src_type, unsigned rst_type); 11 | // ex. load inst. 12 | HT_HOOK1 = 1, 13 | // __memlog_hook2 (unsigned id, size_t value, unsigned src_type, void* ptr, unsigned rst_type); 14 | // ex. store inst. 15 | HT_HOOK2 = 2, 16 | // __memlog_hook2_int128 (unsigned id, uint128_t value, unsigned src_type, void* ptr, unsigned rst_type); 17 | // deal with 16byte float point value 18 | HT_HOOK2_INT128 = 3, 19 | // __memlog_hook3 (unsigned id, void* ptr, int c, size_t size); 20 | // ex. memset 21 | HT_HOOK3 = 4, 22 | // __memlog_hook4 (unsigned id, void* dst, void* src, size_t size); 23 | // ex. memcpy 24 | HT_HOOK4 = 5, 25 | // __memlog_hook5 (unsigned id, size_t size); 26 | // ex. malloc 27 | HT_HOOK5 = 6, 28 | // __memlog_hook6 (unsigned id, void* ptr); 29 | // ex. free 30 | HT_HOOK6 = 7, 31 | // __memlog_hook7 (unsigned id, void* ptr, size_t size); 32 | // ex. realloc 33 | HT_HOOK7 = 8, 34 | // __memlog_va_arg_hook1 (unsigned id, void* ptr, unsigned src_type, 35 | // unsigned rst_type, unsigned num_of_idx, ...); 36 | // ex. get_element_ptr 37 | HT_GEP_HOOK = 9 38 | 39 | }; 40 | 41 | struct mem_header { 42 | 43 | // instructions executed 44 | unsigned int hits; 45 | // unique id 46 | unsigned int id; 47 | // src shape 48 | unsigned int src_shape; 49 | // result shape 50 | unsigned int rst_shape; 51 | //type 52 | unsigned int type; 53 | 54 | } __attribute__((packed)); 55 | 56 | 57 | struct hook_operand { 58 | 59 | void* src; 60 | void* dst; 61 | unsigned long long size; 62 | unsigned long long value; 63 | unsigned long long value_128; 64 | 65 | }; 66 | 67 | struct hook_va_arg_operand { 68 | 69 | unsigned int num; 70 | void* ptr; 71 | unsigned int idx[MEM_MAP_MAX_IDX]; 72 | 73 | } __attribute__((packed)); 74 | 75 | struct hook_va_arg_idx { 76 | 77 | unsigned int type; 78 | unsigned long long idx; 79 | 80 | } __attribute__((packed)); 81 | 82 | union hook_operands { 83 | 84 | struct hook_operand __hook_op; 85 | struct hook_va_arg_operand __hook_va_arg; 86 | 87 | }; 88 | 89 | struct mem_map { 90 | 91 | /* used for path hash calculation, for speed, just one byte */ 92 | unsigned char hits[MEM_MAP_W]; 93 | struct mem_header headers[MEM_MAP_W]; 94 | union hook_operands log[MEM_MAP_W][MEM_MAP_H]; 95 | /** 96 | * current memlog map hash 97 | * used to distinguish different path 98 | * 99 | */ 100 | unsigned long long cksum[MEM_MAP_W][MEM_MAP_H]; 101 | 102 | }; 103 | 104 | #endif -------------------------------------------------------------------------------- /src/pass/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(LLVM REQUIRED CONFIG) 3 | 4 | if (LLVM_FOUND) 5 | message(STATUS "LLVM_VERSION_MAJOR: ${LLVM_VERSION_MAJOR}") 6 | message(STATUS "LLVM_VERSION_MINOR: ${LLVM_VERSION_MINOR}") 7 | message(STATUS "LLVM_VERSION_PATCH: ${LLVM_VERSION_PATCH}") 8 | if (${LLVM_VERSION_MAJOR} GREATER 11 OR ${LLVM_VERSION_MAJOR} LESS 11) 9 | message(FATAL_ERROR "LLVM version should be 11.0.0 !") 10 | endif() 11 | else() 12 | message(FATAL_ERROR "You haven't install LLVM !") 13 | endif() 14 | 15 | if (NOT TARGET LLVMPassConfig) 16 | add_library(LLVMPassConfig INTERFACE IMPORTED) 17 | set_target_properties(LLVMPassConfig PROPERTIES 18 | INTERFACE_COMPILE_OPTIONS "-fno-rtti" #-fpic 19 | INTERFACE_INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIRS}" 20 | INTERFACE_LINK_DIRECTORIES "${LLVM_LIBRARY_DIRS}" 21 | INTERFACE_COMPILE_DEFINITIONS "LLVM_VERSION_MAJOR=${LLVM_VERSION_MAJOR};LLVM_VERSION_MINOR=${LLVM_VERSION_MINOR};MAP_SIZE_POW2=${MAP_SIZE_POW2}" 22 | # INTERFACE_LINK_OPTIONS "-Wl,-znodelete" 23 | ) 24 | endif() 25 | 26 | # fix pass bug: https://github.com/sampsyo/llvm-pass-skeleton/issues/7#issuecomment-401834287 27 | set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-znodelete") 28 | 29 | #DataFlowSanitizer Pass 30 | add_library(DFSanPass MODULE DataFlowSanitizer.cpp) 31 | target_link_libraries(DFSanPass LLVMPassConfig) 32 | #install (TARGETS DFSanPass DESTINATION ${DTAINT_PASS_DIR}) 33 | #Memlog Pass 34 | add_library(MemlogPass MODULE MemlogPass.cc) 35 | target_link_libraries(MemlogPass LLVMPassConfig) 36 | #install (TARGETS MemlogPass DESTINATION ${DTAINT_PASS_DIR}) 37 | set_target_properties(DFSanPass 38 | MemlogPass 39 | PROPERTIES 40 | LIBRARY_OUTPUT_DIRECTORY "${DTAINT_PASS_DIR}" 41 | ) 42 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | CC = clang 2 | CXX = clang++ 3 | CFLAGS = -O3 -fPIE -pie -g -v 4 | CXXFLAGS = -O3 -fPIE -pie 5 | OPT=/usr/bin/opt-11 6 | PASS1 = ../build/pass/libDFSanPass.so 7 | PASS2 = ../build/pass/libTaintPass.so 8 | PASS1_ARG = -dfsan 9 | PASS2_ARG = -taint 10 | ABILIST1 = ../build/lib/share/dfsan_abilist.txt 11 | ABILIST2 = ../src/pass/abilist.txt 12 | # Need to enable corresponding llvm optimization level, where your pass is registed. 13 | # otherwise your opt pass will not be executed. 14 | LLVM_PASS1 = -Xclang -load -Xclang $(PASS1) -mllvm -taint-dfsan-abilist=$(ABILIST1) 15 | LLVM_PASS2 = -Xclang -load -Xclang $(PASS2) 16 | RUNTIME1 = ../build/lib/libclang_rt.dfsan-x86_64.a -ldl -lpthread -lstdc++ 17 | RUNTIME2 = ../build/lib/libtaint_rt.a 18 | SRC := $(wildcard *.c) 19 | ELF = target 20 | BC = target.bc 21 | BC2 = target2.bc 22 | 23 | .PHONY: all origin opt clean 24 | 25 | all: 26 | $(CC) $(CFLAGS) $(LLVM_PASS1) $(LLVM_PASS2) target.c -c -o target.o 27 | $(CC) $(CFLAGS) target.o $(RUNTIME1) $(RUNTIME2) -o $(ELF) 28 | 29 | origin: 30 | $(CC) $(CFLAGS) target.c -o target 31 | 32 | opt: 33 | $(CXX) $(CFLAGS) -S -emit-llvm test.cpp -o test.bc 34 | $(CXX) $(CFLAGS) -S -emit-llvm -Xclang -load -Xclang ../build/pass/libMemlogPass.so -mllvm -memlog-hook-inst=1 test.cpp -o test2.bc 35 | #$(OPT) -load ../build/pass/libMemlogPass.so -Memloghook test.bc -o test2.bc 36 | #$(CC) $(CFLAGS) $(BC2) $(RUNTIME2) -o target 37 | 38 | clean: 39 | rm -f $(wildcard *.o) 40 | rm -f $(ELF) 41 | rm -f $(BC) 42 | rm -f $(BC2) 43 | rm -f target_taint 44 | -------------------------------------------------------------------------------- /test/environment/atexit_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void dump() { 6 | std::cout<<"Test for calling order of c++ global object destructor and atexit call in __libc_start_main."< 2 | #include 3 | #include 4 | 5 | void dump() { 6 | std::cout<<"Test for calling order of c++ global object destructor and atexit call in __libc_start_main."< 2 | #include 3 | 4 | /* define simple structure */ 5 | struct { 6 | unsigned int widthValidated; 7 | unsigned int heightValidated; 8 | } status1; 9 | 10 | /* define a structure with bit fields */ 11 | struct { 12 | char widthValidated : 1; 13 | char heightValidated : 1; 14 | } status2; 15 | 16 | struct { 17 | unsigned int age: 3; 18 | } Age; 19 | 20 | struct cmp_header { 21 | 22 | unsigned hits : 24; 23 | unsigned id : 24; 24 | unsigned shape : 5; 25 | unsigned type : 2; 26 | unsigned attribute : 4; 27 | unsigned reserved : 5; 28 | 29 | } __attribute__((packed)) __cmp_header; 30 | 31 | int main( ) { 32 | unsigned k; 33 | printf("unsigned size: %d\n", sizeof(k)); 34 | printf( "Memory size occupied by status1 : %d\n", sizeof(status1)); 35 | printf( "Memory size occupied by status2 : %d\n", sizeof(status2)); 36 | printf( "Memory size occupied by Age : %d\n", sizeof(Age)); 37 | printf( "Memory size occupied by __cmp_header: %d\n", sizeof(__cmp_header)); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test/environment/color_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | int main() { 6 | 7 | fprintf(stderr, "\x1b[0;36mtaint inference\n"); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /test/environment/env_child_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | int main(int argc, char **argv, char **envp) { 6 | 7 | int k = 0; 8 | while(envp[k] != NULL) { 9 | fprintf(stderr, "envp[%d]: %s\n", k, envp[k]); 10 | k++; 11 | } 12 | 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/environment/env_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | int main() { 7 | int status; 8 | pid_t pid = fork(); 9 | 10 | setenv("GAGAGA", "BADDAASDSADSSS", 1); 11 | setenv("Angora", "fuzzing", 1); 12 | 13 | if (pid == 0) { 14 | fprintf(stderr, "child exec\n"); 15 | char* argv[1]; 16 | argv[0] = NULL; 17 | execl("./env_child_test", "rew", NULL); 18 | } 19 | else { 20 | 21 | } 22 | 23 | wait(&status); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/environment/float_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | float float_test(float a, float b) { 5 | 6 | return a + b; 7 | } 8 | 9 | int main() { 10 | float a; 11 | float b; 12 | double c; 13 | a = 1.111111111; 14 | b = 2.3; 15 | 16 | c = float_test(a, b); 17 | fprintf(stderr, "c: %f b: %f a: %f\n", c, b, a); 18 | 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /test/environment/fstream_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int main() { 6 | 7 | std::fstream infile; 8 | infile.open(".hookID.txt", std::ios::in | std::ios::out); 9 | unsigned int hookID; 10 | if (infile.eof()) 11 | hookID = 0; 12 | else 13 | infile >> hookID; 14 | infile >> hookID; 15 | 16 | std::cout << hookID << std::endl; 17 | infile.close(); 18 | 19 | 20 | std::fstream outfile; 21 | outfile.open(".hookID.txt", std::ios::out | std::ios::trunc); 22 | 23 | outfile << hookID+1; 24 | outfile.close(); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /test/environment/getElementPtr_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | struct RT { 5 | char A; 6 | int B[10][20]; 7 | char C; 8 | }; 9 | struct ST { 10 | int X; 11 | double Y; 12 | struct RT Z; 13 | }; 14 | 15 | int *foo(struct ST *s) { 16 | return &s[1].Z.B[5][13]; 17 | } -------------------------------------------------------------------------------- /test/environment/init_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | __attribute__((constructor)) void debug(int argc, char** argv, char **envp) { 5 | fprintf(stderr, "called before main\n"); 6 | } 7 | 8 | int main(int argc, char** argv[]) { 9 | 10 | printf("this main\n"); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /test/environment/mmap_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Test for internel_mmap in DFSan, cause SegFault. 6 | */ 7 | int main() { 8 | 9 | void* addr = mmap((void *)0x10000, 0x200200000000 - 0x10000, 0x3, 0x4032, 0xffffffffffffffff, 0x0); 10 | printf("ok. address is %p\n", addr); 11 | return 0; 12 | } -------------------------------------------------------------------------------- /test/environment/opt_priority_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct A { 6 | int B[16]; 7 | }; 8 | 9 | 10 | int main () { 11 | 12 | struct A *a = (struct A*)malloc(sizeof(struct A)); 13 | 14 | memset(a, 0, sizeof(struct A)); 15 | 16 | a->B[10] = 2; 17 | 18 | for(int i = 0; i < 16; i++) { 19 | 20 | fprintf(stderr, "A.B[%d]: %d ", i, a->B[i]); 21 | }fprintf(stderr, "\n"); 22 | 23 | a->B[10]++; 24 | 25 | for(int i = 0; i < 16; i++) { 26 | 27 | fprintf(stderr, "A.B[%d]: %d ", i, a->B[i]); 28 | }fprintf(stderr, "\n"); 29 | 30 | a->B[0]++; 31 | 32 | for(int i = 0; i < 16; i++) { 33 | 34 | fprintf(stderr, "A.B[%d]: %d ", i, a->B[i]); 35 | }fprintf(stderr, "\n"); 36 | 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /test/environment/preinit_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | static void preinit_debug() { 5 | printf("preinit\n"); 6 | } 7 | 8 | __attribute__((section(".preinit_array"), used)) 9 | static void (*preinit_debug_ptr)(int, char **, char **) = preinit_debug; 10 | __attribute((constructor)) void init_debug() { 11 | printf("__libc_csu_init\n"); 12 | } 13 | 14 | int main(int argc, char** argv[]) { 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /test/environment/pthread_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // 子執行緒函數 6 | void* child(void* data) { 7 | char *str = (char*) data; // 取得輸入資料 8 | for(int i = 0;i < 3;++i) { 9 | printf("%s\n", str); // 每秒輸出文字 10 | sleep(1); 11 | } 12 | pthread_exit(NULL); // 離開子執行緒 13 | } 14 | 15 | // 主程式 16 | int main() { 17 | pthread_t t; // 宣告 pthread 變數 18 | pthread_create(&t, NULL, child, "Child"); // 建立子執行緒 19 | 20 | // 主執行緒工作 21 | for(int i = 0;i < 3;++i) { 22 | printf("Master\n"); // 每秒輸出文字 23 | sleep(1); 24 | } 25 | 26 | pthread_join(t, NULL); // 等待子執行緒執行完成 27 | return 0; 28 | } -------------------------------------------------------------------------------- /test/environment/shm_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int main(int argc, char* argv[]) { 6 | 7 | int fd = shm_open("shm_test_shm1", O_CREAT | O_RDWR | O_EXCL, 0600); 8 | fprintf(stderr, "fd: %u", fd); 9 | while(1); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /test/environment/strchr_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | 7 | int ninks = 4, inknameslen = 0; 8 | char *inknames = (char *)malloc(0xf); 9 | strncpy(inknames, "not_kitty.tiff\0", 15); 10 | const char* cp = inknames; 11 | char * chunk2, *chunk3; 12 | 13 | chunk2 = (char *)malloc(0x50); 14 | chunk3 = (char *)malloc(0x90); 15 | 16 | free(chunk2); 17 | 18 | while (ninks > 1) { 19 | cp = strchr(cp, '\0'); 20 | if (cp) { 21 | cp++; 22 | inknameslen += (strlen(cp) + 1); 23 | } 24 | } 25 | ninks--; 26 | 27 | 28 | return 0; 29 | 30 | } -------------------------------------------------------------------------------- /test/environment/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | int main() { 6 | unsigned hits = 0; 7 | unsigned current_hits = 1; 8 | 9 | hits = current_hits++; 10 | 11 | fprintf(stderr, "hits: %u current hits: %u\n", hits, current_hits); 12 | 13 | return 0; 14 | } -------------------------------------------------------------------------------- /test/environment/typedef_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct tainted { 6 | 7 | unsigned pos; 8 | unsigned len; 9 | struct tainted *next; 10 | 11 | }; 12 | 13 | typedef struct tainted* tainted_map[4][4]; 14 | 15 | int main(int argc, char *argv[]) { 16 | 17 | tainted_map *map; 18 | 19 | if (argc >= 2) { 20 | map = (tainted_map *)malloc(sizeof(tainted_map)); 21 | 22 | for(int i = 0; i < 4; i++) { 23 | 24 | memset((*map)[i], 0, sizeof(struct tainted *) * 4); 25 | 26 | } 27 | 28 | for(int i = 0; i < 4; i++) { 29 | for(int j = 0; j < 4; j++) { 30 | if ((*map)[i][j] == NULL) { 31 | (*map)[i][j] = (struct tainted *)malloc(sizeof(struct tainted)); 32 | (*map)[i][j]->pos = 9487; 33 | (*map)[i][j]->len = 9527; 34 | } 35 | 36 | fprintf(stderr, "map[%d][%d]: pos: %d len: %d\n", i, j, (*map)[i][j]->pos, (*map)[i][j]->len); 37 | }fprintf(stderr, "\n"); 38 | } 39 | } 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /test/environment/union_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | 5 | struct hook1 { 6 | void* ptr; 7 | size_t size; 8 | }; 9 | 10 | struct hook2 { 11 | void* ptr; 12 | size_t size; 13 | int c; 14 | }; 15 | 16 | struct hook3 { 17 | void* src; 18 | void* dst; 19 | size_t size; 20 | }; 21 | 22 | struct hook4 { 23 | void* ptr; 24 | int src_type; 25 | int rst_type; 26 | }; 27 | 28 | struct hook5 { 29 | void* ptr; 30 | int src_type; 31 | int rst_type; 32 | size_t value; 33 | }; 34 | 35 | union hook { 36 | struct hook1 __hook1; 37 | struct hook2 __hook2; 38 | struct hook3 __hook3; 39 | struct hook4 __hook4; 40 | struct hook5 __hook5; 41 | }; 42 | 43 | int main(int argc, char* argv[]) { 44 | struct hook5 test_hook5; 45 | 46 | test_hook5.ptr = 0x10; 47 | test_hook5.rst_type = 8; 48 | test_hook5.src_type = 16; 49 | test_hook5.value = 9487; 50 | 51 | union hook test_hook; 52 | test_hook.__hook5 = test_hook5; 53 | 54 | fprintf(stderr, "test hook5: ptr: %p src_type: %u rst_type: %u value: %lld\n", 55 | test_hook.__hook5.ptr, test_hook.__hook5.rst_type, test_hook.__hook5.src_type, test_hook.__hook5.value); 56 | 57 | fprintf(stderr, "test hook1: ptr: %p size: %lld", 58 | test_hook.__hook1.ptr, test_hook.__hook1.size); 59 | return 0; 60 | } -------------------------------------------------------------------------------- /test/environment/va_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int func(int num1, int num2, int num3, int num_of_idx, ...) { 5 | 6 | fprintf(stderr, "num1: %d num2: %p num3: %lf num4: %d\n", num1, num2, num3, num_of_idx); 7 | 8 | va_list args; 9 | va_start(args, num_of_idx); 10 | 11 | //for(int j = 0; j < num_of_idx; j++) { 12 | fprintf(stderr, "float: %lf\n", va_arg(args, double)); 13 | 14 | fprintf(stderr, "int64: %p\n", va_arg(args, long long)); 15 | long long v1 = va_arg(args, long long); 16 | long long v2 = va_arg(args, long long); 17 | fprintf(stderr, "upper: %p lower: %p\n", v1, v2); 18 | __int128_t val = va_arg(args, __int128); 19 | fprintf(stderr, "upper: %p lower: %x\n", (long long)(val >> 64),(val)); 20 | //} 21 | va_end(args); 22 | } 23 | int main() { 24 | 25 | func(99, 98, 87, 5, 777.676567, 666, 0x7fffffffffff8787, 0x7fffffffffff8585, 0x7fffffffffff8686); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /test/environment/wait_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | 7 | int main() { 8 | fprintf(stderr, "WNOHANG: %u WUNTRACED: %u", WNOHANG, WUNTRACED); 9 | return 0; 10 | } -------------------------------------------------------------------------------- /test/hook_test/Makefile: -------------------------------------------------------------------------------- 1 | CC = clang 2 | CXX = clang++ 3 | DTAINT_CC = ../../build/clang-wrapper 4 | AFL_CC = ../../../AFLplusplus/afl-cc 5 | CFLAGS = -fPIE -pie -g -v 6 | CXXFLAGS = fPIE -pie 7 | SRC = $(wildcard *.c) 8 | ELF = $(patsubst %.c, %, $(SRC)) 9 | ELF_ORIG = $(patsubst %.c, %_orig, $(SRC)) 10 | ELF_AFL = $(patsubst %.c, %_afl, $(SRC)) 11 | afl_SRC = $(wildcard *.c) 12 | .PHONY: all origin afl clean 13 | 14 | all: $(ELF) 15 | 16 | $(patsubst %.c, %, %.c): %.c 17 | ifeq ($(MEMLOG_MODE), 1) 18 | $(DTAINT_CC) $< -o $@ 19 | else 20 | $(DTAINT_CC) $< -o $@ 21 | endif 22 | $(AFL_CC) $< -o $(patsubst %, %_afl, $@) 23 | #$(CC) $< -o $(patsubst %, %_orig, $@) 24 | 25 | clean: 26 | rm -f $(wildcard *.o) 27 | rm -f $(ELF) 28 | rm -f $(ELF_ORIG) 29 | rm -f $(ELF_AFL) 30 | 31 | -------------------------------------------------------------------------------- /test/hook_test/hook3_test.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_hook3. 3 | * In this program function memset's 2nd, 3rd argument can be 4 | * affected by input. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define MAXSIZE 512 15 | 16 | int main(int argc, char** argv) 17 | { 18 | char src[MAXSIZE]; 19 | FILE *f; 20 | unsigned int size, len, value; 21 | 22 | if (argc < 2) 23 | return -1; 24 | 25 | memset(src, 0, MAXSIZE); 26 | 27 | f = fopen (argv[1], "r"); 28 | 29 | if (f == NULL) 30 | return -1; 31 | 32 | while (1) { 33 | len = fread (src, 1, MAXSIZE, f); 34 | if (len <= 0) 35 | break; 36 | } 37 | 38 | fclose(f); 39 | 40 | value = (unsigned char)src[0]; 41 | size = (unsigned char)src[0] + (unsigned char)src[1]; 42 | 43 | fprintf(stderr, "value: %d size: %d\n", value, size); 44 | 45 | for (int i = 0; i < MAXSIZE; i++) { 46 | 47 | if (i == MAXSIZE - 1) { 48 | memset(src, value, size); 49 | } 50 | 51 | } 52 | 53 | return 0; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /test/hook_test/hook4_test.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_hook4. 3 | * In this program function memcpy's 2nd, 3rd argument can be 4 | * affected by input. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXSIZE 512 14 | 15 | int main(int argc, char** argv) 16 | { 17 | char src[MAXSIZE]; 18 | FILE *f; 19 | unsigned int size, len; 20 | char *dst; 21 | 22 | if (argc < 2) 23 | return -1; 24 | 25 | memset(src, 0, MAXSIZE); 26 | 27 | f = fopen (argv[1], "r"); 28 | 29 | if (f == NULL) 30 | return -1; 31 | 32 | while (1) { 33 | len = fread (src, 1, MAXSIZE, f); 34 | if (len <= 0) 35 | break; 36 | } 37 | 38 | fclose(f); 39 | 40 | dst = src + (unsigned char)src[0]; 41 | size = (unsigned char)src[1] + (unsigned char)src[8]; 42 | 43 | fprintf(stderr, "dst: %p size: %d\n", dst, size); 44 | 45 | for (int i = 0; i < MAXSIZE; i++) { 46 | 47 | if (i == MAXSIZE - 1) { 48 | memcpy(dst, src, size); 49 | } 50 | 51 | } 52 | 53 | return 0; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /test/hook_test/hook5_test.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_hook5. 3 | * In this program function malloc argument can be 4 | * affected by input. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXSIZE 512 14 | 15 | int main(int argc, char** argv) 16 | { 17 | char src[MAXSIZE]; 18 | FILE *f; 19 | unsigned int size, len; 20 | char *dst; 21 | 22 | if (argc < 2) 23 | return -1; 24 | 25 | memset(src, 0, MAXSIZE); 26 | 27 | f = fopen (argv[1], "r"); 28 | 29 | if (f == NULL) 30 | return -1; 31 | 32 | while (1) { 33 | len = fread (src, 1, MAXSIZE, f); 34 | if (len <= 0) 35 | break; 36 | } 37 | 38 | fclose(f); 39 | 40 | size = (unsigned char)src[1] + (unsigned char)src[5]; 41 | dst = malloc(size); 42 | 43 | fprintf(stderr, "dst: %p size: %d\n", dst, size); 44 | 45 | 46 | for (int i = 0; i < size; i++) { 47 | 48 | dst[i] = src[i]*2; 49 | 50 | } 51 | 52 | free(dst); 53 | 54 | return 0; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /test/hook_test/hook6_test.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_hook6. 3 | * In this program function free argument can be 4 | * affected by input. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXSIZE 512 14 | 15 | int main(int argc, char** argv) 16 | { 17 | char src[MAXSIZE]; 18 | FILE *f; 19 | unsigned int size, len; 20 | char *dst; 21 | 22 | if (argc < 2) 23 | return -1; 24 | 25 | memset(src, 0, MAXSIZE); 26 | 27 | f = fopen (argv[1], "r"); 28 | 29 | if (f == NULL) 30 | return -1; 31 | 32 | while (1) { 33 | len = fread (src, 1, MAXSIZE, f); 34 | if (len <= 0) 35 | break; 36 | } 37 | 38 | fclose(f); 39 | 40 | size = (unsigned char)src[1] + (unsigned char)src[4]; 41 | dst = malloc(MAXSIZE); 42 | 43 | fprintf(stderr, "dst: %p size: %d\n", dst, size); 44 | 45 | 46 | for (int i = 0; i < size; i++) { 47 | 48 | dst[i] = src[i]*2; 49 | 50 | } 51 | 52 | free(dst); 53 | 54 | return 0; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /test/hook_test/test.txt: -------------------------------------------------------------------------------- 1 | 2434127653dsasdawqewqqw 2 | -------------------------------------------------------------------------------- /test/hook_test/testcases/test.txt: -------------------------------------------------------------------------------- 1 | 223412dsasdawqewqqw 2 | -------------------------------------------------------------------------------- /test/hook_test/va_arg_hook1_test.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_va_arg_hook1. 3 | * In this program aggregate type access should be 4 | * affected by input. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXSIZE 512 14 | 15 | int main(int argc, char** argv) 16 | { 17 | char src[MAXSIZE]; 18 | FILE *f; 19 | unsigned int size, len; 20 | 21 | if (argc < 2) 22 | return -1; 23 | 24 | memset(src, 0, MAXSIZE); 25 | 26 | f = fopen (argv[1], "r"); 27 | 28 | if (f == NULL) 29 | return -1; 30 | 31 | while (1) { 32 | len = fread (src, 1, MAXSIZE, f); 33 | if (len <= 0) 34 | break; 35 | } 36 | 37 | fclose(f); 38 | 39 | size = (unsigned char)src[2] + (unsigned char)src[8]; 40 | 41 | fprintf(stderr, "size: %d\n", size); 42 | 43 | 44 | for (int i = 0; i < MAXSIZE; i++) { 45 | 46 | if(i >= MAXSIZE - 2) { 47 | 48 | src[size + i] = '8'; 49 | } 50 | 51 | } 52 | 53 | return 0; 54 | 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/hook_test/va_arg_hook1_test_with_constraint.c: -------------------------------------------------------------------------------- 1 | /** 2 | * This program is used as a test for __memlog_va_arg_hook1. 3 | * In this program aggregate type access should be 4 | * affected by input. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAXSIZE 512 14 | 15 | int main(int argc, char** argv) 16 | { 17 | char src[MAXSIZE]; 18 | FILE *f; 19 | unsigned int size, len; 20 | 21 | if (argc < 2) 22 | return -1; 23 | 24 | memset(src, 0, MAXSIZE); 25 | 26 | f = fopen (argv[1], "r"); 27 | 28 | if (f == NULL) 29 | return -1; 30 | 31 | while (1) { 32 | len = fread (src, 1, MAXSIZE, f); 33 | if (len <= 0) 34 | break; 35 | } 36 | 37 | fclose(f); 38 | 39 | size = (unsigned char)src[9]; 40 | 41 | fprintf(stderr, "size: %d\n", size); 42 | 43 | 44 | for (int i = 0; i < MAXSIZE; i++) { 45 | 46 | if(i >= MAXSIZE - 2 && size <= 57 && size >= 48) { 47 | 48 | src[size + i] = '8'; 49 | } 50 | 51 | } 52 | 53 | return 0; 54 | 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /test/target.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define MAXSIZE 256 7 | 8 | 9 | struct A{ 10 | int pos; 11 | int len; 12 | }; 13 | char dst[MAXSIZE]; 14 | int main(int argc, char** argv) 15 | { 16 | char* src; 17 | FILE *f; 18 | int size, len; 19 | char buf[16]; 20 | 21 | src = malloc(MAXSIZE); 22 | 23 | memset(src, 0, MAXSIZE); 24 | 25 | f = fopen ("test.txt", "r"); 26 | 27 | while (1) { 28 | len = fread (src, 1, 1, f); 29 | if (len <= 0) 30 | break; 31 | } 32 | 33 | fclose(f); 34 | 35 | src = realloc(src, MAXSIZE * 2); 36 | int temp = 0, count = 0; 37 | 38 | for(int i = 0; i < MAXSIZE; i++) { 39 | 40 | src[i] = 9487 + i; 41 | count += src[i]; 42 | 43 | } 44 | 45 | memcpy(dst, src, MAXSIZE); 46 | 47 | memmove(dst, dst + MAXSIZE/2 , MAXSIZE/4); 48 | 49 | memcmp(dst, src, MAXSIZE); 50 | struct A st; 51 | st.len = 10; 52 | st.pos = 1; 53 | 54 | count += st.len + st.pos; 55 | fprintf(stderr, "%d\n", count); 56 | 57 | free(src); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | // inserting into a vector 2 | #include 3 | #include 4 | 5 | 6 | struct element { 7 | unsigned long long num; 8 | unsigned pos; 9 | unsigned len; 10 | }; 11 | 12 | int main () 13 | { 14 | std::vector myvector(100, 100); 15 | std::vector::iterator it; 16 | 17 | //int a[32][32]; 18 | 19 | 20 | it = myvector.begin(); 21 | it = myvector.insert ( it , 200 ); 22 | it = myvector.insert (it,1,9487); 23 | 24 | // myvector.insert (it,1,9487); 25 | 26 | // "it" no longer valid, get a new one: 27 | 28 | std::vector anothervector (2,400); 29 | myvector.insert (it+2,anothervector.begin(),anothervector.end()); 30 | 31 | int myarray [] = { 501,502,503 }; 32 | myvector.insert (myvector.begin(), myarray, myarray+3); 33 | 34 | myvector.push_back(101); 35 | myvector.push_back(102); 36 | 37 | int temp; 38 | std::cout << "myvector contains:"; 39 | for (it=myvector.begin(); it&2 <<_EOF_ 7 | Usage 8 | - Discard taints 9 | $ ./gen_library_abilist.sh path-to-library.so > xxlib_abilist.txt discard 10 | - Return value is the union of the label of its arguments. 11 | $ ./gen_library_abilist.sh path-to-library.so > xxlib_abilist.txt functional 12 | - Define a custom wrapper by yourself 13 | $ ./gen_library_abilist.sh path-to-library.so > xxlib_abilist.txt custom 14 | visit https://clang.llvm.org/docs/DataFlowSanitizer.html to see more. 15 | _EOF_ 16 | 17 | exit 1 18 | 19 | fi 20 | 21 | NM=`which nm 2>/dev/null` 22 | 23 | if [ "$NM" = "" ]; then 24 | echo "[-] Error: can't find 'nm' in your \$PATH. please install binutils" 1>&2 25 | exit 1 26 | fi 27 | 28 | echo "# $1" | grep 'so[.0-9]*$' 29 | if [ $? -eq 0 ] 30 | then 31 | # echo "dynamic library.." 32 | nm -D --defined-only $1 | grep " T " | sed 's/^[0-9a-z]\+ T /fun:/g; s/$/=uninstrumented/g' 33 | nm -D --defined-only $1 | grep " T " | sed "s/^[0-9a-z]\+ T /fun:/g; s/$/=$2/g" 34 | else 35 | # echo "static library.." 36 | nm --defined-only $1 | grep " T " | sed 's/^[0-9a-z]\+ T /fun:/g; s/$/=uninstrumented/g' 37 | nm --defined-only $1 | grep " T " | sed "s/^[0-9a-z]\+ T /fun:/g; s/$/=$2/g" 38 | fi 39 | -------------------------------------------------------------------------------- /tools/gen_target_abilist.sh: -------------------------------------------------------------------------------- 1 | # Script for generate target_abilist.txt, all target abilists stored in 2 | # src/abilist/target will be generated when building this project. 3 | # User can also manually generate new target_abilist.txt through this 4 | # script. 5 | # This script will combine all file in given directory to a single file. 6 | #!/bin/bash 7 | if test -d $1 8 | then 9 | find $1 -type f -exec cat {} + > $2 10 | else 11 | echo "Usage: ./gen_target_abilist.sh [input_dir] [output_file]" 12 | fi -------------------------------------------------------------------------------- /tools/gen_udr_abilist.sh: -------------------------------------------------------------------------------- 1 | # This script is for generate abilist when target trys to include instrumented library 2 | # and cause undefined reference. 3 | 4 | #!/bin/bash 5 | 6 | # read error message from build message 7 | if test -f $1 8 | then 9 | cat $1 | grep -F 'undefined reference to `dfs$' | sed "s/^.*\(\$.*\'\)/\1/g; s/^./fun:/g; s/.$/=uninstrumented/g;" > $2 10 | cat $1 | grep -F 'undefined reference to `dfs$' | sed "s/^.*\(\$.*\'\)/\1/g; s/^./fun:/g; s/.$/=discard/g;" >> $2 11 | 12 | else 13 | echo "Usage: ./gen_udr_abilist.sh [error message file] [output_file]" 14 | fi -------------------------------------------------------------------------------- /tools/instrument_compiler_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat $1 | sed "s/dfs.//g; s/DFSanPass.*$//g; s/[$]//g;" > $3 4 | cat $2 | sed "s/MemlogPass.*$//g;" > $4 5 | 6 | diff -u $3 $4 7 | -------------------------------------------------------------------------------- /tools/instrument_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | j=0 4 | for i in $1/* 5 | do 6 | echo $i 7 | $2 $i > /dev/null 2> log11 8 | cat log11 | grep 'hook1:' | sed "s/^.*\(hook1:.*\)/\1/g;" > file11 9 | $3 $i > /dev/null 2> log22 10 | cat log22 | grep 'hook1:' | sed "s/^.*\(hook1:.*\)/\1/g;" > file22 11 | DIFF=$(diff file11 file22) 12 | if [ "$DIFF" == "" ] 13 | then 14 | echo "No Difference" 15 | 16 | else 17 | echo "Bad" 18 | 19 | fi 20 | diff -u file11 file22 > "outfile1/outfile_${j}" 21 | j=$((j+1)) 22 | 23 | done 24 | #cat $1 | grep 'header: id' | sed "s/^.*\(id.*\'\)/\1/g;" > $3 25 | #cat $2 | grep 'header: id' | sed "s/^.*\(id.*\'\)/\1/g;" > $4 26 | 27 | #diff -u $3 $4 28 | -------------------------------------------------------------------------------- /tools/instrument_debug_single.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | cat $1 | grep 'hook1:' | sed "s/^.*\(hook1:.*\)/\1/g;" > $3 6 | cat $2 | grep 'hook1:' | sed "s/^.*\(hook1:.*\)/\1/g;" > $4 7 | 8 | diff -u $3 $4 9 | --------------------------------------------------------------------------------