├── .github └── workflows │ └── test.yml ├── .gitignore ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── README.md ├── backend ├── CMakeLists.txt └── fastgen.cpp ├── compiler ├── CMakeLists.txt └── ko_clang.c ├── driver ├── CMakeLists.txt ├── aflpp │ ├── CMakeLists.txt │ ├── README.md │ ├── rgd.proto │ └── symsan.cpp ├── fgtest.cpp ├── harness-proxy.c └── launcher │ ├── CMakeLists.txt │ └── launch.c ├── include ├── alloc_inl.h ├── ast.h ├── cov.h ├── debug.h ├── defs.h ├── launch.h ├── parse-rgd.h ├── parse-z3.h ├── parse.h ├── solver.h ├── task.h ├── task_mgr.h ├── union_find.h └── version.h ├── instrumentation ├── CMakeLists.txt └── TaintPass.cpp ├── libcxx ├── CMakeLists.txt ├── build_taint │ └── lib │ │ ├── libc++.a │ │ ├── libc++abi.a │ │ └── libunwind.a └── rebuild.sh ├── parsers ├── CMakeLists.txt └── rgd-parser.cpp ├── python ├── CMakeLists.txt ├── README.md ├── symsan-py.cpp └── test.py ├── runtime ├── CMakeLists.txt ├── cmake │ ├── AddCompilerRT.cmake │ ├── BuiltinTests.cmake │ ├── CompilerRTCompile.cmake │ ├── CompilerRTDarwinUtils.cmake │ ├── CompilerRTLink.cmake │ ├── CompilerRTUtils.cmake │ ├── CustomLibcxx │ │ └── CMakeLists.txt │ ├── HandleCompilerRT.cmake │ └── SanitizerUtils.cmake ├── common_interface_defs.h ├── dfsan │ ├── .clang-format │ ├── CMakeLists.txt │ ├── dfsan.cpp │ ├── dfsan.h │ ├── dfsan.syms.extra │ ├── dfsan_custom.cpp │ ├── dfsan_flags.inc │ ├── dfsan_interceptors.cpp │ ├── dfsan_platform.h │ ├── done_abilist.txt │ ├── libc++_abilist.txt │ ├── libc_ubuntu1404_abilist.txt │ ├── libc_ubuntu1804_abilist.txt │ ├── libc_ubuntu2204_abilist.txt │ ├── libc_ubuntu2404_abilist.txt │ ├── scripts │ │ ├── build-libc-list.py │ │ └── check_custom_wrappers.sh │ ├── taint.ld │ ├── taint_allocator.cpp │ ├── taint_allocator.h │ ├── union_hashtable.cpp │ ├── union_hashtable.h │ ├── union_util.cpp │ └── union_util.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 ├── libclang_rt.dfsan-x86_64.a.syms └── sanitizer_common │ ├── .clang-format │ ├── 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_dlsym.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_chained_origin_depot.cpp │ ├── sanitizer_chained_origin_depot.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_riscv64.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_dense_map.h │ ├── sanitizer_dense_map_info.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_flat_map.h │ ├── 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_leb128.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_lzw.h │ ├── sanitizer_mac.cpp │ ├── sanitizer_mac.h │ ├── sanitizer_mac_libcdep.cpp │ ├── sanitizer_malloc_mac.inc │ ├── sanitizer_mutex.cpp │ ├── 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_stack_store.cpp │ ├── sanitizer_stack_store.h │ ├── 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_fuchsia.h │ ├── sanitizer_stoptheworld_linux_libcdep.cpp │ ├── sanitizer_stoptheworld_mac.cpp │ ├── sanitizer_stoptheworld_netbsd_libcdep.cpp │ ├── sanitizer_stoptheworld_win.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_hexagon.inc │ ├── sanitizer_syscall_linux_riscv64.inc │ ├── sanitizer_syscall_linux_x86_64.inc │ ├── sanitizer_syscalls_netbsd.inc │ ├── sanitizer_termination.cpp │ ├── sanitizer_thread_registry.cpp │ ├── sanitizer_thread_registry.h │ ├── sanitizer_thread_safety.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_addrhashmap_test.cpp │ ├── sanitizer_allocator_test.cpp │ ├── sanitizer_allocator_testlib.cpp │ ├── sanitizer_atomic_test.cpp │ ├── sanitizer_bitvector_test.cpp │ ├── sanitizer_bvgraph_test.cpp │ ├── sanitizer_chained_origin_depot_test.cpp │ ├── sanitizer_common_test.cpp │ ├── sanitizer_deadlock_detector_test.cpp │ ├── sanitizer_dense_map_test.cpp │ ├── sanitizer_flags_test.cpp │ ├── sanitizer_flat_map_test.cpp │ ├── sanitizer_format_interceptor_test.cpp │ ├── sanitizer_hash_test.cpp │ ├── sanitizer_ioctl_test.cpp │ ├── sanitizer_leb128_test.cpp │ ├── sanitizer_libc_test.cpp │ ├── sanitizer_linux_test.cpp │ ├── sanitizer_list_test.cpp │ ├── sanitizer_lzw_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_stack_store_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 ├── solvers ├── CMakeLists.txt ├── i2s-solver.cpp ├── jigsaw │ ├── CMakeLists.txt │ ├── config.h │ ├── gd.cc │ ├── grad.cc │ ├── grad.h │ ├── input.cc │ ├── input.h │ ├── jit.cc │ ├── jit.h │ └── rgdJit.h ├── jit-solver.cpp ├── wheels │ ├── concurrentqueue │ │ └── queue.h │ ├── lockfreehash │ │ ├── cuckoo │ │ │ ├── Makefile │ │ │ ├── benchmark_lockfree_ht.h │ │ │ ├── benchmark_unordered_map.h │ │ │ ├── cycle_timer.h │ │ │ ├── hash_table.h │ │ │ ├── lockfree_hash_table.cpp │ │ │ ├── lockfree_hash_table.h │ │ │ ├── main.cpp │ │ │ └── thread_service.h │ │ └── lprobe │ │ │ ├── Makefile │ │ │ ├── alloc.h │ │ │ ├── benchmark_lprobe.h │ │ │ ├── benchmark_lprobe_ptr.h │ │ │ ├── block_allocator.h │ │ │ ├── concurrent_stack.h │ │ │ ├── cycle_timer.h │ │ │ ├── data.h │ │ │ ├── data_ptr.h │ │ │ ├── get_time.h │ │ │ ├── hash_table.h │ │ │ ├── main.cc │ │ │ ├── memory_size.h │ │ │ ├── monoid.h │ │ │ ├── parallel.h │ │ │ ├── seq.h │ │ │ ├── sequence_ops.h │ │ │ ├── thread_service.h │ │ │ ├── thread_service_ptr.h │ │ │ └── utilities.h │ └── threadpool │ │ ├── ThreadPool.h │ │ ├── ctpl.h │ │ └── threadpool_example.cpp ├── z3-solver.cpp ├── z3-ts.cpp └── z3.cpp ├── tests ├── CMakeLists.txt ├── aggregate.c ├── atomicrmw.c ├── bitflip.c ├── bool.c ├── boundary.c ├── boundary2.c ├── boundary3.c ├── boundary4.c ├── boundary5.c ├── boundary6.c ├── boundary7.c ├── bounds.cpp ├── call_fn.c ├── call_fn2.c ├── call_fn3.c ├── cf1.c ├── context.c ├── cpp_fstream.cpp ├── cpp_map.cpp ├── cpp_string.cpp ├── gep.c ├── if_eq.c ├── infer_type.c ├── lib.h ├── lit.cfg ├── lit.site.cfg.in ├── memcmp.c ├── mini.c ├── mini2.c ├── optimistic.c ├── partial_concrete.c ├── partial_concrete2.c ├── partial_concrete3.c ├── pointer.c ├── shift_and.c ├── sign.c ├── strcmp.c ├── strcmp2.c ├── struct.c ├── switch.c ├── ubsan_div.c ├── ubsan_intovfl.c ├── ubsan_shift.c ├── ubsan_trunc.c ├── unaligned_load.c └── xor_bool.c └── wrappers ├── CMakeLists.txt └── zlib_abilist.txt /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | branches: [ main ] 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - '!README.md' 11 | 12 | 13 | jobs: 14 | build-and-test: 15 | runs-on: ubuntu-24.04 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: install dependencies 21 | run: sudo apt-get update && sudo apt-get install -y llvm-14 clang-14 libc++-14-dev libc++abi-14-dev python3-minimal libz3-dev libgoogle-perftools-dev libboost-container-dev python3-dev 22 | # run: | 23 | # wget https://apt.llvm.org/llvm.sh 24 | # chmod +x llvm.sh 25 | # sudo ./llvm.sh 12 all 26 | 27 | - name: get aflpp 28 | uses: actions/checkout@v4 29 | with: 30 | repository: AFLplusplus/AFLplusplus 31 | path: ${{ github.workspace }}/aflpp 32 | 33 | - name: configure 34 | run: CC=clang-14 CXX=clang++-14 cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install -DAFLPP_PATH=${{ github.workspace }}/aflpp 35 | 36 | - name: build 37 | run: CC=clang-14 CXX=clang++-14 cmake --build ${{ github.workspace }}/build 38 | 39 | - name: install 40 | run: CC=clang-14 CXX=clang++-14 cmake --install ${{ github.workspace }}/build 41 | 42 | - name: install lit 43 | run: pip install lit 44 | 45 | - name: test 46 | run: lit --verbose tests 47 | working-directory: ${{ github.workspace }}/build 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.taint 3 | *.o 4 | *.so 5 | *.dwo 6 | *.bc 7 | *.ll 8 | GPATH 9 | GRTAGS 10 | GTAGS 11 | GSYMS 12 | output*/ 13 | *.tar.gz 14 | *.tar.xz 15 | auto/ 16 | /bin/ 17 | .DS_Store 18 | /build/ 19 | /libcxx/ 20 | !/libcxx/build_taint/lib/ 21 | /install 22 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(symsan VERSION 1.2.2 LANGUAGES C CXX ASM) 4 | 5 | find_package(LLVM 14 REQUIRED CONFIG) 6 | 7 | if (LLVM_FOUND) 8 | message(STATUS "LLVM_VERSION_MAJOR: ${LLVM_VERSION_MAJOR}") 9 | message(STATUS "LLVM_VERSION_MINOR: ${LLVM_VERSION_MINOR}") 10 | message(STATUS "LLVM_VERSION_PATCH: ${LLVM_VERSION_PATCH}") 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};" 22 | # INTERFACE_LINK_OPTIONS "-Wl,-znodelete" 23 | ) 24 | endif() 25 | 26 | include_directories(${LLVM_INCLUDE_DIRS}) 27 | add_definitions(${LLVM_DEFINITIONS}) 28 | 29 | include_directories(include) 30 | 31 | set(SYMSAN_BIN_DIR "bin") 32 | set(SYMSAN_LIB_DIR "lib/symsan") 33 | 34 | add_subdirectory(compiler) 35 | add_subdirectory(instrumentation) 36 | add_subdirectory(runtime) 37 | add_subdirectory(wrappers) 38 | add_subdirectory(parsers) 39 | add_subdirectory(solvers) 40 | add_subdirectory(backend) 41 | add_subdirectory(driver) 42 | add_subdirectory(tests) 43 | add_subdirectory(libcxx) 44 | add_subdirectory(python) 45 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:noble 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | ENV TZ=Etc/UTC 5 | 6 | ENV DEBIAN_FRONTEND=noninteractive 7 | ENV TZ=Etc/UTC 8 | 9 | WORKDIR /work 10 | COPY . /work/symsan 11 | 12 | RUN apt-get update 13 | RUN apt-get install -y cmake llvm-14 clang-14 libc++-14-dev libc++abi-14-dev libunwind-14-dev \ 14 | python3-minimal python-is-python3 zlib1g-dev git joe libprotobuf-dev 15 | RUN git clone --depth=1 --branch=v4.31c https://github.com/AFLplusplus/AFLplusplus /work/aflpp 16 | RUN cd /work/aflpp && make PERFORMANCE=1 LLVM_CONFIG=llvm-config-14 NO_NYX=1 source-only -j4 && make install 17 | 18 | RUN apt-get install -y libz3-dev libgoogle-perftools-dev libboost-container-dev python3-dev 19 | RUN apt clean 20 | 21 | RUN cd /work/symsan/ && mkdir -p build && \ 22 | cd build && CC=clang-14 CXX=clang++-14 cmake -DCMAKE_INSTALL_PREFIX=. -DAFLPP_PATH=/work/aflpp ../ && \ 23 | make -j4 && make install 24 | 25 | ENV KO_CC=clang-14 26 | ENV KO_CXX=clang++-14 27 | ENV KO_USE_FASTGEN=1 28 | -------------------------------------------------------------------------------- /backend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") 5 | 6 | add_library(Fastgen STATIC fastgen.cpp) 7 | target_compile_options(Fastgen PRIVATE -stdlib=libc++) 8 | target_include_directories(Fastgen PUBLIC 9 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 10 | ) 11 | install (TARGETS Fastgen DESTINATION ${SYMSAN_LIB_DIR}) 12 | -------------------------------------------------------------------------------- /compiler/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(KOClang ko_clang.c) 2 | set_target_properties(KOClang PROPERTIES OUTPUT_NAME "ko-clang") 3 | 4 | add_custom_command(TARGET KOClang POST_BUILD 5 | COMMAND ln -sf "ko-clang" "ko-clang++") 6 | install (TARGETS KOClang DESTINATION ${SYMSAN_BIN_DIR}) 7 | install (FILES ${CMAKE_CURRENT_BINARY_DIR}/ko-clang++ DESTINATION ${SYMSAN_BIN_DIR}) 8 | -------------------------------------------------------------------------------- /driver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | ## launcher lib 5 | add_subdirectory(launcher) 6 | 7 | ## simple driver for testing out-of-process solving 8 | add_executable(FGTest fgtest.cpp) 9 | set_target_properties(FGTest PROPERTIES OUTPUT_NAME "fgtest") 10 | target_include_directories(FGTest PUBLIC 11 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 12 | ) 13 | target_link_libraries(FGTest PRIVATE 14 | launcher 15 | z3parser 16 | z3 17 | rt 18 | ) 19 | install (TARGETS FGTest DESTINATION ${SYMSAN_BIN_DIR}) 20 | 21 | if (DEFINED AFLPP_PATH) 22 | add_subdirectory(aflpp) 23 | endif() 24 | 25 | install (CODE "MESSAGE(STATUS \"Build & Install: libSymsanProxy.o\")") 26 | install (CODE "execute_process(COMMAND \ 27 | ${CMAKE_INSTALL_PREFIX}/${SYMSAN_BIN_DIR}/ko-clang \ 28 | -c ${CMAKE_CURRENT_SOURCE_DIR}/harness-proxy.c \ 29 | -o ${CMAKE_INSTALL_PREFIX}/${SYMSAN_LIB_DIR}/libSymsanProxy.o)") 30 | -------------------------------------------------------------------------------- /driver/aflpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## custom_mutation for AFL++ 2 | 3 | project(SymSanMutator C CXX) 4 | 5 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 | set(CMAKE_CXX_STANDARD 17) 7 | 8 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -g -mcx16 -march=native -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free") 10 | if (ASAN_BUILD) 11 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") 12 | endif() 13 | 14 | if (NOT IS_DIRECTORY "${AFLPP_PATH}/include") 15 | message(FATAL_ERROR "Invalid AFL++ directory path! ${AFLPP_PATH}") 16 | endif() 17 | 18 | add_library(SymSanMutator SHARED symsan.cpp ) 19 | target_include_directories(SymSanMutator PRIVATE 20 | ${CMAKE_CURRENT_SOURCE_DIR}/../../runtime 21 | ${AFLPP_PATH}/include 22 | ) 23 | target_link_libraries(SymSanMutator 24 | launcher 25 | rgd-parser 26 | rgd-solver 27 | ) 28 | if (ASAN_BUILD) 29 | target_link_libraries(SymSanMutator 30 | ${LLVM_BINARY_DIR}/lib/clang/12.0.1/lib/linux/libclang_rt.asan-x86_64.a 31 | ) 32 | endif() 33 | 34 | install (TARGETS SymSanMutator DESTINATION ${SYMSAN_BIN_DIR}) 35 | -------------------------------------------------------------------------------- /driver/aflpp/rgd.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package rgd; 4 | 5 | // AST node for symbolic expressions 6 | message AstNode { 7 | uint32 kind = 1; 8 | uint32 boolvalue = 2; //used by bool expr 9 | uint32 bits = 3; 10 | string value = 4; //used by constant expr 11 | repeated AstNode children = 5; 12 | string name = 6; //used for debugging 13 | uint32 index = 7; //used by read expr for index and extract expr 14 | uint32 label = 8; //for expression dedup 15 | uint32 hash = 9; //for node dedup 16 | uint32 direction = 10; 17 | uint32 sessionid = 11; 18 | uint32 full = 12; 19 | } 20 | -------------------------------------------------------------------------------- /driver/harness-proxy.c: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); 23 | 24 | int main(int argc, char* argv[]) { 25 | // open file 26 | int fd = open(argv[1], O_RDONLY); 27 | if (fd < 0) { 28 | perror("open"); 29 | return 1; 30 | } 31 | // get file size 32 | struct stat st; 33 | if (fstat(fd, &st) < 0) { 34 | perror("fstat"); 35 | close(fd); 36 | return 1; 37 | } 38 | size_t fsize = st.st_size; 39 | 40 | // read file contents 41 | char *string = (char*)malloc(fsize); 42 | if (read(fd, string, fsize) != fsize) { 43 | perror("read"); 44 | close(fd); 45 | return 1; 46 | } 47 | close(fd); 48 | 49 | // Now call into the harness 50 | int retval = LLVMFuzzerTestOneInput((const uint8_t *)string, fsize); 51 | 52 | free(string); 53 | return retval; 54 | } 55 | -------------------------------------------------------------------------------- /driver/launcher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 14) 3 | 4 | add_library(launcher STATIC launch.c) 5 | -------------------------------------------------------------------------------- /include/cov.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace rgd { 10 | 11 | struct BranchContext { 12 | void *addr; 13 | bool direction; 14 | }; 15 | 16 | struct HybridBranchContext : public BranchContext { 17 | uint32_t id; 18 | }; 19 | 20 | struct ContextAwareBranchContext : public BranchContext { 21 | uint32_t context; 22 | }; 23 | 24 | struct LoopAwareBranchContext : public BranchContext { 25 | uint32_t loop_counter; 26 | }; 27 | 28 | struct HistoryAwareBranchContext : public BranchContext { 29 | uint32_t history; 30 | }; 31 | 32 | struct FullBranchContext : public HybridBranchContext, 33 | public ContextAwareBranchContext, 34 | public LoopAwareBranchContext, 35 | public HistoryAwareBranchContext { 36 | }; 37 | 38 | class CovManager { 39 | public: 40 | virtual ~CovManager() {} 41 | virtual const std::shared_ptr // don't want the saved context to be modified 42 | add_branch(void *addr, uint32_t id, bool direction, uint32_t context, bool is_loop_header, bool is_loop_exit) = 0; 43 | virtual bool 44 | is_branch_interesting(const std::shared_ptr context) = 0; 45 | }; 46 | 47 | class EdgeCovManager : public CovManager { 48 | private: 49 | using BranchTargets = std::pair; 50 | std::unordered_map branches; 51 | std::shared_ptr _ctx; 52 | 53 | public: 54 | EdgeCovManager() { _ctx = std::make_shared(); } 55 | 56 | const std::shared_ptr 57 | add_branch(void *addr, uint32_t id, bool direction, uint32_t context, bool is_loop_header, bool is_loop_exit) override { 58 | auto &itr = branches[addr]; 59 | itr.first |= direction? true : false; 60 | itr.second |= direction? false : true; 61 | _ctx->addr = addr; 62 | _ctx->direction = direction; 63 | return _ctx; 64 | } 65 | 66 | bool is_branch_interesting(const std::shared_ptr context) override { 67 | auto itr = branches.find(context->addr); 68 | // assert(itr != branches.end()); 69 | if (context->direction) { 70 | return itr->second.first == false; 71 | } else { 72 | return itr->second.second == false; 73 | } 74 | } 75 | }; 76 | 77 | }; // namespace rgd -------------------------------------------------------------------------------- /include/defs.h: -------------------------------------------------------------------------------- 1 | #ifndef _HAVE_DEFS_H 2 | #define _HAVE_DEFS_H 3 | 4 | #ifdef DEBUG_INFO 5 | // #define DEBUG_PRINTF printf 6 | #define DEBUG_PRINTF(...) \ 7 | do { \ 8 | printf(__VA_ARGS__); \ 9 | } while (0) 10 | #else 11 | #define DEBUG_PRINTF(...) \ 12 | do { \ 13 | } while (0) 14 | #endif 15 | 16 | #ifndef MIN 17 | #define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a)) 18 | #define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) 19 | #endif /* !MIN */ 20 | 21 | #ifndef RRR 22 | #define RRR(x) (random() % (x)) 23 | #endif 24 | 25 | #include 26 | #include 27 | 28 | typedef uint32_t dfsan_label; 29 | 30 | typedef uint8_t u8; 31 | typedef uint16_t u16; 32 | typedef uint32_t u32; 33 | #ifdef __x86_64__ 34 | typedef unsigned long long u64; 35 | typedef long long s64; 36 | #else 37 | typedef uint64_t u64; 38 | typedef int64_t s64; 39 | #endif 40 | typedef int8_t s8; 41 | typedef int16_t s16; 42 | typedef int32_t s32; 43 | 44 | #endif /* ! _HAVE_DEFS_H */ 45 | -------------------------------------------------------------------------------- /include/task_mgr.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "task.h" 4 | 5 | #include 6 | #include 7 | 8 | namespace rgd { 9 | 10 | class TaskManager { 11 | public: 12 | virtual ~TaskManager() {} 13 | virtual bool add_task(std::shared_ptr ctx, std::shared_ptr task) = 0; 14 | virtual std::shared_ptr get_next_task() = 0; 15 | virtual size_t get_num_tasks() = 0; 16 | }; 17 | 18 | class FIFOTaskManager : public TaskManager { 19 | public: 20 | bool add_task(std::shared_ptr ctx, std::shared_ptr task) override { 21 | (void)ctx; 22 | tasks.push_back(std::move(task)); 23 | return true; 24 | } 25 | 26 | std::shared_ptr get_next_task() override { 27 | if (tasks.empty()) return nullptr; 28 | auto task = std::move(tasks.front()); 29 | tasks.pop_front(); 30 | return task; 31 | } 32 | 33 | size_t get_num_tasks() override { 34 | return tasks.size(); 35 | } 36 | 37 | private: 38 | std::deque tasks; 39 | }; 40 | 41 | }; // namespace rgd 42 | -------------------------------------------------------------------------------- /include/union_find.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace rgd { 8 | 9 | // disjoint set data structure 10 | class UnionFind { 11 | public: 12 | static const size_t INVALID = (size_t)-1; 13 | 14 | UnionFind() : size_(0) {}; 15 | UnionFind(size_t size) { 16 | reset(size); 17 | }; 18 | 19 | void reset(size_t size) { 20 | size_ = size; 21 | parent.resize(size); 22 | next.resize(size); 23 | rank.resize(size); 24 | for (size_t i = 0; i < size; ++i) { 25 | parent[i] = i; 26 | next[i] = i; 27 | rank[i] = 0; 28 | } 29 | } 30 | 31 | // find the root of the set containing x 32 | size_t find(size_t x) { 33 | if (x >= size_) return INVALID; 34 | 35 | size_t p = parent[x]; 36 | while (x != p) { 37 | size_t gp = parent[p]; 38 | parent[x] = gp; 39 | x = p; 40 | p = gp; 41 | } 42 | return x; 43 | } 44 | 45 | // merge the sets containing x and y, return new root 46 | size_t merge(size_t x, size_t y) { 47 | if (x >= size_) return INVALID; 48 | if (y >= size_) return INVALID; 49 | 50 | size_t x_root = find(x); 51 | size_t y_root = find(y); 52 | if (x_root == y_root) return x_root; 53 | 54 | // merge link list 55 | size_t x_next = next[x_root]; 56 | next[x_root] = next[y_root]; 57 | next[y_root] = x_next; 58 | 59 | if (rank[x_root] < rank[y_root]) { 60 | parent[x_root] = y_root; 61 | return y_root; 62 | } else if (rank[x_root] > rank[y_root]) { 63 | parent[y_root] = x_root; 64 | return x_root; 65 | } else { 66 | parent[y_root] = x_root; 67 | rank[x_root]++; 68 | return x_root; 69 | } 70 | } 71 | 72 | // get the set containing x 73 | size_t get_set(size_t x, std::unordered_set &set) { 74 | if (x >= size_) return INVALID; 75 | size_t temp = x; 76 | set.clear(); 77 | set.insert(temp); 78 | while (next[temp] != x) { 79 | temp = next[temp]; 80 | set.insert(temp); 81 | } 82 | return set.size(); 83 | } 84 | 85 | private: 86 | size_t size_; 87 | std::vector parent; 88 | std::vector next; 89 | std::vector rank; 90 | }; 91 | 92 | }; -------------------------------------------------------------------------------- /include/version.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _ANGORA_LLVM_VERSION_H 3 | #define _ANGORA_LLVM_VERSION_H 4 | 5 | #define LLVM_VERSION(major, minor) ((major)*100 + (minor)) 6 | #define LLVM_VERSION_CODE LLVM_VERSION(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR) 7 | 8 | #if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0) 9 | #define LLVM_ATTRIBUTE_LIST AttributeList 10 | 11 | #define LLVM_NEW_ALLOCINST(ty, name, insertp) \ 12 | (new AllocaInst(ty, getDataLayout().getAllocaAddrSpace(), name, insertp)) 13 | 14 | #define LLVM_REMOVE_ATTRIBUTE(func, attr, attrbuilder) \ 15 | func->removeAttributes(attr, attrbuilder) 16 | 17 | #else 18 | 19 | #define LLVM_ATTRIBUTE_LIST AttributeSet 20 | 21 | #define LLVM_NEW_ALLOCINST(ty, name, insertp) \ 22 | (new AllocaInst(ty, name, insertp)) 23 | 24 | #define LLVM_REMOVE_ATTRIBUTE(func, attr, attrbuilder) \ 25 | func->removeAttributes( \ 26 | attr, LLVM_ATTRIBUTE_LIST::get(func->getContext(), attr, attrbuilder)) 27 | 28 | #endif 29 | 30 | #if LLVM_VERSION_CODE >= LLVM_VERSION(6, 0) 31 | 32 | #define SCL_INSECTION(scl, section, prefix, query, category) \ 33 | scl->inSection(section, prefix, query, category) 34 | 35 | #define LLVM_ADD_PARAM_ATTR(func, argno, attr) func->addParamAttr(argno, attr) 36 | 37 | #else 38 | 39 | #define SCL_INSECTION(scl, section, prefix, query, category) \ 40 | scl->inSection(prefix, query, category) 41 | 42 | #define LLVM_ADD_PARAM_ATTR(func, argno, attr) \ 43 | func->addAttribute(argno + 1, attr) 44 | 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /instrumentation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (CMAKE_CXX_STANDARD 14) 2 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") 3 | # fix pass bug: https://github.com/sampsyo/llvm-pass-skeleton/issues/7#issuecomment-401834287 4 | set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-znodelete") 5 | if(APPLE) 6 | # User teor2345 reports that this is required to make things work on MacOS X. 7 | set (CMAKE_MODULE_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -Wl,-flat_namespace -Wl,-undefined,suppress") 8 | endif(APPLE) 9 | 10 | include(AddLLVM) 11 | add_llvm_pass_plugin(TaintPass TaintPass.cpp) 12 | install (TARGETS TaintPass DESTINATION ${SYMSAN_LIB_DIR}) 13 | -------------------------------------------------------------------------------- /libcxx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # run rebuild.sh 2 | 3 | install (FILES "build_taint/lib/libc++.a" DESTINATION "${SYMSAN_LIB_DIR}") 4 | install (FILES "build_taint/lib/libc++abi.a" DESTINATION "${SYMSAN_LIB_DIR}") 5 | install (FILES "build_taint/lib/libunwind.a" DESTINATION "${SYMSAN_LIB_DIR}") 6 | 7 | -------------------------------------------------------------------------------- /libcxx/build_taint/lib/libc++.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/libcxx/build_taint/lib/libc++.a -------------------------------------------------------------------------------- /libcxx/build_taint/lib/libc++abi.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/libcxx/build_taint/lib/libc++abi.a -------------------------------------------------------------------------------- /libcxx/build_taint/lib/libunwind.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/libcxx/build_taint/lib/libunwind.a -------------------------------------------------------------------------------- /libcxx/rebuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # usage: rebuild.sh path_to_ko_clang 4 | 5 | if [[ $# -ne 1 ]]; then 6 | echo "Usage: ${0} path_to_ko_clang" 1>&2 7 | exit 1 8 | fi 9 | 10 | BIN_PATH=$(readlink -f "$0") 11 | ROOT_DIR=$(dirname $(dirname $(dirname $BIN_PATH))) 12 | CC=$(readlink -f "$1") 13 | CXX=${CC}++ 14 | 15 | if [ ! -x $CC ]; then 16 | echo "[-] Error: cannot find the C compiler 'ko_clang'" 1>&2 17 | exit 1 18 | fi 19 | 20 | if [ ! -h $CXX ]; then 21 | echo "[-] Error: cannot find the CXX compiler 'ko_clang++'" 1>&2 22 | exit 1 23 | fi 24 | 25 | LLVM_VERSION=14.0.6 26 | 27 | NINJA_B=`which ninja 2>/dev/null` 28 | 29 | if [ "$NINJA_B" = "" ]; then 30 | echo "[-] Error: can't find 'ninja' in your \$PATH. please install ninja-build" 1>&2 31 | echo "[-] Debian&Ubuntu: sudo apt-get install ninja-build" 1>&2 32 | exit 1 33 | fi 34 | 35 | set -euxo pipefail 36 | 37 | CUR_DIR=`pwd` 38 | LLVM_SRC="llvm_project" 39 | 40 | if [ ! -d $LLVM_SRC ]; then 41 | git clone --depth 1 --branch llvmorg-${LLVM_VERSION} https://github.com/llvm/llvm-project.git $LLVM_SRC 42 | fi 43 | 44 | mkdir -p build_taint 45 | rm -rf build_taint/* 46 | 47 | export KO_CONFIG=1 48 | export KO_CC=clang-14 49 | export KO_CXX=clang++-14 50 | cmake -G Ninja -S $LLVM_SRC/runtimes -B build_taint \ 51 | -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE=Release \ 52 | -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} \ 53 | -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ 54 | -DLIBCXXABI_ENABLE_SHARED=OFF -DLIBCXX_ENABLE_SHARED=OFF \ 55 | -DLIBCXX_CXX_ABI="libcxxabi" \ 56 | -DLIBCXXABI_USE_LLVM_UNWINDER=ON \ 57 | -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;unwind" 58 | 59 | unset KO_CONFIG 60 | ninja -C build_taint cxx cxxabi unwind 61 | 62 | -------------------------------------------------------------------------------- /parsers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | find_package(boost_container CONFIG) 5 | 6 | if (NOT boost_container_FOUND) 7 | message(FATAL_ERROR "Failed to locate Boost") 8 | endif() 9 | 10 | ## parser 11 | add_library(rgd-parser STATIC rgd-parser.cpp) 12 | target_include_directories(rgd-parser PRIVATE 13 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 14 | ${Boost_INCLUDE_DIRS} 15 | ) 16 | target_compile_options(rgd-parser PRIVATE 17 | -O3 -g -mcx16 -march=native -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free 18 | ) 19 | target_link_libraries(rgd-parser PRIVATE 20 | Boost::container 21 | ) 22 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | find_package(Python3 COMPONENTS Interpreter Development) 5 | 6 | if (Python3_Development_FOUND) 7 | message(STATUS "Python3_VERSION ${Python3_VERSION}") 8 | else() 9 | message(FATAL_ERROR "Cannot find Python development!") 10 | endif() 11 | 12 | add_library(pysymsan SHARED symsan-py.cpp) 13 | set_target_properties(pysymsan PROPERTIES PREFIX "") 14 | set_target_properties(pysymsan PROPERTIES OUTPUT_NAME "symsan") 15 | set_target_properties(pysymsan PROPERTIES SUFFIX ".cpython-${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}-x86_64-linux-gnu.so") 16 | target_include_directories(pysymsan PRIVATE 17 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 18 | ${Python3_INCLUDE_DIRS} 19 | ) 20 | target_link_libraries(pysymsan PRIVATE 21 | launcher 22 | z3parser 23 | z3 24 | ${Python3_LIBRARIES} 25 | rt 26 | ) 27 | install (TARGETS Fastgen DESTINATION ${SYMSAN_LIB_DIR}) 28 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | Provide a python binding to launch symsan-instrumented binary, receive events, parse constraints, and solve constraints. 2 | 3 | ``` 4 | static PyMethodDef SymSanMethods[] = { 5 | {"init", SymSanInit, METH_VARARGS, "initialize symsan target"}, 6 | {"config", (PyCFunction)SymSanConfig, METH_VARARGS | METH_KEYWORDS, "config symsan"}, 7 | {"run", (PyCFunction)SymSanRun, METH_VARARGS | METH_KEYWORDS, "run symsan target, optional stdin=file"}, 8 | {"read_event", SymSanReadEvent, METH_VARARGS, "read a symsan event"}, 9 | {"terminate", (PyCFunction)SymSanTerminate, METH_NOARGS, "terminate current symsan instance"}, 10 | {"destroy", (PyCFunction)SymSanDestroy, METH_NOARGS, "destroy symsan target"}, 11 | {"reset_input", InitParser, METH_VARARGS, "reset the symbolic expression parser with a new input"}, 12 | {"parse_cond", ParseCond, METH_VARARGS, "parse trace_cond event into solving tasks"}, 13 | {"parse_gep", ParseGEP, METH_VARARGS, "parse trace_gep event into solving tasks"}, 14 | {"add_constraint", AddConstraint, METH_VARARGS, "add a constraint"}, 15 | {"record_memcmp", RecordMemcmp, METH_VARARGS, "record a memcmp event"}, 16 | {"solve_task", SolveTask, METH_VARARGS, "solve a task"}, 17 | {NULL, NULL, 0, NULL} /* Sentinel */ 18 | }; 19 | ``` 20 | 21 | Currently only z3 solver is supported, will merge jigsaw and i2s later. 22 | -------------------------------------------------------------------------------- /python/test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import ctypes 3 | import symsan 4 | 5 | class pipe_msg(ctypes.Structure): 6 | _pack_ = 1 7 | _fields_ = [("type", ctypes.c_uint16), 8 | ("flags", ctypes.c_uint16), 9 | ("instance_id", ctypes.c_uint32), 10 | ("addr", ctypes.c_ulonglong), 11 | ("context", ctypes.c_uint32), 12 | ("id", ctypes.c_uint32), 13 | ("label", ctypes.c_uint32), 14 | ("result", ctypes.c_uint64)] 15 | 16 | class memcmp_msg(ctypes.Structure): 17 | _pack_ = 1 18 | _fields_ = [("label", ctypes.c_uint32)] 19 | content = bytes() 20 | 21 | prog = sys.argv[1] 22 | file = sys.argv[2] 23 | 24 | symsan.init(sys.argv[1]) 25 | symsan.config(file, args=[prog, file], debug=1, bounds=0) 26 | symsan.run() 27 | 28 | f = open(file, "rb") 29 | buf = f.read() 30 | symsan.reset_input([buf]) 31 | 32 | while True: 33 | e = symsan.read_event(ctypes.sizeof(pipe_msg)) 34 | if len(e) < ctypes.sizeof(pipe_msg): 35 | break 36 | msg = pipe_msg.from_buffer_copy(e) 37 | print(f"received msg: type={msg.type}, flags={msg.flags}, " 38 | f"addr={msg.addr:x}, context={msg.context}, cid={msg.id}, " 39 | f"label={msg.label}, result={msg.result}") 40 | 41 | tasks = [] 42 | if msg.type == 0: 43 | tasks = symsan.parse_cond(msg.label, msg.result, msg.flags) 44 | print(tasks) 45 | elif msg.type == 2 and msg.flags == 1: 46 | label = msg.label 47 | size = msg.result 48 | m = symsan.read_event(ctypes.sizeof(memcmp_msg) + size) 49 | if len(m) < ctypes.sizeof(memcmp_msg) + size: 50 | print("error reading memcmp msg") 51 | break 52 | buf = memcmp_msg.from_buffer_copy(m) 53 | if buf.label != label: 54 | print("error reading memcmp msg") 55 | break 56 | buf.content = m[ctypes.sizeof(memcmp_msg):] 57 | print(f"memcmp content: {buf.content.hex()}") 58 | symsan.record_memcmp(label, buf.content) 59 | 60 | for task in tasks: 61 | r, sol = symsan.solve_task(task) 62 | print(sol) 63 | 64 | status, is_killed = symsan.terminate() 65 | print(f"exit status {status}, killed? {is_killed}") 66 | 67 | symsan.destroy() 68 | 69 | -------------------------------------------------------------------------------- /runtime/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Add path for custom compiler-rt modules. 2 | list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 3 | 4 | set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH 5 | "Path where built compiler-rt libraries should be stored.") 6 | set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH 7 | "Path where built compiler-rt executables should be stored.") 8 | set(COMPILER_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") 9 | set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH 10 | "Path where built compiler-rt libraries should be installed.") 11 | 12 | set(COMPILER_RT_LIBRARY_OUTPUT_DIR ${COMPILER_RT_OUTPUT_DIR}) 13 | set(COMPILER_RT_LIBRARY_INSTALL_DIR ${SYMSAN_LIB_DIR}) 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 "-stdlib=libc++") 29 | list(APPEND SANITIZER_COMMON_CFLAGS -O3) 30 | list(APPEND SANITIZER_COMMON_CFLAGS -g) 31 | list(APPEND SANITIZER_COMMON_CFLAGS -fPIC) 32 | 33 | include(CheckIncludeFile) 34 | check_include_file(rpc/xdr.h HAVE_RPC_XDR_H) 35 | if (NOT HAVE_RPC_XDR_H) 36 | set(HAVE_RPC_XDR_H 0) 37 | endif() 38 | 39 | add_custom_target(compiler-rt ALL) 40 | add_custom_target(install-compiler-rt) 41 | add_custom_target(install-compiler-rt-stripped) 42 | 43 | set_property( 44 | TARGET 45 | compiler-rt 46 | install-compiler-rt 47 | install-compiler-rt-stripped 48 | PROPERTY 49 | FOLDER "Compiler-RT Misc" 50 | ) 51 | 52 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 53 | 54 | include(AddCompilerRT) 55 | include(SanitizerUtils) 56 | 57 | set(CMAKE_CXX_STANDARD 14) 58 | 59 | add_subdirectory(sanitizer_common) 60 | add_subdirectory(interception) 61 | add_subdirectory(dfsan) 62 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/cmake/CustomLibcxx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.3) 2 | project(custom-libcxx C CXX) 3 | 4 | message(STATUS "COMPILER_RT_LIBCXX_PATH = ${COMPILER_RT_LIBCXX_PATH}") 5 | 6 | # Build static libcxxabi. 7 | set(LIBCXXABI_STANDALONE_BUILD 1) 8 | set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") 9 | set(LIBCXXABI_ENABLE_EXCEPTIONS ON CACHE BOOL "") 10 | set(LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE STRING "") 11 | set(LIBCXXABI_LIBCXX_PATH ${COMPILER_RT_LIBCXX_PATH} CACHE PATH "") 12 | set(LIBCXXABI_INCLUDE_TESTS OFF CACHE BOOL "") 13 | add_subdirectory(${COMPILER_RT_LIBCXXABI_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxxabi) 14 | 15 | # Build static libcxx without exceptions. 16 | set(LIBCXX_STANDALONE_BUILD 1) 17 | set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE BOOL "") 18 | set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") 19 | set(LIBCXX_ENABLE_EXCEPTIONS ON CACHE BOOL "") 20 | set(LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "") 21 | 22 | # Use above libcxxabi. 23 | set(LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") 24 | set(LIBCXX_CXX_ABI_INTREE 1) 25 | set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") 26 | set(LIBCXX_CXX_ABI_INCLUDE_PATHS ${COMPILER_RT_LIBCXXABI_PATH}/include CACHE PATH "") 27 | 28 | add_subdirectory(${COMPILER_RT_LIBCXX_PATH} ${CMAKE_CURRENT_BINARY_DIR}/cxx) 29 | -------------------------------------------------------------------------------- /runtime/cmake/HandleCompilerRT.cmake: -------------------------------------------------------------------------------- 1 | function(find_compiler_rt_library name dest) 2 | set(dest "" PARENT_SCOPE) 3 | set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${SANITIZER_COMMON_CFLAGS} 4 | "--rtlib=compiler-rt" "--print-libgcc-file-name") 5 | if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) 6 | list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") 7 | endif() 8 | execute_process( 9 | COMMAND ${CLANG_COMMAND} 10 | RESULT_VARIABLE HAD_ERROR 11 | OUTPUT_VARIABLE LIBRARY_FILE 12 | ) 13 | string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) 14 | string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}") 15 | if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}") 16 | message(STATUS "Found compiler-rt ${name} library: ${LIBRARY_FILE}") 17 | set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE) 18 | else() 19 | message(STATUS "Failed to find compiler-rt ${name} library") 20 | endif() 21 | endfunction() 22 | -------------------------------------------------------------------------------- /runtime/dfsan/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | IndentPPDirectives: AfterHash 4 | -------------------------------------------------------------------------------- /runtime/dfsan/dfsan.syms.extra: -------------------------------------------------------------------------------- 1 | dfsan_* 2 | __dfsan_* 3 | __dfsw_* 4 | __taint_* 5 | -------------------------------------------------------------------------------- /runtime/dfsan/scripts/check_custom_wrappers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DFSAN_DIR=$(dirname "$0")/../ 4 | DFSAN_CUSTOM_TESTS=${DFSAN_DIR}/../../test/dfsan/custom.cc 5 | DFSAN_CUSTOM_WRAPPERS=${DFSAN_DIR}/dfsan_custom.cc 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 | -------------------------------------------------------------------------------- /runtime/dfsan/taint_allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "../sanitizer_common/sanitizer_atomic.h" 2 | #include "../sanitizer_common/sanitizer_common.h" 3 | #include "dfsan.h" 4 | #include "taint_allocator.h" 5 | 6 | using namespace __sanitizer; 7 | 8 | namespace __taint { 9 | 10 | static uptr begin_addr; 11 | static atomic_uint64_t next_usable_byte; 12 | static uptr end_addr; 13 | 14 | /** 15 | * Initialize allocator memory, 16 | * begin: first usable byte 17 | * end: first unusable byte 18 | */ 19 | 20 | void allocator_init(uptr begin, uptr end) { 21 | begin_addr = begin; 22 | atomic_store_relaxed(&next_usable_byte, begin); 23 | end_addr = end; 24 | } 25 | 26 | void *allocator_alloc(uptr size) { 27 | if (begin_addr == 0) { 28 | Report("FATAL: Allocator not initialized\n"); 29 | Die(); 30 | } 31 | uptr retval = atomic_fetch_add(&next_usable_byte, size, memory_order_relaxed); 32 | if (retval + size >= end_addr) { 33 | Report("FATAL: Allocate size exceeded\n"); 34 | Die(); 35 | } 36 | return reinterpret_cast(retval); 37 | } 38 | 39 | void 40 | allocator_dealloc(uptr addr) { 41 | // do nothing for now 42 | } 43 | 44 | } // namespace 45 | -------------------------------------------------------------------------------- /runtime/dfsan/taint_allocator.h: -------------------------------------------------------------------------------- 1 | #ifndef UNION_ALLOCATOR_H 2 | #define UNION_ALLOCATOR_H 3 | 4 | #include "sanitizer_common/sanitizer_internal_defs.h" 5 | 6 | using __sanitizer::uptr; 7 | 8 | namespace __taint { 9 | 10 | void allocator_init(uptr begin, uptr end); 11 | void *allocator_alloc(uptr size); 12 | void allocator_dealloc(uptr addr); 13 | 14 | } // namespace 15 | 16 | #endif // UNION_ALLOCATOR_H 17 | -------------------------------------------------------------------------------- /runtime/dfsan/union_hashtable.cpp: -------------------------------------------------------------------------------- 1 | #include "sanitizer_common/sanitizer_libc.h" 2 | #include "union_hashtable.h" 3 | #include "union_util.h" 4 | 5 | using namespace __taint; 6 | 7 | union_hashtable::union_hashtable(uint64_t n) { 8 | bucket_size = n; 9 | bucket = reinterpret_cast( 10 | allocator_alloc(n * sizeof(atomic_uintptr_t))); 11 | __sanitizer::internal_memset(bucket, 0, n * sizeof(atomic_uintptr_t)); 12 | } 13 | 14 | uint32_t 15 | union_hashtable::hash(const dfsan_label_info &key) { 16 | return key.hash & (bucket_size - 1); 17 | } 18 | 19 | void 20 | union_hashtable::insert(dfsan_label_info *key, dfsan_label entry) { 21 | uint32_t index = hash(*key); 22 | auto curr = (struct union_hashtable_entry *) 23 | allocator_alloc(sizeof(struct union_hashtable_entry)); 24 | curr->key = key; curr->entry = entry; 25 | uptr p = atomic_load(&bucket[index], memory_order_acquire); 26 | while (true) { 27 | curr->next = reinterpret_cast(p); 28 | if (atomic_compare_exchange_strong(&bucket[index], &p, (uptr)curr, 29 | memory_order_seq_cst)) 30 | break; // spin until succeed, when fail, p will contain the current head 31 | } 32 | } 33 | 34 | option 35 | union_hashtable::lookup(const dfsan_label_info &key) { 36 | uint64_t index = hash(key); 37 | uptr p = atomic_load(&bucket[index], memory_order_acquire); 38 | auto curr = reinterpret_cast(p); 39 | while (curr) { 40 | if (*(curr->key) == key) { 41 | return some_dfsan_label(curr->entry); 42 | } 43 | curr = curr->next; // no data race here 44 | } 45 | return none(); 46 | } 47 | -------------------------------------------------------------------------------- /runtime/dfsan/union_hashtable.h: -------------------------------------------------------------------------------- 1 | #ifndef UNION_HASHTABLE_H 2 | #define UNION_HASHTABLE_H 3 | 4 | #include 5 | #include "sanitizer_common/sanitizer_atomic.h" 6 | #include "sanitizer_common/sanitizer_internal_defs.h" 7 | #include "taint_allocator.h" 8 | #include "union_util.h" 9 | #include "dfsan.h" 10 | 11 | using __sanitizer::atomic_uintptr_t; 12 | using __sanitizer::atomic_load; 13 | using __sanitizer::atomic_compare_exchange_strong; 14 | using __sanitizer::memory_order_acquire; 15 | using __sanitizer::memory_order_seq_cst; 16 | 17 | namespace __taint { 18 | 19 | struct union_hashtable_entry { 20 | dfsan_label_info *key; 21 | dfsan_label entry; 22 | struct union_hashtable_entry *next; 23 | }; 24 | 25 | class union_hashtable { 26 | atomic_uintptr_t *bucket; 27 | uint64_t bucket_size; 28 | uint32_t hash(const dfsan_label_info &key); 29 | public: 30 | union_hashtable(uint64_t n); 31 | void insert(dfsan_label_info *key, dfsan_label value); 32 | option lookup(const dfsan_label_info &key); 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /runtime/dfsan/union_util.cpp: -------------------------------------------------------------------------------- 1 | #include "union_util.h" 2 | 3 | namespace __taint { 4 | 5 | /** 6 | * Initialize allocator memory, 7 | * begin: first usable byte 8 | * end: first unusable byte 9 | */ 10 | 11 | option::option(bool isa, dfsan_label l) { 12 | this->isa = isa; 13 | this->content = l; 14 | } 15 | 16 | option some_dfsan_label(dfsan_label x) { 17 | return option(true, x); 18 | } 19 | 20 | option none() { 21 | return option(false, 0); 22 | } 23 | 24 | bool 25 | option::operator==(option rhs) { 26 | if (isa == false) { 27 | return rhs.isa == false; 28 | } 29 | return rhs.isa != false && content == rhs.content; 30 | } 31 | 32 | bool 33 | option::operator!=(option rhs) { 34 | return !(*this == rhs); 35 | } 36 | 37 | dfsan_label 38 | option::operator*() { 39 | return this->content; 40 | } 41 | 42 | bool 43 | operator==(const dfsan_label_info& lhs, const dfsan_label_info& rhs) { 44 | return lhs.l1 == rhs.l1 45 | && lhs.l2 == rhs.l2 46 | && lhs.op == rhs.op 47 | && lhs.size == rhs.size 48 | && lhs.op1.i == rhs.op1.i 49 | && lhs.op2.i == rhs.op2.i; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /runtime/dfsan/union_util.h: -------------------------------------------------------------------------------- 1 | #ifndef UNION_UTIL_H 2 | #define UNION_UTIL_H 3 | 4 | #include "sanitizer_common/sanitizer_internal_defs.h" 5 | #include "dfsan.h" 6 | 7 | using __sanitizer::uptr; 8 | using __sanitizer::u32; 9 | 10 | namespace __taint { 11 | 12 | class option { 13 | bool isa; 14 | dfsan_label content; 15 | public: 16 | option(bool, dfsan_label); 17 | bool operator==(option rhs); 18 | bool operator!=(option rhs); 19 | dfsan_label operator*(); 20 | }; 21 | 22 | option some_dfsan_label(dfsan_label x); 23 | option none(); 24 | 25 | bool operator==(const dfsan_label_info& lhs, 26 | const dfsan_label_info& rhs); 27 | 28 | } // namespace 29 | 30 | #endif // UNION_UTIL_H 31 | -------------------------------------------------------------------------------- /runtime/interception/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | IndentPPDirectives: AfterHash 4 | -------------------------------------------------------------------------------- /runtime/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 | # Silence warnings in system headers with MSVC. 23 | if(NOT CLANG_CL) 24 | append_list_if(COMPILER_RT_HAS_EXTERNAL_FLAG "/experimental:external /external:W0 /external:anglebrackets" INTERCEPTION_CFLAGS) 25 | endif() 26 | 27 | add_compiler_rt_object_libraries(RTInterception 28 | OS ${SANITIZER_COMMON_SUPPORTED_OS} 29 | ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH} 30 | SOURCES ${INTERCEPTION_SOURCES} 31 | ADDITIONAL_HEADERS ${INTERCEPTION_HEADERS} 32 | CFLAGS ${INTERCEPTION_CFLAGS}) 33 | 34 | if(COMPILER_RT_INCLUDE_TESTS) 35 | add_subdirectory(tests) 36 | endif() 37 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/libclang_rt.dfsan-x86_64.a.syms: -------------------------------------------------------------------------------- 1 | { 2 | __dfsan_*; 3 | __dfsw_*; 4 | __interceptor_mmap; 5 | __interceptor_mmap64; 6 | __sanitizer_cov; 7 | __sanitizer_cov_dump; 8 | __sanitizer_cov_indir_call16; 9 | __sanitizer_cov_init; 10 | __sanitizer_cov_module_init; 11 | __sanitizer_cov_trace_basic_block; 12 | __sanitizer_cov_trace_cmp; 13 | __sanitizer_cov_trace_cmp1; 14 | __sanitizer_cov_trace_cmp2; 15 | __sanitizer_cov_trace_cmp4; 16 | __sanitizer_cov_trace_cmp8; 17 | __sanitizer_cov_trace_div4; 18 | __sanitizer_cov_trace_div8; 19 | __sanitizer_cov_trace_func_enter; 20 | __sanitizer_cov_trace_gep; 21 | __sanitizer_cov_trace_pc_guard; 22 | __sanitizer_cov_trace_pc_guard_init; 23 | __sanitizer_cov_trace_pc_indir; 24 | __sanitizer_cov_trace_switch; 25 | __sanitizer_cov_with_check; 26 | __sanitizer_get_coverage_guards; 27 | __sanitizer_get_number_of_counters; 28 | __sanitizer_get_total_unique_caller_callee_pairs; 29 | __sanitizer_get_total_unique_coverage; 30 | __sanitizer_install_malloc_and_free_hooks; 31 | __sanitizer_maybe_open_cov_file; 32 | __sanitizer_report_error_summary; 33 | __sanitizer_reset_coverage; 34 | __sanitizer_sandbox_on_notify; 35 | __sanitizer_set_death_callback; 36 | __sanitizer_set_report_fd; 37 | __sanitizer_set_report_path; 38 | __sanitizer_symbolize_global; 39 | __sanitizer_symbolize_pc; 40 | __sanitizer_update_counter_bitset_and_clear_counters; 41 | __taint_* 42 | dfsan_*; 43 | mmap; 44 | mmap64; 45 | }; 46 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowShortIfStatementsOnASingleLine: false 3 | IndentPPDirectives: AfterHash 4 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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, coverage information will be symbolized by sancov tool " 18 | "after dumping.") 19 | 20 | SANCOV_FLAG(bool, help, false, "Print flags help.") 21 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | void InternalAllocatorLock(); 52 | void InternalAllocatorUnlock(); 53 | InternalAllocator *internal_allocator(); 54 | 55 | } // namespace __sanitizer 56 | 57 | #endif // SANITIZER_ALLOCATOR_INTERNAL_H 58 | -------------------------------------------------------------------------------- /runtime/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 | void NORETURN ReportRssLimitExceeded(const StackTrace *stack); 37 | 38 | } // namespace __sanitizer 39 | 40 | #endif // SANITIZER_ALLOCATOR_REPORT_H 41 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_chained_origin_depot.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_chained_origin_depot.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 storage for chained origins. 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef SANITIZER_CHAINED_ORIGIN_DEPOT_H 13 | #define SANITIZER_CHAINED_ORIGIN_DEPOT_H 14 | 15 | #include "sanitizer_common.h" 16 | 17 | namespace __sanitizer { 18 | 19 | class ChainedOriginDepot { 20 | public: 21 | ChainedOriginDepot(); 22 | 23 | // Gets the statistic of the origin chain storage. 24 | StackDepotStats GetStats() const; 25 | 26 | // Stores a chain with StackDepot ID here_id and previous chain ID prev_id. 27 | // If successful, returns true and the new chain id new_id. 28 | // If the same element already exists, returns false and sets new_id to the 29 | // existing ID. 30 | bool Put(u32 here_id, u32 prev_id, u32 *new_id); 31 | 32 | // Retrieves the stored StackDepot ID for the given origin ID. 33 | u32 Get(u32 id, u32 *other); 34 | 35 | void LockAll(); 36 | void UnlockAll(); 37 | 38 | private: 39 | ChainedOriginDepot(const ChainedOriginDepot &) = delete; 40 | void operator=(const ChainedOriginDepot &) = delete; 41 | }; 42 | 43 | } // namespace __sanitizer 44 | 45 | #endif // SANITIZER_CHAINED_ORIGIN_DEPOT_H 46 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S: -------------------------------------------------------------------------------- 1 | #if defined(__aarch64__) && defined(__linux__) 2 | 3 | #include "sanitizer_common/sanitizer_asm.h" 4 | #include "builtins/assembly.h" 5 | 6 | ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) 7 | 8 | .comm _ZN14__interception10real_vforkE,8,8 9 | .globl ASM_WRAPPER_NAME(vfork) 10 | ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) 11 | ASM_WRAPPER_NAME(vfork): 12 | // Save x30 in the off-stack spill area. 13 | hint #25 // paciasp 14 | stp xzr, x30, [sp, #-16]! 15 | bl COMMON_INTERCEPTOR_SPILL_AREA 16 | ldp xzr, x30, [sp], 16 17 | str x30, [x0] 18 | 19 | // Call real vfork. This may return twice. User code that runs between the first and the second return 20 | // may clobber the stack frame of the interceptor; that's why it does not have a frame. 21 | adrp x0, _ZN14__interception10real_vforkE 22 | ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE] 23 | blr x0 24 | 25 | stp x0, xzr, [sp, #-16]! 26 | cmp x0, #0 27 | b.eq .L_exit 28 | 29 | // x0 != 0 => parent process. Clear stack shadow. 30 | add x0, sp, #16 31 | bl COMMON_INTERCEPTOR_HANDLE_VFORK 32 | 33 | .L_exit: 34 | // Restore x30. 35 | bl COMMON_INTERCEPTOR_SPILL_AREA 36 | ldr x30, [x0] 37 | ldp x0, xzr, [sp], 16 38 | hint #29 // autiasp 39 | 40 | ret 41 | ASM_SIZE(vfork) 42 | 43 | .weak vfork 44 | .set vfork, ASM_WRAPPER_NAME(vfork) 45 | 46 | GNU_PROPERTY_BTI_PAC 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | _CET_ENDBR 10 | // Store return address in the spill area and tear down the stack frame. 11 | sub $12, %esp 12 | call COMMON_INTERCEPTOR_SPILL_AREA 13 | mov 12(%esp), %ecx 14 | mov %ecx, (%eax) 15 | add $16, %esp 16 | 17 | call .L0$pb 18 | .L0$pb: 19 | pop %eax 20 | .Ltmp0: 21 | add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax 22 | call *_ZN14__interception10real_vforkE@GOTOFF(%eax) 23 | 24 | // Restore the stack frame. 25 | // 12(%esp) return address 26 | // 8(%esp) spill %ebx 27 | // 4(%esp) spill REAL(vfork) return value 28 | // (%esp) call frame (arg0) for __*_handle_vfork 29 | sub $16, %esp 30 | mov %ebx, 8(%esp) 31 | mov %eax, 4(%esp) 32 | 33 | // Form GOT address in %ebx. 34 | call .L1$pb 35 | .L1$pb: 36 | pop %ebx 37 | .Ltmp1: 38 | add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx 39 | 40 | // Restore original return address. 41 | call COMMON_INTERCEPTOR_SPILL_AREA 42 | mov (%eax), %ecx 43 | mov %ecx, 12(%esp) 44 | mov 4(%esp), %eax 45 | 46 | // Call handle_vfork in the parent process (%rax != 0). 47 | test %eax, %eax 48 | je .L_exit 49 | 50 | lea 16(%esp), %ecx 51 | mov %ecx, (%esp) 52 | call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT 53 | 54 | .L_exit: 55 | mov 4(%esp), %eax 56 | mov 8(%esp), %ebx 57 | add $12, %esp 58 | ret 59 | ASM_SIZE(vfork) 60 | 61 | .weak vfork 62 | .set vfork, ASM_WRAPPER_NAME(vfork) 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S: -------------------------------------------------------------------------------- 1 | #if (defined(__riscv) && (__riscv_xlen == 64)) && 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 ra in the off-stack spill area. 12 | // allocate space on stack 13 | addi sp, sp, -16 14 | // store ra value 15 | sd ra, 8(sp) 16 | call COMMON_INTERCEPTOR_SPILL_AREA 17 | // restore previous values from stack 18 | ld ra, 8(sp) 19 | // adjust stack 20 | addi sp, sp, 16 21 | // store ra by x10 22 | sd ra, 0(x10) 23 | 24 | // Call real vfork. This may return twice. User code that runs between the first and the second return 25 | // may clobber the stack frame of the interceptor; that's why it does not have a frame. 26 | la x10, _ZN14__interception10real_vforkE 27 | ld x10, 0(x10) 28 | jalr x10 29 | 30 | // adjust stack 31 | addi sp, sp, -16 32 | // store x10 by adjusted stack 33 | sd x10, 8(sp) 34 | // jump to exit label if x10 is 0 35 | beqz x10, .L_exit 36 | 37 | // x0 != 0 => parent process. Clear stack shadow. 38 | // put old sp to x10 39 | addi x10, sp, 16 40 | call COMMON_INTERCEPTOR_HANDLE_VFORK 41 | 42 | .L_exit: 43 | // Restore ra 44 | call COMMON_INTERCEPTOR_SPILL_AREA 45 | ld ra, 0(x10) 46 | // load value by stack 47 | ld x10, 8(sp) 48 | // adjust stack 49 | addi sp, sp, 16 50 | ret 51 | ASM_SIZE(vfork) 52 | 53 | .weak vfork 54 | .set vfork, ASM_WRAPPER_NAME(vfork) 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /runtime/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 | _CET_ENDBR 10 | // Store return address in the spill area and tear down the stack frame. 11 | push %rcx 12 | call COMMON_INTERCEPTOR_SPILL_AREA 13 | pop %rcx 14 | pop %rdi 15 | mov %rdi, (%rax) 16 | 17 | call *_ZN14__interception10real_vforkE(%rip) 18 | 19 | // Restore return address from the spill area. 20 | push %rcx 21 | push %rax 22 | call COMMON_INTERCEPTOR_SPILL_AREA 23 | mov (%rax), %rdx 24 | mov %rdx, 8(%rsp) 25 | mov (%rsp), %rax 26 | 27 | // Call handle_vfork in the parent process (%rax != 0). 28 | test %rax, %rax 29 | je .L_exit 30 | 31 | lea 16(%rsp), %rdi 32 | call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT 33 | 34 | .L_exit: 35 | pop %rax 36 | ret 37 | ASM_SIZE(vfork) 38 | 39 | .weak vfork 40 | .set vfork, ASM_WRAPPER_NAME(vfork) 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /runtime/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_get_report_path) 17 | INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container) 18 | INTERFACE_WEAK_FUNCTION(__sanitizer_on_print) 19 | INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary) 20 | INTERFACE_WEAK_FUNCTION(__sanitizer_sandbox_on_notify) 21 | // Sanitizer weak hooks 22 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_memcmp) 23 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strcmp) 24 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strncmp) 25 | INTERFACE_WEAK_FUNCTION(__sanitizer_weak_hook_strstr) 26 | // Stacktrace interface. 27 | INTERFACE_FUNCTION(__sanitizer_get_module_and_offset_for_pc) 28 | INTERFACE_FUNCTION(__sanitizer_symbolize_global) 29 | INTERFACE_FUNCTION(__sanitizer_symbolize_pc) 30 | // Allocator interface. 31 | INTERFACE_FUNCTION(__sanitizer_get_allocated_size) 32 | INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes) 33 | INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size) 34 | INTERFACE_FUNCTION(__sanitizer_get_free_bytes) 35 | INTERFACE_FUNCTION(__sanitizer_get_heap_size) 36 | INTERFACE_FUNCTION(__sanitizer_get_ownership) 37 | INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes) 38 | INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks) 39 | INTERFACE_FUNCTION(__sanitizer_purge_allocator) 40 | INTERFACE_FUNCTION(__sanitizer_print_memory_profile) 41 | INTERFACE_WEAK_FUNCTION(__sanitizer_free_hook) 42 | INTERFACE_WEAK_FUNCTION(__sanitizer_malloc_hook) 43 | -------------------------------------------------------------------------------- /runtime/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 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_set_demangle) 15 | INTERFACE_WEAK_FUNCTION(__sanitizer_symbolize_set_inline_frames) 16 | -------------------------------------------------------------------------------- /runtime/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_common.h" 14 | #include "sanitizer_flags.h" 15 | #include "sanitizer_libc.h" 16 | #include "sanitizer_platform.h" 17 | 18 | namespace __sanitizer { 19 | 20 | // The Windows implementations of these functions use the win32 API directly, 21 | // bypassing libc. 22 | #if !SANITIZER_WINDOWS 23 | #if SANITIZER_LINUX 24 | void LogMessageOnPrintf(const char *str) {} 25 | #endif 26 | void WriteToSyslog(const char *buffer) {} 27 | void Abort() { internal__exit(1); } 28 | bool CreateDir(const char *pathname) { return false; } 29 | #endif // !SANITIZER_WINDOWS 30 | 31 | #if !SANITIZER_WINDOWS && !SANITIZER_MAC 32 | void ListOfModules::init() {} 33 | void InitializePlatformCommonFlags(CommonFlags *cf) {} 34 | #endif 35 | 36 | } // namespace __sanitizer 37 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 27 | # define __errno_location __errno 28 | #elif SANITIZER_SOLARIS 29 | # define __errno_location ___errno 30 | #elif SANITIZER_WINDOWS 31 | # define __errno_location _errno 32 | #endif 33 | 34 | extern "C" int *__errno_location(); 35 | 36 | #define errno (*__errno_location()) 37 | 38 | #endif // SANITIZER_ERRNO_H 39 | -------------------------------------------------------------------------------- /runtime/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 | #define errno_ENAMETOOLONG 36 28 | 29 | // Those might not present or their value differ on different platforms. 30 | extern const int errno_EOWNERDEAD; 31 | 32 | } // namespace __sanitizer 33 | 34 | #endif // SANITIZER_ERRNO_CODES_H 35 | -------------------------------------------------------------------------------- /runtime/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 | void InitShadowBounds(); 34 | 35 | } // namespace __sanitizer 36 | 37 | #endif // SANITIZER_FUCHSIA 38 | #endif // SANITIZER_FUCHSIA_H 39 | -------------------------------------------------------------------------------- /runtime/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 | !SANITIZER_GO 27 | # define SANITIZER_USE_GETAUXVAL 1 28 | # else 29 | # define SANITIZER_USE_GETAUXVAL 0 30 | # endif 31 | 32 | # if SANITIZER_USE_GETAUXVAL 33 | # include 34 | # else 35 | // The weak getauxval definition allows to check for the function at runtime. 36 | // This is useful for Android, when compiled at a lower API level yet running 37 | // on a more recent platform that offers the function. 38 | extern "C" SANITIZER_WEAK_ATTRIBUTE unsigned long getauxval(unsigned long type); 39 | # endif 40 | 41 | #elif SANITIZER_NETBSD 42 | 43 | #define SANITIZER_USE_GETAUXVAL 1 44 | 45 | #include 46 | #include 47 | 48 | static inline decltype(AuxInfo::a_v) getauxval(decltype(AuxInfo::a_type) type) { 49 | for (const AuxInfo *aux = (const AuxInfo *)_dlauxinfo(); 50 | aux->a_type != AT_NULL; ++aux) { 51 | if (type == aux->a_type) 52 | return aux->a_v; 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | #endif 59 | 60 | #endif // SANITIZER_GETAUXVAL_H 61 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | 42 | class MurMur2Hash64Builder { 43 | static const u64 m = 0xc6a4a7935bd1e995ull; 44 | static const u64 seed = 0x9747b28c9747b28cull; 45 | static const u64 r = 47; 46 | u64 h; 47 | 48 | public: 49 | explicit MurMur2Hash64Builder(u64 init = 0) { h = seed ^ (init * m); } 50 | void add(u64 k) { 51 | k *= m; 52 | k ^= k >> r; 53 | k *= m; 54 | h ^= k; 55 | h *= m; 56 | } 57 | u64 get() { 58 | u64 x = h; 59 | x ^= x >> r; 60 | x *= m; 61 | x ^= x >> r; 62 | return x; 63 | } 64 | }; 65 | } //namespace __sanitizer 66 | 67 | #endif // SANITIZER_HASH_H 68 | -------------------------------------------------------------------------------- /runtime/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 | bool operator<(const VersionType &other) const { return !(*this >= other); } 48 | }; 49 | 50 | struct MacosVersion : VersionBase { 51 | MacosVersion(u16 major, u16 minor) : VersionBase(major, minor) {} 52 | }; 53 | 54 | struct DarwinKernelVersion : VersionBase { 55 | DarwinKernelVersion(u16 major, u16 minor) : VersionBase(major, minor) {} 56 | }; 57 | 58 | MacosVersion GetMacosAlignedVersion(); 59 | DarwinKernelVersion GetDarwinKernelVersion(); 60 | 61 | char **GetEnviron(); 62 | 63 | void RestrictMemoryToMaxAddress(uptr max_address); 64 | 65 | } // namespace __sanitizer 66 | 67 | #endif // SANITIZER_MAC 68 | #endif // SANITIZER_MAC_H 69 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_openbsd.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/runtime/sanitizer_common/sanitizer_openbsd.cpp -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_platform_limits_openbsd.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/runtime/sanitizer_common/sanitizer_platform_limits_openbsd.cpp -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_platform_limits_openbsd.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/R-Fuzz/symsan/47910b83ce55bb435f6d39c99938a5a106bafd10/runtime/sanitizer_common/sanitizer_platform_limits_openbsd.h -------------------------------------------------------------------------------- /runtime/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 | #elif defined(__ARM_FEATURE_PAC_DEFAULT) && !defined(__APPLE__) 15 | inline unsigned long ptrauth_strip(void* __value, unsigned int __key) { 16 | // On the stack the link register is protected with Pointer 17 | // Authentication Code when compiled with -mbranch-protection. 18 | // Let's stripping the PAC unconditionally because xpaclri is in 19 | // the NOP space so will do nothing when it is not enabled or not available. 20 | unsigned long ret; 21 | asm volatile( 22 | "mov x30, %1\n\t" 23 | "hint #7\n\t" // xpaclri 24 | "mov %0, x30\n\t" 25 | : "=r"(ret) 26 | : "r"(__value) 27 | : "x30"); 28 | return ret; 29 | } 30 | #define ptrauth_auth_data(__value, __old_key, __old_data) __value 31 | #define ptrauth_string_discriminator(__string) ((int)0) 32 | #else 33 | // Copied from 34 | #define ptrauth_strip(__value, __key) __value 35 | #define ptrauth_auth_data(__value, __old_key, __old_data) __value 36 | #define ptrauth_string_discriminator(__string) ((int)0) 37 | #endif 38 | 39 | #define STRIP_PAC_PC(pc) ((uptr)ptrauth_strip(pc, 0)) 40 | 41 | #endif // SANITIZER_PTRAUTH_H 42 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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_ = nullptr; 26 | u32 id_ = 0; 27 | StackDepotHandle(StackDepotNode *node, u32 id) : node_(node), id_(id) {} 28 | bool valid() const { return node_; } 29 | u32 id() const { return id_; } 30 | int use_count() const; 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 | void StackDepotPrintAll(); 45 | void StackDepotStopBackgroundThread(); 46 | 47 | void StackDepotTestOnlyUnmap(); 48 | 49 | } // namespace __sanitizer 50 | 51 | #endif // SANITIZER_STACKDEPOT_H 52 | -------------------------------------------------------------------------------- /runtime/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 | #include "sanitizer_stoptheworld_fuchsia.h" 21 | 22 | namespace __sanitizer { 23 | 24 | // The Fuchsia implementation stops the world but doesn't offer a real 25 | // SuspendedThreadsList argument. This is enough for ASan's use case, 26 | // and LSan does not use this API on Fuchsia. 27 | void StopTheWorld(StopTheWorldCallback callback, void *argument) { 28 | struct Params { 29 | StopTheWorldCallback callback; 30 | void *argument; 31 | } params = {callback, argument}; 32 | __sanitizer_memory_snapshot( 33 | nullptr, nullptr, nullptr, nullptr, 34 | [](zx_status_t, void *data) { 35 | auto params = reinterpret_cast(data); 36 | params->callback(SuspendedThreadsListFuchsia(), params->argument); 37 | }, 38 | ¶ms); 39 | } 40 | 41 | } // namespace __sanitizer 42 | 43 | #endif // SANITIZER_FUCHSIA 44 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_stoptheworld_fuchsia.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_stoptheworld_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 | #ifndef SANITIZER_STOPTHEWORLD_FUCHSIA_H 10 | #define SANITIZER_STOPTHEWORLD_FUCHSIA_H 11 | 12 | #include "sanitizer_stoptheworld.h" 13 | 14 | namespace __sanitizer { 15 | 16 | class SuspendedThreadsListFuchsia final : public SuspendedThreadsList {}; 17 | 18 | } // namespace __sanitizer 19 | 20 | #endif // SANITIZER_STOPTHEWORLD_FUCHSIA_H 21 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 final : 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 | -------------------------------------------------------------------------------- /runtime/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 final : 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 final : 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 | 39 | private: 40 | AtosSymbolizerProcess *process_; 41 | }; 42 | 43 | } // namespace __sanitizer 44 | 45 | #endif // SANITIZER_MAC 46 | 47 | #endif // SANITIZER_SYMBOLIZER_MAC_H 48 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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_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 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/sanitizer_thread_safety.h: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_thread_safety.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 sanitizer tools. 10 | // 11 | // Wrappers around thread safety annotations. 12 | // https://clang.llvm.org/docs/ThreadSafetyAnalysis.html 13 | //===----------------------------------------------------------------------===// 14 | 15 | #ifndef SANITIZER_THREAD_SAFETY_H 16 | #define SANITIZER_THREAD_SAFETY_H 17 | 18 | #if defined(__clang__) 19 | # define SANITIZER_THREAD_ANNOTATION(x) __attribute__((x)) 20 | #else 21 | # define SANITIZER_THREAD_ANNOTATION(x) 22 | #endif 23 | 24 | #define SANITIZER_MUTEX SANITIZER_THREAD_ANNOTATION(capability("mutex")) 25 | #define SANITIZER_SCOPED_LOCK SANITIZER_THREAD_ANNOTATION(scoped_lockable) 26 | #define SANITIZER_GUARDED_BY(x) SANITIZER_THREAD_ANNOTATION(guarded_by(x)) 27 | #define SANITIZER_PT_GUARDED_BY(x) SANITIZER_THREAD_ANNOTATION(pt_guarded_by(x)) 28 | #define SANITIZER_REQUIRES(...) \ 29 | SANITIZER_THREAD_ANNOTATION(requires_capability(__VA_ARGS__)) 30 | #define SANITIZER_REQUIRES_SHARED(...) \ 31 | SANITIZER_THREAD_ANNOTATION(requires_shared_capability(__VA_ARGS__)) 32 | #define SANITIZER_ACQUIRE(...) \ 33 | SANITIZER_THREAD_ANNOTATION(acquire_capability(__VA_ARGS__)) 34 | #define SANITIZER_ACQUIRE_SHARED(...) \ 35 | SANITIZER_THREAD_ANNOTATION(acquire_shared_capability(__VA_ARGS__)) 36 | #define SANITIZER_TRY_ACQUIRE(...) \ 37 | SANITIZER_THREAD_ANNOTATION(try_acquire_capability(__VA_ARGS__)) 38 | #define SANITIZER_RELEASE(...) \ 39 | SANITIZER_THREAD_ANNOTATION(release_capability(__VA_ARGS__)) 40 | #define SANITIZER_RELEASE_SHARED(...) \ 41 | SANITIZER_THREAD_ANNOTATION(release_shared_capability(__VA_ARGS__)) 42 | #define SANITIZER_EXCLUDES(...) \ 43 | SANITIZER_THREAD_ANNOTATION(locks_excluded(__VA_ARGS__)) 44 | #define SANITIZER_CHECK_LOCKED(...) \ 45 | SANITIZER_THREAD_ANNOTATION(assert_capability(__VA_ARGS__)) 46 | #define SANITIZER_NO_THREAD_SAFETY_ANALYSIS \ 47 | SANITIZER_THREAD_ANNOTATION(no_thread_safety_analysis) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | from io import open 14 | 15 | # Compile regex once for all files 16 | runRegex = re.compile(r'(? 0: 73 | sys.exit(1) 74 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/scripts/litlint_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env 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 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/symbolizer/scripts/ar_to_bc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env 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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/tests/sanitizer_addrhashmap_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_addrhashmap_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 | #include "sanitizer_common/sanitizer_addrhashmap.h" 9 | 10 | #include 11 | 12 | #include "gtest/gtest.h" 13 | 14 | namespace __sanitizer { 15 | 16 | struct Value { 17 | int payload; 18 | inline bool operator==(const Value& rhs) const { 19 | return payload == rhs.payload; 20 | } 21 | }; 22 | 23 | using MapTy = AddrHashMap; 24 | using HandleTy = MapTy::Handle; 25 | using RefMapTy = std::unordered_map; 26 | 27 | static void ExistsInReferenceMap(const uptr key, const Value& val, void* arg) { 28 | RefMapTy* ref = reinterpret_cast(arg); 29 | const RefMapTy::iterator iter = ref->find(key); 30 | ASSERT_NE(iter, ref->end()); 31 | EXPECT_EQ(iter->second, val); 32 | ref->erase(iter); 33 | } 34 | 35 | TEST(AddrHashMap, Basic) { 36 | // Use a reference implementation to compare with. 37 | RefMapTy reference_map{ 38 | {0x1000, {1}}, 39 | {0x2000, {2}}, 40 | {0x3000, {3}}, 41 | }; 42 | 43 | MapTy m; 44 | 45 | for (const auto& key_val : reference_map) { 46 | const uptr key = key_val.first; 47 | const Value val = key_val.second; 48 | 49 | // Insert all the elements. 50 | { 51 | HandleTy h(&m, key); 52 | ASSERT_TRUE(h.created()); 53 | h->payload = val.payload; 54 | } 55 | } 56 | 57 | // Now check that all the elements are present. 58 | m.ForEach(ExistsInReferenceMap, &reference_map); 59 | EXPECT_TRUE(reference_map.empty()); 60 | } 61 | 62 | } // namespace __sanitizer 63 | -------------------------------------------------------------------------------- /runtime/sanitizer_common/tests/sanitizer_hash_test.cpp: -------------------------------------------------------------------------------- 1 | //===-- sanitizer_hash_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 Sanitizers. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | #include "sanitizer_common/sanitizer_hash.h" 13 | 14 | #include "gtest/gtest.h" 15 | 16 | namespace __sanitizer { 17 | 18 | // Tests matche a few hashes generated by https://github.com/aappleby/smhasher. 19 | 20 | TEST(SanitizerCommon, Hash32Seed) { 21 | EXPECT_EQ(MurMur2HashBuilder(0).get(), 275646681u); 22 | EXPECT_EQ(MurMur2HashBuilder(1).get(), 3030210376u); 23 | EXPECT_EQ(MurMur2HashBuilder(3).get(), 1816185114u); 24 | } 25 | 26 | TEST(SanitizerCommon, Hash32Add) { 27 | MurMur2HashBuilder h(123 * sizeof(u32)); 28 | for (u32 i = 0; i < 123; ++i) h.add(i); 29 | EXPECT_EQ(h.get(), 351963665u); 30 | for (u32 i = 0; i < 123; ++i) h.add(-i); 31 | EXPECT_EQ(h.get(), 2640061027u); 32 | } 33 | 34 | TEST(SanitizerCommon, Hash64Seed) { 35 | EXPECT_EQ(MurMur2Hash64Builder(0).get(), 4469829599815726255ull); 36 | EXPECT_EQ(MurMur2Hash64Builder(1).get(), 14121968454562043709ull); 37 | EXPECT_EQ(MurMur2Hash64Builder(3).get(), 8040757559320203998ull); 38 | } 39 | 40 | TEST(SanitizerCommon, Hash64Add) { 41 | MurMur2Hash64Builder h(123 * sizeof(u64)); 42 | for (u32 i = 0; i < 123; ++i) h.add(i); 43 | EXPECT_EQ(h.get(), 11366430808886012537ull); 44 | for (u32 i = 0; i < 123; ++i) h.add(-i); 45 | EXPECT_EQ(h.get(), 10843188204560467446ull); 46 | } 47 | 48 | } // namespace __sanitizer 49 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | -------------------------------------------------------------------------------- /runtime/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 | ___sanitizer_symbolize_set_demangle 10 | ___sanitizer_symbolize_set_inline_frames 11 | -------------------------------------------------------------------------------- /solvers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | set(CMAKE_CXX_STANDARD 17) 3 | 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") 5 | 6 | ## solvers 7 | add_library(Z3Solver STATIC z3.cpp z3-ts.cpp) 8 | target_compile_options(Z3Solver PRIVATE -stdlib=libc++) 9 | target_include_directories(Z3Solver PUBLIC 10 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 11 | ) 12 | install (TARGETS Z3Solver DESTINATION ${SYMSAN_LIB_DIR}) 13 | 14 | add_library(z3parser STATIC z3-ts.cpp) 15 | target_include_directories(z3parser PRIVATE 16 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 17 | ) 18 | 19 | if (NOT LLVM_FOUND) 20 | message(FATAL_ERROR "You haven't install LLVM !") 21 | endif() 22 | 23 | ## rgd-solver 24 | 25 | add_subdirectory(jigsaw) 26 | 27 | add_library(rgd-solver STATIC 28 | z3-solver.cpp 29 | jit-solver.cpp 30 | i2s-solver.cpp 31 | ) 32 | 33 | target_compile_options(rgd-solver PRIVATE 34 | -O3 -g -mcx16 -march=native -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free 35 | ) 36 | if (ASAN_BUILD) 37 | target_compile_options(rgd-solver PRIVATE -fsanitize=address) 38 | endif() 39 | 40 | target_include_directories(rgd-solver PRIVATE 41 | ${CMAKE_CURRENT_SOURCE_DIR} 42 | ${CMAKE_CURRENT_SOURCE_DIR}/../runtime 43 | ) 44 | 45 | target_link_libraries(rgd-solver PRIVATE 46 | tcmalloc 47 | z3 48 | jigsaw 49 | profiler 50 | ) 51 | -------------------------------------------------------------------------------- /solvers/jigsaw/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5.1) 2 | 3 | project(jigsaw CXX) 4 | 5 | set(CMAKE_CXX_STANDARD 17) 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -g -mcx16 -march=native -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free") 7 | if (ASAN_BUILD) 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") 9 | endif() 10 | 11 | add_library(jigsaw STATIC 12 | gd.cc 13 | input.cc 14 | grad.cc 15 | jit.cc 16 | ) 17 | 18 | target_include_directories(jigsaw PRIVATE 19 | ${CMAKE_CURRENT_SOURCE_DIR}/../ 20 | ) 21 | 22 | target_link_libraries(jigsaw 23 | tcmalloc 24 | LLVM 25 | ) 26 | -------------------------------------------------------------------------------- /solvers/jigsaw/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H_ 2 | #define CONFIG_H_ 3 | #define MAX_NUM_MINIMAL_OPTIMA_ROUND 32 4 | #define MAX_EXEC_TIMES 1000 5 | #endif 6 | -------------------------------------------------------------------------------- /solvers/jigsaw/grad.cc: -------------------------------------------------------------------------------- 1 | #include "grad.h" 2 | #include 3 | #include 4 | 5 | using namespace rgd; 6 | 7 | Grad::Grad(size_t size) : grads(size) { 8 | } 9 | 10 | std::vector& Grad::get_value() { 11 | return grads; 12 | } 13 | 14 | 15 | uint64_t Grad::max_val() { 16 | uint64_t ret = 0; 17 | for (auto gradu : grads) { 18 | //std::cout << "graud value is " << gradu.val < ret) 20 | ret = gradu.val; 21 | } 22 | return ret; 23 | } 24 | 25 | void Grad::normalize() { 26 | double max_grad = (double)max_val(); 27 | if (max_grad > 0.0) { 28 | for(auto &grad : grads) { 29 | grad.pct = 1.0 * ((double)grad.val / max_grad); 30 | } 31 | } 32 | } 33 | 34 | void Grad::clear() { 35 | for (auto gradu : grads) { 36 | gradu.val = 0; 37 | gradu.pct = 0.0; 38 | } 39 | } 40 | 41 | size_t Grad::len() { 42 | return grads.size(); 43 | } 44 | 45 | 46 | uint64_t Grad::val_sum() { 47 | uint64_t ret = 0; 48 | for (auto gradu : grads) { 49 | //FIXME: saturating_add 50 | ret += gradu.val; 51 | } 52 | return ret; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /solvers/jigsaw/grad.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAD_H 2 | #define GRAD_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace rgd { 9 | 10 | class GradUnit { 11 | public: 12 | bool sign; 13 | uint64_t val; 14 | double pct; 15 | }; 16 | 17 | 18 | class Grad { 19 | private: 20 | std::vector grads; 21 | public: 22 | Grad(size_t size); 23 | std::vector& get_value(); 24 | uint64_t max_val(); 25 | void clear(); 26 | size_t len(); 27 | uint64_t val_sum(); 28 | void normalize(); 29 | }; 30 | 31 | }; // namespace rgd 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /solvers/jigsaw/input.cc: -------------------------------------------------------------------------------- 1 | #include "input.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace rgd; 8 | 9 | void MutInput::update(size_t index, bool direction, uint64_t delta) 10 | { 11 | if (direction) 12 | value[index] += delta; 13 | else 14 | value[index] -= delta; 15 | } 16 | 17 | uint8_t MutInput::get_rand() 18 | { 19 | uint8_t r = (uint8_t)r_val; 20 | r_val >>= 8; 21 | r_idx++; 22 | if (r_idx == 4) { 23 | random_r(&r_d, &r_val); 24 | r_idx = 0; 25 | } 26 | return r; 27 | } 28 | 29 | void MutInput::assign(std::vector> const& input) { 30 | for (int i = 0; i < size_; i++) { 31 | value[i] = input[i].second; 32 | //std::cout << "randomize " << i << " and assign value " << (int)value[i] << std::endl; 33 | } 34 | } 35 | 36 | void MutInput::flip(size_t index, size_t bit_index) { 37 | uint8_t val = value[index]; 38 | uint8_t mask = 1; 39 | mask = mask << bit_index; 40 | value[index] = val^mask; 41 | } 42 | 43 | void MutInput::set(const size_t index, uint8_t val) 44 | { 45 | value[index] = (uint64_t)val; 46 | } 47 | 48 | uint64_t MutInput::len() { 49 | return size_; 50 | } 51 | 52 | uint64_t MutInput::val_len() { 53 | return size_; 54 | } 55 | 56 | MutInput& MutInput::operator=(const MutInput &other) 57 | { 58 | MutInput::copy(this, &other); 59 | return *this; 60 | } 61 | 62 | void MutInput::dump() { 63 | // printf("dumping input and value size is %lu\n",value.size()); 64 | // for(auto i : value) 65 | // printf("%d, ",i); 66 | // printf("\n"); 67 | } 68 | 69 | void MutInput::randomize() { 70 | for(int i=0;i 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace rgd { 11 | 12 | class InputMeta { 13 | public: 14 | bool sign; 15 | size_t offset; 16 | size_t size; 17 | }; 18 | 19 | 20 | class MutInput { 21 | public: 22 | // std::vector value; 23 | uint64_t* value; 24 | // std::vector meta; 25 | size_t size_; 26 | size_t get_size(); 27 | MutInput(size_t size); 28 | ~MutInput(); 29 | void dump(); 30 | uint64_t len(); 31 | uint64_t val_len(); 32 | void randomize(); 33 | //random 34 | char r_s[256]; 35 | struct random_data r_d; 36 | int32_t r_val; 37 | int32_t r_idx; 38 | uint8_t get_rand(); 39 | 40 | uint8_t get(const size_t i); 41 | void update(size_t index, bool direction, uint64_t delta); 42 | void flip(size_t index, size_t bit_index); 43 | void set(const size_t index, uint8_t value); 44 | void assign(std::vector> const& input); 45 | MutInput& operator=(const MutInput &other); 46 | 47 | static void copy(MutInput *dst, const MutInput *src) 48 | { 49 | uint64_t *dst_value = dst->value; 50 | memcpy(dst, src, sizeof(MutInput)); 51 | if (!dst_value) 52 | dst->value = (uint64_t*)malloc(src->size_ * sizeof(uint64_t)); 53 | else 54 | dst->value = dst_value; 55 | memcpy(dst->value, src->value, src->size_ * sizeof(uint64_t)); 56 | } 57 | }; 58 | 59 | }; // namespace rgd 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /solvers/jigsaw/jit.h: -------------------------------------------------------------------------------- 1 | #ifndef JIGSAW_H_ 2 | #define JIGSAW_H_ 3 | 4 | #include 5 | 6 | #include "ast.h" 7 | #include "task.h" 8 | 9 | namespace rgd { 10 | 11 | int addFunction(const AstNode* node, 12 | std::map const& local_map, 13 | uint64_t id); 14 | 15 | test_fn_type performJit(uint64_t id); 16 | 17 | bool gd_entry(std::shared_ptr task); 18 | 19 | } 20 | 21 | #endif -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/cuckoo/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ main.cpp lockfree_hash_table.cpp -pthread -std=c++11 3 | clean: 4 | rm -rf a.out 5 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/cuckoo/hash_table.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_TABLE 2 | #define HASH_TABLE 3 | 4 | #include 5 | 6 | struct Hash_table { 7 | virtual std::pair search(int key) = 0; 8 | virtual void insert(int key, int val) = 0; 9 | virtual void remove(int key) = 0; 10 | }; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/cuckoo/lockfree_hash_table.h: -------------------------------------------------------------------------------- 1 | #ifndef LOCKFREE_HASH_TABLE 2 | #define LOCKFREE_HASH_TABLE 3 | 4 | #define MAX_BUF 256 5 | 6 | #include "hash_table.h" 7 | #include 8 | #include 9 | 10 | struct Hash_entry { 11 | int key; 12 | int val; 13 | }; 14 | 15 | // Alternate count_ptr definition using unused bits 16 | typedef Hash_entry* Count_ptr; 17 | 18 | enum Find_result { FIRST, SECOND, NIL }; 19 | 20 | struct Lockfree_hash_table { 21 | Lockfree_hash_table(int capacity, int thread_count); 22 | ~Lockfree_hash_table(); 23 | 24 | std::pair search(int key, int tid); 25 | void insert(int key, int val, int tid); 26 | void remove(int key, int tid); 27 | 28 | private: 29 | Count_ptr *table[2]; 30 | int size1; 31 | int size2; 32 | 33 | std::vector> rlist; 34 | std::vector rcount; 35 | std::vector> hp_rec; 36 | 37 | int hash1(int key); 38 | int hash2(int key); 39 | bool check_counter(int ts1, int ts2, int ts1x, int ts2x); 40 | Find_result find(int key, Count_ptr &ptr1, Count_ptr &ptr2, int tid); 41 | bool relocate(int which, int index, int tid); 42 | void help_relocate(int which, int index, bool initiator, int tid); 43 | void del_dup(int idx1, Count_ptr ptr1, int idx2, Count_ptr ptr2, int tid); 44 | 45 | void retire_node(Hash_entry* node, int tid); 46 | void scan(int tid); 47 | }; 48 | #endif 49 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/lprobe/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | g++ main.cc -std=c++14 -mcx16 -march=native -pthread 3 | clean: 4 | rm -rf a.out 5 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/lprobe/data.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_ELEMENT_ 2 | #define DATA_ELEMENT_ 3 | #include "utilities.h" 4 | using namespace pbbs; 5 | struct KV { 6 | int k; 7 | int v; 8 | bool operator== (struct KV other) { return k == other.k && v == other.v ;} 9 | bool operator!= (struct KV other) { return k != other.k || v != other.v ;} 10 | KV(int ak, int av) {k=ak;v=av;} 11 | }; 12 | 13 | struct hashKV { 14 | using eType = struct KV; 15 | using kType = int; 16 | eType empty() {return {-1,-1};} 17 | kType getKey(eType v) {return v.k;} 18 | //int hash(kType v) {return v * 999029;} //hash64_2(v);} 19 | int hash(kType v) {return hash64_2(v);} 20 | //int cmp(kType v, kType b) {return (v > b) ? 1 : ((v == b) ? 0 : -1);} 21 | int cmp(kType v, kType b) {return (v == b) ? 0 : -1;} 22 | bool replaceQ(eType, eType) {return 0;} 23 | eType update(eType v, eType) {return v;} 24 | bool cas(eType* p, eType o, eType n) {return 25 | atomic_compare_and_swap(p, o, n);} 26 | }; 27 | #endif 28 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/lprobe/data_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_ELEMENT_ 2 | #define DATA_ELEMENT_ 3 | #include "utilities.h" 4 | using namespace pbbs; 5 | struct KV { 6 | int k; 7 | int v; 8 | //bool operator== (struct KV other) { return k == other.k && v == other.v ;} 9 | //bool operator!= (struct KV other) { return k != other.k || v != other.v ;} 10 | KV(int ak, int av) {k=ak;v=av;} 11 | }; 12 | 13 | struct hashKV { 14 | using eType = struct KV*; 15 | using kType = int; 16 | //eType empty() {return new struct KV(-1,-1);} 17 | eType empty() {return nullptr;} 18 | kType getKey(eType v) {return v->k;} 19 | int hash(kType v) {return v * 999029;} //hash64_2(v);} 20 | //int hash(kType v) {return hash64_2(v);} 21 | //int cmp(kType v, kType b) {return (v > b) ? 1 : ((v == b) ? 0 : -1);} 22 | int cmp(kType v, kType b) {return (v == b) ? 0 : -1;} 23 | bool replaceQ(eType, eType) {return 0;} 24 | eType update(eType v, eType) {return v;} 25 | bool cas(eType* p, eType o, eType n) {return 26 | atomic_compare_and_swap(p, o, n);} 27 | }; 28 | #endif 29 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/lprobe/get_time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct timer { 10 | double total_time; 11 | double last_time; 12 | bool on; 13 | std::string name; 14 | struct timezone tzp; 15 | 16 | timer(std::string name = "PBBS time", bool _start = true) 17 | : total_time(0.0), on(false), name(name), tzp({0,0}) { 18 | if (_start) start(); 19 | } 20 | 21 | double get_time() { 22 | timeval now; 23 | gettimeofday(&now, &tzp); 24 | return ((double) now.tv_sec) + ((double) now.tv_usec)/1000000.; 25 | } 26 | 27 | void start () { 28 | on = 1; 29 | last_time = get_time(); 30 | } 31 | 32 | double stop () { 33 | on = 0; 34 | double d = (get_time()-last_time); 35 | total_time += d; 36 | return d; 37 | } 38 | 39 | void reset() { 40 | total_time=0.0; 41 | on=0; 42 | } 43 | 44 | double get_total() { 45 | if (on) return total_time + get_time() - last_time; 46 | else return total_time; 47 | } 48 | 49 | double get_next() { 50 | if (!on) return 0.0; 51 | double t = get_time(); 52 | double td = t - last_time; 53 | total_time += td; 54 | last_time = t; 55 | return td; 56 | } 57 | 58 | void report(double time, std::string str) { 59 | std::ios::fmtflags cout_settings = std::cout.flags(); 60 | std::cout.precision(4); 61 | std::cout << std::fixed; 62 | std::cout << name << ": "; 63 | if (str.length() > 0) 64 | std::cout << str << ": "; 65 | std::cout << time << std::endl; 66 | std::cout.flags(cout_settings); 67 | } 68 | 69 | void total() { 70 | report(get_total(),"total"); 71 | total_time = 0.0; 72 | } 73 | 74 | void reportTotal(std::string str) { 75 | report(get_total(), str); 76 | } 77 | 78 | void next(std::string str) { 79 | if (on) report(get_next(), str); 80 | } 81 | }; 82 | 83 | static timer _tm; 84 | #define startTime() _tm.start(); 85 | #define nextTime(_string) _tm.next(_string); 86 | -------------------------------------------------------------------------------- /solvers/wheels/lockfreehash/lprobe/main.cc: -------------------------------------------------------------------------------- 1 | #include "hash_table.h" 2 | #include "benchmark_lprobe.h" 3 | #include "data.h" 4 | using namespace pbbs; 5 | //#define DEFAULT_OP_COUNT 2000 6 | //#define DEFAULT_THREAD_COUNT 2 7 | //#define DEFAULT_READ_PERCENT 90 8 | //#define DEFAULT_LOAD_FACTOR 40 9 | //#define CAPACITY 8000016 10 | //#define CAPACITY 800000 11 | 12 | #define DEFAULT_OP_COUNT 2000000 13 | #define DEFAULT_THREAD_COUNT 24 14 | #define DEFAULT_READ_PERCENT 90 15 | #define DEFAULT_LOAD_FACTOR 40 16 | #define CAPACITY 8000016 17 | 18 | 19 | int main() { 20 | 21 | int op_count = DEFAULT_OP_COUNT; 22 | int num_threads = DEFAULT_THREAD_COUNT; 23 | int read_percent = DEFAULT_READ_PERCENT; 24 | int load_factor = DEFAULT_LOAD_FACTOR; 25 | 26 | int rweight = read_percent; 27 | int idweight = 100 - read_percent; 28 | /* 29 | Table T(100000, hashKV(), 1.3); 30 | T.insert({1,2}); 31 | T.insert({2,45}); 32 | struct KV res = T.find(2); 33 | std::cout << "return value is " << res.v << std::endl; 34 | */ 35 | 36 | BenchmarkLockFreeHT benchmark_lockfree_ht(op_count, CAPACITY, rweight, idweight, num_threads, 0.3); 37 | benchmark_lockfree_ht.run(); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_file(lit.site.cfg.in 2 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg 3 | @ONLY) 4 | 5 | -------------------------------------------------------------------------------- /tests/aggregate.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | typedef struct { 20 | int64_t x; 21 | int64_t y; 22 | } point_struct; 23 | 24 | point_struct __attribute__((noinline)) bar(int32_t x, int32_t y) { 25 | point_struct p; 26 | p.x = x; 27 | p.y = y; 28 | return p; 29 | } 30 | 31 | int __attribute__((noinline)) foo(int32_t y) { 32 | point_struct p = bar(y, y + 1); 33 | return p.x * p.y == 2; 34 | } 35 | 36 | int main (int argc, char** argv) { 37 | if (argc < 2) { 38 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 39 | return -1; 40 | } 41 | 42 | char buf[20]; 43 | FILE* fp = chk_fopen(argv[1], "rb"); 44 | chk_fread(buf, 1, sizeof(buf), fp); 45 | fclose(fp); 46 | 47 | int32_t x = 0; 48 | 49 | memcpy(&x, buf + 1, 4); // x 0 - 1 50 | 51 | if (foo(x) == 1) { 52 | // CHECK-GEN: Good 53 | printf("Good\n"); 54 | } else { 55 | // CHECK-ORIG: Bad 56 | printf("Bad\n"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/atomicrmw.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "lib.h" 19 | 20 | int main (int argc, char** argv) { 21 | if (argc < 2) { 22 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 23 | return -1; 24 | } 25 | 26 | char buf[20]; 27 | size_t ret; 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(buf, 1, sizeof(buf), fp); 31 | fclose(fp); 32 | 33 | uint32_t x = 0; 34 | uint32_t y = 0; 35 | memcpy(&x, buf, 4); 36 | memcpy(&y, buf + 4, 4); 37 | 38 | int orig = __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 39 | if(orig == 2 && y == 1) { 40 | // CHECK-GEN: Good 41 | printf("Good\n"); 42 | } 43 | else { 44 | // CHECK-ORIG: Bad 45 | printf("Bad\n"); 46 | } 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tests/bitflip.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | size_t ret; 27 | 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(buf, 1, sizeof(buf), fp); 30 | fclose(fp); 31 | 32 | uint32_t x = 0; 33 | memcpy(&x, buf, 4); 34 | 35 | if ((1 & (x >> 29)) && 36 | !(1 & (x >> 28)) && 37 | (1 & (x >> 27)) && 38 | (1 & (x >> 26)) && 39 | !(1 & (x >> 25)) && 40 | (1 & (x >> 24)) && 41 | (1 & (x >> 23)) && 42 | (1 & (x >> 22)) && 43 | !(1 & (x >> 21)) && 44 | !(1 & (x >> 20)) && 45 | (1 & (x >> 19)) && 46 | (1 & (x >> 18))) { 47 | // CHECK-GEN: Good 48 | printf("Good\n"); 49 | } 50 | else { 51 | // CHECK-ORIG: Bad 52 | printf("Bad\n"); 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /tests/bool.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("AABB"*10)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int __attribute__((noinline)) foo(int32_t y) { 20 | return y * y - 6 * y == -8; 21 | } 22 | 23 | int main (int argc, char** argv) { 24 | if (argc < 2) { 25 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 26 | return -1; 27 | } 28 | 29 | char buf[20]; 30 | FILE* fp = chk_fopen(argv[1], "rb"); 31 | chk_fread(buf, 1, sizeof(buf), fp); 32 | fclose(fp); 33 | 34 | int32_t x = 0; 35 | 36 | memcpy(&x, buf + 1, 4); // x 0 - 1 37 | 38 | if (foo(x) == 1) { 39 | // CHECK-GEN: Good 40 | printf("Good\n"); 41 | } else { 42 | // CHECK-ORIG: Bad 43 | printf("Bad\n"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/boundary.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -fsanitize=bounds -o %t.ubsan %s 5 | // RUN: env KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-1 2>&1 | FileCheck %s 8 | // CHECK: runtime error: index {{.*}} out of bounds for type 'char[26]' 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib.h" 15 | 16 | int main (int argc, char** argv) { 17 | if (argc < 2) { 18 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 19 | return 0; 20 | } 21 | 22 | int index = 0; 23 | char alphabet[26] = {0}; 24 | 25 | for (int i = 0; i < 26; i++) { 26 | alphabet[i] = 'A' + i; 27 | } 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&index, sizeof(index), 1, fp); 31 | fclose(fp); 32 | 33 | // BUG: out-of-boundary 34 | printf("%c\n", alphabet[index]); 35 | } 36 | -------------------------------------------------------------------------------- /tests/boundary2.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -fsanitize=bounds -o %t.ubsan %s 5 | // RUN: env KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-1 2>&1 | FileCheck %s 8 | // CHECK: runtime error: index {{.*}} out of bounds for type 'char[26]' 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib.h" 15 | 16 | int main (int argc, char** argv) { 17 | if (argc < 2) { 18 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 19 | return 0; 20 | } 21 | 22 | int index = 0; 23 | char alphabet[26] = {0}; 24 | 25 | for (int i = 0; i < 26; i++) { 26 | alphabet[i] = 'A' + i; 27 | } 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&index, sizeof(index), 1, fp); 31 | fclose(fp); 32 | 33 | // BUG: off-by-one if index == 26 34 | if (index > sizeof(alphabet)) { 35 | printf("Bad\n"); 36 | return 0; 37 | } 38 | 39 | printf("%c\n", alphabet[index]); 40 | } 41 | -------------------------------------------------------------------------------- /tests/boundary3.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -fsanitize=bounds -o %t.ubsan %s 5 | // RUN: env KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-1 2>&1 | FileCheck %s 8 | // CHECK: runtime error: index {{.*}} out of bounds for type 'char[26]' 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib.h" 15 | 16 | int main (int argc, char** argv) { 17 | if (argc < 2) { 18 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 19 | return 0; 20 | } 21 | 22 | int index = 0; 23 | char alphabet[26] = {0}; 24 | 25 | for (int i = 0; i < 26; i++) { 26 | alphabet[i] = 'A' + i; 27 | } 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&index, sizeof(index), 1, fp); 31 | fclose(fp); 32 | 33 | // BUG: index can be negative 34 | if (index >= 26) { 35 | printf("Bad\n"); 36 | return 0; 37 | } 38 | 39 | printf("%c\n", alphabet[index]); 40 | } 41 | -------------------------------------------------------------------------------- /tests/boundary4.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: env KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 5 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 6 | // RUN: not env TAINT_OPTIONS="debug=1 trace_bounds=1" %t.fg %t.out/id-0-0-1 2>&1 | FileCheck %s 7 | // CHECK: ERROR: OOB overflow 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib.h" 14 | 15 | int main (int argc, char** argv) { 16 | if (argc < 2) { 17 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 18 | return 0; 19 | } 20 | 21 | int index = 0; 22 | char *alphabet = malloc(26); 23 | 24 | for (int i = 0; i < 26; i++) { 25 | alphabet[i] = 'A' + i; 26 | } 27 | 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(&index, sizeof(index), 1, fp); 30 | fclose(fp); 31 | 32 | // BUG: off-by-one if index == 26 33 | if (index > 26U) { 34 | printf("Bad\n"); 35 | return 0; 36 | } 37 | 38 | printf("%c\n", alphabet[index]); 39 | free(alphabet); 40 | } 41 | -------------------------------------------------------------------------------- /tests/boundary5.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 5 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 6 | // RUN: not env TAINT_OPTIONS="debug=1 trace_bounds=1" %t.fg %t.out/id-0-0-1 2>&1 | FileCheck %s 7 | // CHECK: ERROR: OOB underflow 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib.h" 14 | 15 | int main (int argc, char** argv) { 16 | if (argc < 2) { 17 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 18 | return 0; 19 | } 20 | 21 | int index = 0; 22 | char *alphabet = malloc(26);; 23 | 24 | for (int i = 0; i < 26; i++) { 25 | alphabet[i] = 'A' + i; 26 | } 27 | 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(&index, sizeof(index), 1, fp); 30 | fclose(fp); 31 | 32 | // BUG: index can be negative 33 | if (index >= 26) { 34 | printf("Bad\n"); 35 | return 0; 36 | } 37 | 38 | // oob write 39 | alphabet[index] = 'A'; 40 | free(alphabet); 41 | } 42 | -------------------------------------------------------------------------------- /tests/boundary6.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x01\x00\x00\x00')" > %t.bin 4 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 5 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 6 | // RUN: not env TAINT_OPTIONS="debug=1 trace_bounds=1" %t.fg %t.out/id-0-0-0 2>&1 | FileCheck %s 7 | // CHECK: ERROR: OOB overflow 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib.h" 14 | 15 | int main (int argc, char** argv) { 16 | if (argc < 2) { 17 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 18 | return 0; 19 | } 20 | 21 | int size = 0; 22 | char alphabet[26] = {0}; 23 | char buf[26] = {0}; 24 | 25 | for (int i = 0; i < 26; i++) { 26 | alphabet[i] = 'A' + i; 27 | } 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&size, sizeof(size), 1, fp); 31 | fclose(fp); 32 | 33 | // BUG: out-of-boundary 34 | memcpy(buf, alphabet, size); 35 | } 36 | -------------------------------------------------------------------------------- /tests/boundary7.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x01\x00\x00\x00')" > %t.bin 4 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 5 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 6 | // RUN: not env TAINT_OPTIONS="debug=1 trace_bounds=1" %t.fg %t.out/id-0-0-0 2>&1 | FileCheck %s 7 | // CHECK: ERROR: OOB overflow 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "lib.h" 14 | 15 | int main (int argc, char** argv) { 16 | if (argc < 2) { 17 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 18 | return 0; 19 | } 20 | 21 | int size = 0; 22 | char alphabet[26] = {0}; 23 | char *buffer = malloc(26); 24 | 25 | for (int i = 0; i < 26; i++) { 26 | alphabet[i] = 'A' + i; 27 | } 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&size, sizeof(size), 1, fp); 31 | fclose(fp); 32 | 33 | // oob write 34 | memcpy(buffer, alphabet, size); 35 | free(alphabet); 36 | } 37 | -------------------------------------------------------------------------------- /tests/bounds.cpp: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00'*3)" > %t.bin 4 | // RUN: clang++ -fsanitize=bounds -o %t.ubsan %s 5 | // RUN: env KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang++ -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-0 2>&1 FileCheck %s --check-prefix=CHECK-A2 8 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-1 2>&1 FileCheck %s --check-prefix=CHECK-A2 9 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-3 2>&1 FileCheck %s --check-prefix=CHECK-B-3 10 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-4 2>&1 FileCheck %s --check-prefix=CHECK-B-3 11 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-7 2>&1 FileCheck %s --check-prefix=CHECK-C-4 12 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-8 2>&1 FileCheck %s --check-prefix=CHECK-C-4 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "lib.h" 19 | 20 | int main (int argc, char** argv) { 21 | if (argc < 2) { 22 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 23 | return 0; 24 | } 25 | 26 | int i = 0, j = 0, k = 0; 27 | 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(&i, sizeof(i), 1, fp); 30 | chk_fread(&j, sizeof(j), 1, fp); 31 | chk_fread(&k, sizeof(k), 1, fp); 32 | fclose(fp); 33 | 34 | int arr[2][3][4] = {}; 35 | 36 | return arr[i][j][k]; 37 | // CHECK-A-2: bounds.cpp:[[@LINE-1]]:10: runtime error: index {{.*}} out of bounds for type 'int[2][3][4]' 38 | // CHECK-B-3: bounds.cpp:[[@LINE-2]]:10: runtime error: index {{.*}} out of bounds for type 'int[3][4]' 39 | // CHECK-C-4: bounds.cpp:[[@LINE-3]]:10: runtime error: index {{.*}} out of bounds for type 'int[4]' 40 | } 41 | -------------------------------------------------------------------------------- /tests/call_fn.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN1 %s 9 | // RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN2 %s 10 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 11 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 12 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN1 %s 13 | // RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN2 %s 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "lib.h" 20 | 21 | void __attribute__ ((noinline)) bar(int y) { 22 | if (y == 12334) { 23 | // CHECK-GEN1: Good1 24 | printf("Good1"); 25 | } 26 | else { 27 | // CHECK-ORIG: Bad 28 | printf("Bad"); 29 | } 30 | } 31 | 32 | void __attribute__ ((noinline)) foo(int y) { 33 | bar(y - 1); 34 | } 35 | 36 | int main (int argc, char** argv) { 37 | if (argc < 2) { 38 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 39 | return -1; 40 | } 41 | 42 | char buf[20]; 43 | FILE* fp = chk_fopen(argv[1], "rb"); 44 | chk_fread(buf, 1, sizeof(buf), fp); 45 | fclose(fp); 46 | 47 | int32_t y = 0; 48 | memcpy(&y, buf + 4, 4); // y 4 - 7 49 | foo(y); 50 | 51 | int x = y; 52 | if (x == 123) { 53 | // CHECK-GEN2: Good2 54 | printf("Good2"); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/call_fn2.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int __attribute__ ((noinline)) foo(int y) { 20 | return y + 1024; 21 | } 22 | 23 | int main(int argc, char **argv) { 24 | if (argc < 2) { 25 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 26 | return -1; 27 | } 28 | 29 | char buf[20]; 30 | size_t ret; 31 | 32 | FILE* fp = chk_fopen(argv[1], "rb"); 33 | chk_fread(buf, 1, sizeof(buf), fp); 34 | fclose(fp); 35 | 36 | int32_t x = 0; 37 | 38 | memcpy(&x, buf + 4, 4); 39 | 40 | if (foo(x) == 8731) { 41 | // CHECK-GEN: Good 42 | printf("Good"); 43 | } 44 | else { 45 | // CHECK-ORIG: Bad 46 | printf("Bad"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/call_fn3.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int __attribute__ ((noinline)) foo(int y) { 20 | return y == 39123; 21 | } 22 | 23 | int main(int argc, char **argv) { 24 | if (argc < 2) { 25 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 26 | return -1; 27 | } 28 | 29 | char buf[20]; 30 | FILE* fp = chk_fopen(argv[1], "rb"); 31 | chk_fread(buf, 1, sizeof(buf), fp); 32 | fclose(fp); 33 | 34 | int32_t y = 0; 35 | memcpy(&y, buf + 4, 4); // y 4 - 7 36 | 37 | if (foo(y) && buf[0] == 12) { 38 | // CHECK-GEN: Good 39 | printf("Good"); 40 | } 41 | else { 42 | // CHECK-ORIG: Bad 43 | printf("Bad"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/cf1.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main(int argc, char **argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | int8_t x = 0; 31 | int32_t y = 0; 32 | int32_t m = 0; 33 | 34 | memcpy(&x, buf, 1); 35 | memcpy(&y, buf + 8, 4); 36 | memcpy(&m, buf + 15, 4); 37 | int z = 0; 38 | if (x == 1) { 39 | z = 123; 40 | } else { 41 | z = 998; 42 | } 43 | 44 | if (z == 123) { 45 | // CHECK-GEN: Good 46 | printf("Good\n"); 47 | } 48 | else { 49 | // CHECK-ORIG: Bad 50 | printf("Bad\n"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/cpp_fstream.cpp: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang++ -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang++ -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: cp %t.out/id-0-0-0 %t.bin 9 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 10 | // RUN: cp %t.out/id-0-0-1 %t.bin 11 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 12 | // RUN: %t.uninstrumented %t.out/id-0-0-2 | FileCheck --check-prefix=CHECK-GEN %s 13 | 14 | // doesn't work with in-process z3 solver 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | int main (int argc, char** argv) { 25 | if (argc < 2) { 26 | std::cerr << "Usage: " << argv[0] << "[file]\n"; 27 | return -1; 28 | } 29 | 30 | std::fstream in_file; 31 | in_file.open(argv[1], std::ios::in | std::ios::binary); 32 | if (!in_file.is_open()) return 0; 33 | 34 | in_file.seekg (0, in_file.end); 35 | int length = in_file.tellg(); 36 | in_file.seekg (0, in_file.beg); 37 | 38 | if (length <= 3) { 39 | std::cerr << "Input too short\n"; 40 | return 0; 41 | } 42 | 43 | char *val = new char[length]; 44 | in_file.read(val, length); 45 | 46 | if (val[0] == 'z' && val[1] == 'a' && val[2] == 'c') { 47 | // CHECK-GEN: Good 48 | std::cout << "Good\n"; 49 | } else { 50 | // CHECK-ORIG: Bad 51 | std::cout << "Bad\n"; 52 | } 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /tests/cpp_map.cpp: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: clang++ -o %t.uninstrumented %s 4 | // RUN: %t.uninstrumented | FileCheck --check-prefix=CHECK-BUG %s 5 | // RUN: env KO_USE_FASTGEN=1 %ko-clang++ -o %t.fg %s 6 | // RUN: %t.fg | FileCheck --check-prefix=CHECK-BUG %s 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main() { 14 | std::map mymap; 15 | std::string k1("key1"); 16 | std::string k2("key2"); 17 | 18 | mymap[k1] = "xx1"; 19 | mymap[k2] = "xx2"; 20 | 21 | if (mymap["key1"] == "xx1" && mymap[k2] == "xx2" && mymap[k1] != mymap["k2"]) { 22 | // CHECK-BUG: Good 23 | std::cout << "Good\n"; 24 | } else { 25 | std::cout << "Bad\n"; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /tests/cpp_string.cpp: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang++ -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang++ -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | 10 | // doesn't work with in-process z3 solver 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "lib.h" 20 | 21 | int main(int argc, char **argv) { 22 | if (argc < 2) { 23 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 24 | return -1; 25 | } 26 | 27 | char buf[20]; 28 | size_t ret; 29 | 30 | FILE* fp = chk_fopen(argv[1], "rb"); 31 | chk_fread(buf, 1, sizeof(buf), fp); 32 | fclose(fp); 33 | 34 | // if (contents.substr(0, 7) == "iamback") { 35 | // std::cout <<" hhe\n"; 36 | // abort(); 37 | // } 38 | 39 | // if (contents[1] == 'y' && contents[2] == 'x') { 40 | // abort(); 41 | // } 42 | 43 | std::string val(buf); 44 | 45 | // if (val.compare("deadbeef") == 0) { 46 | // if (val == "deadbeef") { 47 | if (strcmp(val.c_str(), "deadbeef") == 0) { 48 | // CHECK-GEN: Good 49 | std::cout << "Good\n"; 50 | } else { 51 | // CHECK-ORIG: Bad 52 | std::cout << "Bad\n"; 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /tests/if_eq.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("AABB"*10)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | uint16_t x = 0; 31 | uint16_t y = 0; 32 | 33 | memcpy(&x, buf + 1, 2); // x 0 - 1 34 | memcpy(&y, buf + 4, 2); // y 4 - 7 35 | 36 | if (x == y) { 37 | // CHECK-GEN: Good 38 | printf("Good\n"); 39 | } 40 | else { 41 | // CHECK-ORIG: Bad 42 | printf("Bad\n"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/infer_type.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main(int argc, char **argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | size_t ret; 27 | 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(buf, 1, sizeof(buf), fp); 30 | fclose(fp); 31 | 32 | uint16_t x = 0; 33 | int32_t y = 0; 34 | int32_t z = 0; 35 | uint32_t a = 0; 36 | 37 | memcpy(&x, buf + 1, 2); // x 0 - 1 38 | memcpy(&y, buf + 4, 4); // y 4 - 7 39 | memcpy(&z, buf + 10, 4); // 10 - 13 40 | memcpy(&a, buf + 14, 4); // 14 - 17 41 | 42 | uint32_t bb = x + y + z + a; 43 | if (bb == 213) { 44 | // CHECK-GEN: Good 45 | printf("Good\n"); 46 | } 47 | else { 48 | // CHECK-ORIG: Bad 49 | printf("Bad\n"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/lib.h: -------------------------------------------------------------------------------- 1 | #ifndef LIB_H 2 | #define LIB_H 3 | 4 | #include 5 | #include 6 | 7 | FILE *chk_fopen(const char *pathname, const char *mode) { 8 | FILE* fp = fopen(pathname, mode); 9 | if (!fp) { 10 | fprintf(stderr, "Failed to open\n"); 11 | exit(0); 12 | } 13 | return fp; 14 | } 15 | 16 | void chk_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { 17 | if (fread(ptr, size, nmemb, stream) != nmemb) { 18 | fprintf(stderr, "Failed to read\n"); 19 | exit(0); 20 | } 21 | } 22 | 23 | 24 | #endif /* LIB_H */ 25 | -------------------------------------------------------------------------------- /tests/lit.cfg: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import re 4 | import platform 5 | 6 | try: 7 | import lit.util 8 | import lit.formats 9 | except ImportError: 10 | pass 11 | 12 | config.name = "SymSan" 13 | config.test_format = lit.formats.ShTest(execute_external=False) 14 | 15 | config.suffixes = ['.c', '.cpp'] 16 | config.test_source_root = os.path.join(config.source_dir, "tests") 17 | 18 | 19 | bin_dir = os.path.join(config.install_dir, "bin") 20 | if not os.path.exists(bin_dir): 21 | lit_config.fatal("Cannot find install directory: {}".format(bin_dir)) 22 | 23 | if not os.path.exists(config.llvm_bin_dir): 24 | lit_config.fatal("Cannot find llvm tool directory: {}".format(config.llvm_bin_dir)) 25 | 26 | path = os.path.pathsep.join([ 27 | config.llvm_bin_dir, 28 | config.environment['PATH'] 29 | ]) 30 | 31 | config.environment['PATH'] = path 32 | # config.environment['KO_CC'] = 'clang-14' 33 | # config.environment['KO_CXX'] = 'clang++-14' 34 | 35 | config.substitutions.append(('%ko-clang', os.path.join(bin_dir, "ko-clang"))) 36 | config.substitutions.append(('%ko-clangxx', os.path.join(bin_dir, "ko-clang++"))) 37 | config.substitutions.append(('%fgtest', os.path.join(bin_dir, "fgtest"))) 38 | -------------------------------------------------------------------------------- /tests/lit.site.cfg.in: -------------------------------------------------------------------------------- 1 | config.build_dir = "@CMAKE_BINARY_DIR@" 2 | config.source_dir = "@CMAKE_SOURCE_DIR@" 3 | config.install_dir = "@CMAKE_INSTALL_PREFIX@" 4 | config.llvm_bin_dir = "@LLVM_TOOLS_BINARY_DIR@" 5 | 6 | lit_config.load_config(config, "@CMAKE_SOURCE_DIR@/tests/lit.cfg") 7 | -------------------------------------------------------------------------------- /tests/memcmp.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main(int argc, char **argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | char b[10] = {1, 1, 1, 1, 1, 2, 3, 4, 5, 0}; 31 | 32 | if (memcmp(b, buf, 9) == 0) { 33 | // CHECK-GEN: Good 34 | printf("Good\n"); 35 | } 36 | else { 37 | // CHECK-ORIG: Bad 38 | printf("Bad\n"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/mini.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-5 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out debug=1" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-5 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main(int argc, char **argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | uint16_t x = 0; 31 | int32_t y = 0; 32 | int32_t z = 0; 33 | uint32_t a = 0; 34 | 35 | memcpy(&x, buf + 1, 2); // x 1 - 2 36 | memcpy(&y, buf + 4, 4); // y 4 - 7 37 | memcpy(&z, buf + 10, 4); // 10 - 13 38 | memcpy(&a, buf + 14, 4); // 14 - 17 39 | if (x > 12300 && x < 12350 && z < -100000000 && z > -100000005 && 40 | z != -100000003 && y >= 987654321 && y <= 987654325 && a == 123456789) { 41 | // CHECK-GEN: Good 42 | printf("Good\n"); 43 | } 44 | else { 45 | // CHECK-ORIG: Bad 46 | printf("Bad\n"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/optimistic.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\xef\xbe\xad\xde')" > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 7 | // RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN %s 8 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_Z3=1 %ko-clang -o %t.z3 %s 9 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 10 | // RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN %s 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "lib.h" 17 | 18 | int main (int argc, char** argv) { 19 | if (argc < 2) { 20 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 21 | return -1; 22 | } 23 | 24 | uint32_t x = 0; 25 | FILE* fp = chk_fopen(argv[1], "rb"); 26 | chk_fread(&x, sizeof(x), 1, fp); 27 | fclose(fp); 28 | 29 | if (x == 0xdeadbeef) { 30 | // CHECK-ORIG: Bad 31 | printf("Bad\n"); 32 | } 33 | 34 | if (x == 0xbadf00d) { 35 | // CHECK-GEN: Good 36 | printf("Good\n"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/partial_concrete.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20], copy[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | memcpy(copy, buf, sizeof(buf)); 31 | copy[3] = 0x80; 32 | 33 | if (buf[0] != 0x80 34 | && *(int*)copy == 0x80adbeef) { 35 | // CHECK-GEN: Good 36 | printf("Good\n"); 37 | } 38 | else { 39 | // CHECK-ORIG: Bad 40 | printf("Bad\n"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/partial_concrete2.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20], copy[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | memset(copy, 0, sizeof(copy)); 31 | copy[2] = buf[0]; 32 | 33 | if (*(int*)copy == 0x00ee0000) { 34 | // CHECK-GEN: Good 35 | printf("Good\n"); 36 | } 37 | else { 38 | // CHECK-ORIG: Bad 39 | printf("Bad\n"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/partial_concrete3.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20], copy[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | memset(copy, 0, sizeof(copy)); 31 | copy[1] = buf[0]; 32 | 33 | if (*(int*)copy == 0x0000ee00) { 34 | // CHECK-GEN: Good 35 | printf("Good\n"); 36 | } 37 | else { 38 | // CHECK-ORIG: Bad 39 | printf("Bad\n"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/pointer.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main(int argc, char **argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | void* x = NULL; 31 | memcpy(&x, buf, sizeof x); 32 | if (!x) { 33 | // CHECK-GEN: Good 34 | printf("Good"); 35 | } 36 | else { 37 | // CHECK-ORIG: Bad 38 | printf("Bad"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/shift_and.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | uint32_t x = 0; 31 | 32 | memcpy(&x, buf, 4); 33 | /* if ((int)(x & 0xFF) == 12) { */ 34 | if (((int)(x >> 24) & 0xFF) == 11 && ((int)(x >> 16) & 0xFF) == 22 && 35 | ((int)(x >> 8) & 0xFF) == 33 && (int)(x & 0xFF) == 44) { 36 | // CHECK-GEN: Good 37 | printf("Good\n"); 38 | } 39 | else { 40 | // CHECK-ORIG: Bad 41 | printf("Bad\n"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/sign.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | char buf[20]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | uint16_t x = 0; 31 | 32 | memcpy(&x, buf + 1, 2); 33 | 34 | // if y is less than 32 bits, it has not nsw flag. 35 | int16_t y = x * -3; 36 | 37 | if (y == -12) { 38 | // CHECK-GEN: Good 39 | printf("Good\n"); 40 | } 41 | else { 42 | // CHECK-ORIG: Bad 43 | printf("Bad\n"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/strcmp2.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // TODO: RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN1 %s 9 | // TODO: RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN2 %s 10 | // RUN: env KO_USE_Z3=1 %ko-clang -o %t.z3 %s 11 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 12 | // TODO: RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN1 %s 13 | // TODO: RUN: %t.uninstrumented %t.out/id-0-0-1 | FileCheck --check-prefix=CHECK-GEN2 %s 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "lib.h" 20 | 21 | int main (int argc, char** argv) { 22 | if (argc < 2) { 23 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 24 | return -1; 25 | } 26 | 27 | char buf[20]; 28 | FILE* fp = chk_fopen(argv[1], "rb"); 29 | chk_fread(buf, 1, sizeof(buf), fp); 30 | fclose(fp); 31 | 32 | char a[20] = { 33 | 1, 1, 1, 1, 7, 34 | 8, 9, 1, 45, 2, 35 | 88, 1, 1, 2, 3, 36 | 4, 5, 0 37 | }; 38 | 39 | 40 | char b[10] = {1, 1, 1, 1, 41 | 1, 2, 3, 4, 5, 0}; 42 | 43 | if (strcmp(buf, a) == 0) { 44 | // CHECK-GEN1: Good1 45 | printf("Good1\n"); 46 | } 47 | else { 48 | // CHECK-ORIG: Bad 49 | printf("Bad\n"); 50 | } 51 | 52 | if (strcmp(buf, b) == 0) { 53 | // CHECK-GEN2: Good2 54 | printf("Good2\n"); 55 | } 56 | else { 57 | // CHECK-ORIG: Bad 58 | printf("Bad\n"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/struct.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib.h" 15 | 16 | struct point_t { 17 | int x; 18 | int y; 19 | }; 20 | 21 | int main (int argc, char** argv) { 22 | if (argc < 2) { 23 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 24 | return -1; 25 | } 26 | 27 | int x = 0; 28 | 29 | FILE* fp = chk_fopen(argv[1], "rb"); 30 | chk_fread(&x, 1, sizeof(x), fp); 31 | fclose(fp); 32 | 33 | struct point_t p = { x, 1 }; 34 | 35 | if (p.x == 1) { 36 | // CHECK-GEN: Good 37 | printf("Good1\n"); 38 | } 39 | else { 40 | // CHECK-ORIG: Bad 41 | printf("Bad\n"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/ubsan_div.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x01\x00\x00\x00\x01\x00\x00\x00')" > %t.bin 4 | // RUN: clang -fsanitize=undefined -o %t.ubsan %s 5 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-0 2>&1 | FileCheck %s 8 | // CHECK: runtime error: division by zero 9 | // CHECK: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "lib.h" 16 | 17 | int main (int argc, char** argv) { 18 | if (argc < 2) { 19 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 20 | return 0; 21 | } 22 | 23 | FILE* fp = chk_fopen(argv[1], "rb"); 24 | int dividend = 0, divisor = 0; 25 | 26 | chk_fread(÷nd, sizeof(dividend), 1, fp); 27 | chk_fread(&divisor, sizeof(divisor), 1, fp); 28 | fclose(fp); 29 | printf("%d\n", dividend / divisor); 30 | } 31 | -------------------------------------------------------------------------------- /tests/ubsan_intovfl.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x00\x00\x00\x00\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -O0 -fsanitize=unsigned-integer-overflow -o %t.ubsan %s 5 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-0 2>&1 | FileCheck %s 8 | // CHECK: runtime error: unsigned integer overflow 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "lib.h" 15 | 16 | int main (int argc, char** argv) { 17 | if (argc < 2) { 18 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 19 | return 0; 20 | } 21 | 22 | FILE* fp = chk_fopen(argv[1], "rb"); 23 | size_t size = 0; 24 | 25 | chk_fread(&size, sizeof(size), 1, fp); 26 | fclose(fp); 27 | 28 | char* ptr = malloc(size + 1); 29 | memset(ptr, 0, size); 30 | free(ptr); 31 | } 32 | -------------------------------------------------------------------------------- /tests/ubsan_shift.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c"import sys; sys.stdout.buffer.write(b'\x02\x00\x00\x00\x00\x00\x00\x00')" > %t.bin 4 | // RUN: clang -fsanitize=undefined -o %t.ubsan %s 5 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 KO_SOLVE_UB=1 %ko-clang -o %t.fg %s 6 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out solve_ub=1" %fgtest %t.fg %t.bin 7 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-0 2>&1 | FileCheck %s --check-prefix=LARGE 8 | // LARGE: runtime error: shift exponent 9 | // LARGE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 10 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-1 2>&1 | FileCheck %s --check-prefix=NEG 11 | // NEG: runtime error: shift exponent 12 | // NEG: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 13 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-2 2>&1 | FileCheck %s --check-prefix=OVFL 14 | // OVFL: runtime error: left shift 15 | // OVFL: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 16 | // RUN: not env UBSAN_OPTIONS="halt_on_error=1" %t.ubsan %t.out/id-0-0-3 2>&1 | FileCheck %s --check-prefix=NEGB 17 | // NEGB: runtime error: left shift of negative value 18 | // NEGB: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 19 | 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "lib.h" 26 | 27 | int main (int argc, char** argv) { 28 | if (argc < 2) { 29 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 30 | return 0; 31 | } 32 | 33 | FILE* fp = chk_fopen(argv[1], "rb"); 34 | int base = 0, shift = 0; 35 | 36 | chk_fread(&base, sizeof(base), 1, fp); 37 | chk_fread(&shift, sizeof(shift), 1, fp); 38 | fclose(fp); 39 | printf("%d\n", base << shift); 40 | } 41 | -------------------------------------------------------------------------------- /tests/unaligned_load.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*20)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int main (int argc, char** argv) { 20 | if (argc < 2) { 21 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 22 | return -1; 23 | } 24 | 25 | int buf[5]; 26 | FILE* fp = chk_fopen(argv[1], "rb"); 27 | chk_fread(buf, 1, sizeof(buf), fp); 28 | fclose(fp); 29 | 30 | buf[0] += 0xbadf00d; 31 | buf[2] = *(int*)((void*)buf + 1); 32 | 33 | if (buf[2] == 0xdeadbeef) { 34 | // CHECK-GEN: Good 35 | printf("Good\n"); 36 | } 37 | else { 38 | // CHECK-ORIG: Bad 39 | printf("Bad\n"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/xor_bool.c: -------------------------------------------------------------------------------- 1 | // RUN: rm -rf %t.out 2 | // RUN: mkdir -p %t.out 3 | // RUN: python -c'print("A"*4 + "B"*4)' > %t.bin 4 | // RUN: clang -o %t.uninstrumented %s 5 | // RUN: %t.uninstrumented %t.bin | FileCheck --check-prefix=CHECK-ORIG %s 6 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_FASTGEN=1 %ko-clang -o %t.fg %s 7 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %fgtest %t.fg %t.bin 8 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 9 | // RUN: env KO_DONT_OPTIMIZE=1 KO_USE_Z3=1 %ko-clang -o %t.z3 %s 10 | // RUN: env TAINT_OPTIONS="taint_file=%t.bin output_dir=%t.out" %t.z3 %t.bin 11 | // RUN: %t.uninstrumented %t.out/id-0-0-0 | FileCheck --check-prefix=CHECK-GEN %s 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "lib.h" 18 | 19 | int __attribute__((noinline)) foo(int32_t y) { 20 | return y * y - 6 * y == -8; 21 | } 22 | 23 | int main (int argc, char** argv) { 24 | if (argc < 2) { 25 | fprintf(stderr, "Usage: %s [file]\n", argv[0]); 26 | return -1; 27 | } 28 | 29 | int x = 0; 30 | int y = 0; 31 | FILE* fp = chk_fopen(argv[1], "rb"); 32 | chk_fread(&x, 1, sizeof(x), fp); 33 | chk_fread(&y, 1, sizeof(y), fp); 34 | fclose(fp); 35 | 36 | if (x == 0xdeadbeef ^ y == 0xbadf00d) { 37 | // CHECK-GEN: Good 38 | printf("Good\n"); 39 | } else { 40 | // CHECK-ORIG: Bad 41 | printf("Bad\n"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wrappers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | 3 | ## custom model 4 | # add_library(ZlibRt STATIC zlib_func.c) 5 | # install (TARGETS ZlibRt DESTINATION ${SYMSAN_LIB_DIR}) 6 | install (FILES "zlib_abilist.txt" DESTINATION ${SYMSAN_LIB_DIR}) 7 | --------------------------------------------------------------------------------