├── .github └── workflows │ └── build.yml ├── .gitmodules ├── Dockerfile ├── README.rst ├── build_all.sh ├── build_all_sudo.sh ├── build_remote.sh ├── build_rustc.sh ├── examples ├── source_0_original_1c0_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c1_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c2_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c3_rs │ ├── .gitignore │ ├── Cargo.toml │ ├── fuzz │ │ ├── Cargo.toml │ │ └── fuzz_targets │ │ │ └── fuzz_target_1.rs │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c4_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c5_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c6_rs │ ├── .gitignore │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c7_rs │ ├── .gitignore │ ├── Cargo.toml │ ├── fuzz │ │ ├── Cargo.toml │ │ └── fuzz_targets │ │ │ └── fuzz_target_1.rs │ └── src │ │ ├── lib.rs │ │ └── main.rs ├── source_0_original_1c8_rs │ ├── .gitignore │ ├── Cargo.toml │ ├── fuzz │ │ ├── Cargo.toml │ │ └── fuzz_targets │ │ │ └── fuzz_target_1.rs │ └── src │ │ ├── lib.rs │ │ └── main.rs └── source_0_original_1c9_rs │ ├── .gitignore │ ├── Cargo.toml │ ├── README.md │ ├── fuzz │ ├── Cargo.toml │ └── fuzz_targets │ │ └── fuzz_target_1.rs │ └── src │ ├── lib.rs │ └── main.rs ├── generated ├── build.sh └── linux │ └── .config ├── git_current_branch.sh ├── git_rebase_versions.sh ├── make_build.sh ├── rustc.Dockerfile ├── src ├── cpp │ ├── fold_exec_clang++.sh │ ├── fold_exec_ko-clang++.sh │ ├── fold_exec_sym++_qsym.sh │ ├── fold_exec_sym++_simple_z3.sh │ ├── fold_llvm_clang++.sh │ ├── fold_llvm_ko-clang++.sh │ ├── fold_llvm_sym++.sh │ ├── main_fold_clang++.sh │ ├── main_fold_ko-clang++.sh │ ├── main_fold_sym++_qsym.sh │ └── main_fold_sym++_simple_z3.sh ├── llvm │ ├── cmake.sh │ └── cmake0.sh └── rs │ ├── cargo_fuzz.sh │ ├── cargo_fuzz0.sh │ ├── env.sh │ ├── env0.sh │ ├── fold_symrustc_build.sh │ ├── fold_symrustc_run.sh │ ├── hexdump.sh │ ├── libafl_cargo.sh │ ├── libafl_solving_build.sh │ ├── libafl_solving_build0.sh │ ├── libafl_solving_run.sh │ ├── libafl_solving_run0.sh │ ├── libafl_swap.sh │ ├── libafl_tracing_build.sh │ ├── libafl_tracing_run.sh │ ├── parse_args.sh │ ├── parse_args0.sh │ ├── rustc.sh │ ├── rustc_file.sh │ ├── rustc_none.sh │ ├── rustc_stdin.sh │ ├── symcc_fuzzing_helper.sh │ ├── symrustc.sh │ ├── symrustc_build.sh │ ├── symrustc_build_show.sh │ ├── symrustc_hybrid.sh │ ├── symrustc_run.sh │ └── wait_all.sh └── symrustc.Dockerfile /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build all 2 | on: [push, pull_request] 3 | jobs: 4 | all: 5 | runs-on: ubuntu-20.04 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Set up Ubuntu environment 9 | run: docker build --target builder_base -t belcarra_base --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 10 | 11 | - name: Set up project source 12 | run: docker build --target builder_source -t belcarra_source --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 13 | 14 | - name: Set up project dependencies 15 | run: docker build --target builder_depend -t belcarra_depend --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 16 | 17 | - name: Build AFL 18 | run: docker build --target builder_afl -t belcarra_afl --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 19 | 20 | - name: Build SymCC simple backend 21 | run: docker build --target builder_symcc_simple -t belcarra_symcc_simple --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 22 | 23 | - name: Build LLVM libcxx using SymCC simple backend 24 | run: docker build --target builder_symcc_libcxx -t belcarra_symcc_libcxx --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 25 | 26 | - name: Build SymCC Qsym backend 27 | run: docker build --target builder_symcc_qsym -t belcarra_symcc_qsym --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 28 | 29 | - name: Build SymLLVM 30 | run: docker build --target builder_symllvm -t belcarra_symllvm --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 31 | 32 | - name: Build SymRustC core 33 | run: docker build --target builder_symrustc -t belcarra_symrustc --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 34 | 35 | - name: Build SymRustC main 36 | run: docker build --target builder_symrustc_main -t belcarra_symrustc_main --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 37 | 38 | - name: Set up Ubuntu/Rust environment 39 | run: docker build --target builder_base_rust -t belcarra_base_rust --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 40 | 41 | - name: Build LibAFL solving runtime 42 | run: docker build --target builder_libafl_solving -t belcarra_libafl_solving --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 43 | 44 | - name: Build LibAFL solving runtime main 45 | run: docker build --target builder_libafl_solving_main -t belcarra_libafl_solving_main --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 46 | 47 | - name: Build end user environment 48 | run: docker build --target builder_end_user -t belcarra_end_user --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 49 | 50 | - name: Build end user environment main 51 | run: docker build --target builder_end_user_main -t belcarra_end_user_main --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='main' --build-arg SYMRUSTC_DIR_COPY='examples' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 52 | 53 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/rs/rust_source"] 2 | path = src/rs/rust_source 3 | url = https://github.com/sfu-rsl/rust.git 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier 2 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 3 | 4 | # # 5 | 6 | # This file is part of SymCC. 7 | # 8 | # SymCC is free software: you can redistribute it and/or modify it under the 9 | # terms of the GNU General Public License as published by the Free Software 10 | # Foundation, either version 3 of the License, or (at your option) any later 11 | # version. 12 | # 13 | # SymCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 15 | # A PARTICULAR PURPOSE. See the GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License along with 18 | # SymCC. If not, see . 19 | 20 | # # 21 | 22 | # 23 | # Set up Ubuntu environment 24 | # 25 | FROM ubuntu:22.10 AS builder_base 26 | 27 | SHELL ["/bin/bash", "-c"] 28 | 29 | RUN apt-get update \ 30 | && DEBIAN_FRONTEND=noninteractive apt-get install -y \ 31 | sudo \ 32 | && apt-get clean 33 | 34 | RUN useradd -m -s /bin/bash ubuntu \ 35 | && echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/ubuntu 36 | 37 | USER ubuntu 38 | ENV HOME=/home/ubuntu 39 | WORKDIR $HOME 40 | 41 | 42 | # 43 | # Set up project source 44 | # 45 | FROM builder_base AS builder_source 46 | 47 | ENV SYMRUSTC_LLVM_VERSION=15 48 | 49 | RUN sudo apt-get update \ 50 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 51 | clang-tools-$SYMRUSTC_LLVM_VERSION \ 52 | mlir-$SYMRUSTC_LLVM_VERSION-tools \ 53 | libmlir-$SYMRUSTC_LLVM_VERSION-dev \ 54 | cmake \ 55 | g++ \ 56 | git \ 57 | ninja-build \ 58 | python3-pip \ 59 | && sudo apt-get clean 60 | 61 | ENV SYMRUSTC_USER=$HOME 62 | ENV SYMRUSTC_HOME=$HOME/belcarra_source 63 | ENV SYMRUSTC_HOME_CPP=$SYMRUSTC_HOME/src/cpp 64 | ENV SYMRUSTC_HOME_RS=$SYMRUSTC_HOME/src/rs 65 | ENV SYMCC_LIBCXX_PATH=$HOME/libcxx_symcc_install 66 | ENV SYMRUSTC_LIBAFL_SOLVING_DIR=$HOME/libafl/fuzzers/libfuzzer_rust_concolic 67 | ENV SYMRUSTC_LIBAFL_TRACING_DIR=$HOME/libafl/libafl_concolic/test 68 | 69 | # Setup Rust compiler source 70 | ARG SYMRUSTC_RUST_VERSION 71 | ARG SYMRUSTC_BRANCH 72 | RUN if [[ -v SYMRUSTC_RUST_VERSION ]] ; then \ 73 | git clone --depth 1 -b $SYMRUSTC_RUST_VERSION https://github.com/sfu-rsl/rust.git rust_source; \ 74 | else \ 75 | git clone --depth 1 -b "$SYMRUSTC_BRANCH" https://github.com/sfu-rsl/symrustc.git belcarra_source0; \ 76 | ln -s ~/belcarra_source0/src/rs/rust_source; \ 77 | fi 78 | 79 | # Init submodules 80 | RUN [[ -v SYMRUSTC_RUST_VERSION ]] && dir='rust_source' || dir='belcarra_source0' ; \ 81 | git -C "$dir" submodule update --init --recursive 82 | 83 | # 84 | RUN ln -s ~/rust_source/src/llvm-project llvm_source 85 | RUN git clone -b rust_runtime_verbose/20221214 https://github.com/sfu-rsl/LibAFL.git libafl 86 | RUN ln -s ~/llvm_source/symcc symcc_source 87 | 88 | # Note: Depending on the commit revision, the Rust compiler source may not have yet a SymCC directory. In this docker stage, we treat such case as a "non-aborting failure" (subsequent stages may raise different errors). 89 | RUN if [ -d symcc_source ] ; then \ 90 | cd symcc_source \ 91 | && current=$(git log -1 --pretty=format:%H) \ 92 | # Note: Ideally, all submodules must also follow the change of version happening in the super-root project. 93 | && git checkout origin/main/$(git branch -r --contains "$current" | cut -d '/' -f 3-) \ 94 | && cp -a . ~/symcc_source_main \ 95 | && git checkout "$current"; \ 96 | fi 97 | 98 | # Download AFL 99 | RUN git clone --depth 1 -b v2.56b https://github.com/google/AFL.git afl 100 | 101 | # Download Z3 102 | RUN git clone --depth 1 -b z3-4.11.2 https://github.com/Z3Prover/z3.git 103 | 104 | 105 | # 106 | # Set up project dependencies 107 | # 108 | FROM builder_source AS builder_depend 109 | 110 | RUN sudo apt-get update \ 111 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 112 | llvm-$SYMRUSTC_LLVM_VERSION-dev \ 113 | llvm-$SYMRUSTC_LLVM_VERSION-tools \ 114 | python2 \ 115 | zlib1g-dev \ 116 | && sudo apt-get clean 117 | RUN pip3 install lit 118 | ENV PATH=$HOME/.local/bin:$PATH 119 | 120 | # https://github.com/season-lab/SymFusion/blob/main/docker/Dockerfile 121 | RUN mkdir z3_build \ 122 | && cd z3_build \ 123 | && cmake ~/z3 \ 124 | -DCMAKE_BUILD_TYPE=Release \ 125 | -DCMAKE_INSTALL_PREFIX=`pwd`/dist \ 126 | && make -j `nproc` \ 127 | && make install 128 | 129 | 130 | # 131 | # Build AFL 132 | # 133 | FROM builder_source AS builder_afl 134 | 135 | RUN cd afl \ 136 | && make 137 | 138 | 139 | # 140 | # Build SymCC simple backend 141 | # 142 | FROM builder_depend AS builder_symcc_simple 143 | RUN mkdir symcc_build_simple \ 144 | && cd symcc_build_simple \ 145 | && cmake -G Ninja ~/symcc_source_main \ 146 | -DLLVM_VERSION_FORCE=$SYMRUSTC_LLVM_VERSION \ 147 | -DQSYM_BACKEND=OFF \ 148 | -DCMAKE_BUILD_TYPE=RelWithDebInfo \ 149 | -DZ3_DIR=~/z3_build/dist/lib/cmake/z3 \ 150 | && ninja check 151 | 152 | 153 | # 154 | # Build LLVM libcxx using SymCC simple backend 155 | # 156 | FROM builder_symcc_simple AS builder_symcc_libcxx 157 | RUN export SYMCC_REGULAR_LIBCXX=yes SYMCC_NO_SYMBOLIC_INPUT=yes \ 158 | && mkdir -p rust_source/build/x86_64-unknown-linux-gnu/llvm/build \ 159 | && cd rust_source/build/x86_64-unknown-linux-gnu/llvm/build \ 160 | && cmake -G Ninja ~/llvm_source/llvm \ 161 | -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ 162 | -DLLVM_TARGETS_TO_BUILD="X86" \ 163 | -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ 164 | -DCMAKE_BUILD_TYPE=Release \ 165 | -DCMAKE_INSTALL_PREFIX=$SYMCC_LIBCXX_PATH \ 166 | -DCMAKE_C_COMPILER=$HOME/symcc_build_simple/symcc \ 167 | -DCMAKE_CXX_COMPILER=$HOME/symcc_build_simple/sym++ \ 168 | && ninja distribution \ 169 | && ninja install-distribution 170 | 171 | 172 | # 173 | # Build SymCC Qsym backend 174 | # 175 | FROM builder_symcc_libcxx AS builder_symcc_qsym 176 | RUN mkdir symcc_build \ 177 | && cd symcc_build \ 178 | && cmake -G Ninja ~/symcc_source_main \ 179 | -DLLVM_VERSION_FORCE=$SYMRUSTC_LLVM_VERSION \ 180 | -DQSYM_BACKEND=ON \ 181 | -DCMAKE_BUILD_TYPE=RelWithDebInfo \ 182 | -DZ3_DIR=~/z3_build/dist/lib/cmake/z3 \ 183 | && ninja check 184 | 185 | 186 | # 187 | # Build SymLLVM 188 | # 189 | FROM builder_source AS builder_symllvm 190 | 191 | COPY --chown=ubuntu:ubuntu src/llvm/cmake.sh $SYMRUSTC_HOME/src/llvm/ 192 | 193 | RUN mkdir -p rust_source/build/x86_64-unknown-linux-gnu/llvm/build \ 194 | && cd -P rust_source/build/x86_64-unknown-linux-gnu/llvm/build \ 195 | && $SYMRUSTC_HOME/src/llvm/cmake.sh 196 | 197 | 198 | # 199 | # Build SymRustC core 200 | # 201 | FROM builder_source AS builder_symrustc 202 | 203 | RUN sudo apt-get update \ 204 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 205 | curl \ 206 | && sudo apt-get clean 207 | 208 | # 209 | 210 | COPY --chown=ubuntu:ubuntu --from=builder_symcc_qsym $HOME/symcc_build_simple symcc_build_simple 211 | COPY --chown=ubuntu:ubuntu --from=builder_symcc_qsym $HOME/symcc_build symcc_build 212 | COPY --chown=ubuntu:ubuntu --from=builder_symcc_qsym $HOME/z3_build z3_build 213 | 214 | RUN mkdir -p rust_source/build/x86_64-unknown-linux-gnu 215 | COPY --chown=ubuntu:ubuntu --from=builder_symllvm $HOME/rust_source/build/x86_64-unknown-linux-gnu/llvm rust_source/build/x86_64-unknown-linux-gnu/llvm 216 | 217 | # 218 | 219 | ENV SYMRUSTC_RUNTIME_DIR=$HOME/symcc_build/SymRuntime-prefix/src/SymRuntime-build 220 | 221 | RUN export SYMCC_NO_SYMBOLIC_INPUT=yes \ 222 | && cd rust_source \ 223 | && sed -i -e 's/is_x86_feature_detected!("sse2")/false \&\& &/' \ 224 | compiler/rustc_span/src/analyze_source_file.rs \ 225 | && export SYMCC_RUNTIME_DIR=$SYMRUSTC_RUNTIME_DIR \ 226 | && /usr/bin/python3 ./x.py build --stage 2 227 | 228 | # 229 | 230 | ARG SYMRUSTC_RUST_BUILD=$HOME/rust_source/build/x86_64-unknown-linux-gnu 231 | ARG SYMRUSTC_RUST_BUILD_STAGE=$SYMRUSTC_RUST_BUILD/stage2 232 | 233 | ENV SYMRUSTC_CARGO=$SYMRUSTC_RUST_BUILD/stage0/bin/cargo 234 | ENV SYMRUSTC_RUSTC=$SYMRUSTC_RUST_BUILD_STAGE/bin/rustc 235 | ENV SYMRUSTC_LD_LIBRARY_PATH=$SYMRUSTC_RUST_BUILD_STAGE/lib 236 | ENV PATH=$HOME/.cargo/bin:$PATH 237 | 238 | COPY --chown=ubuntu:ubuntu --from=builder_symcc_libcxx $SYMCC_LIBCXX_PATH $SYMCC_LIBCXX_PATH 239 | 240 | RUN mkdir clang_symcc_on \ 241 | && ln -s ~/symcc_build/symcc clang_symcc_on/clang \ 242 | && ln -s ~/symcc_build/sym++ clang_symcc_on/clang++ 243 | 244 | RUN mkdir clang_symcc_off \ 245 | && ln -s $(which clang-$SYMRUSTC_LLVM_VERSION) clang_symcc_off/clang \ 246 | && ln -s $(which clang++-$SYMRUSTC_LLVM_VERSION) clang_symcc_off/clang++ 247 | 248 | 249 | # 250 | # Build SymRustC main 251 | # 252 | FROM builder_symrustc AS builder_symrustc_main 253 | 254 | RUN sudo apt-get update \ 255 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 256 | bsdmainutils \ 257 | && sudo apt-get clean 258 | 259 | COPY --chown=ubuntu:ubuntu src/rs belcarra_source/src/rs 260 | COPY --chown=ubuntu:ubuntu examples belcarra_source/examples 261 | 262 | 263 | # 264 | # Set up Ubuntu/Rust environment 265 | # 266 | FROM builder_symrustc AS builder_base_rust 267 | 268 | ENV RUSTUP_HOME=$HOME/rustup \ 269 | CARGO_HOME=$HOME/cargo \ 270 | PATH=$HOME/cargo/bin:$PATH \ 271 | RUST_VERSION=1.65.0 272 | 273 | # https://github.com/rust-lang/docker-rust/blob/76e3311a6326bc93a1e96ad7ae06c05763b62b18/1.65.0/bullseye/Dockerfile 274 | RUN set -eux; \ 275 | dpkgArch="$(dpkg --print-architecture)"; \ 276 | case "${dpkgArch##*-}" in \ 277 | amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='5cc9ffd1026e82e7fb2eec2121ad71f4b0f044e88bca39207b3f6b769aaa799c' ;; \ 278 | armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='48c5ecfd1409da93164af20cf4ac2c6f00688b15eb6ba65047f654060c844d85' ;; \ 279 | arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='e189948e396d47254103a49c987e7fb0e5dd8e34b200aa4481ecc4b8e41fb929' ;; \ 280 | i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='0e0be29c560ad958ba52fcf06b3ea04435cb3cd674fbe11ce7d954093b9504fd' ;; \ 281 | *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \ 282 | esac; \ 283 | url="https://static.rust-lang.org/rustup/archive/1.25.1/${rustArch}/rustup-init"; \ 284 | curl -O "$url"; \ 285 | echo "${rustupSha256} *rustup-init" | sha256sum -c -; \ 286 | chmod +x rustup-init; \ 287 | ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch} 288 | 289 | RUN rustup component add rustfmt 290 | 291 | ENV SYMRUSTC_TIMEOUT_DEFAULT=300 292 | ENV SYMRUSTC_LIBAFL_EXAMPLE0=$HOME/belcarra_source/examples/source_0_original_1c3_rs 293 | ENV SYMRUSTC_LIBAFL_EXAMPLE1=$HOME/belcarra_source/examples/source_0_original_1c8_rs 294 | ENV SYMRUSTC_LIBAFL_EXAMPLE2=$HOME/belcarra_source/examples/source_0_original_1c7_rs 295 | ENV SYMRUSTC_LIBAFL_EXAMPLE3=$HOME/belcarra_source/examples/source_0_original_1c9_rs 296 | 297 | 298 | # 299 | # Build LibAFL solving runtime 300 | # 301 | FROM builder_base_rust AS builder_libafl_solving 302 | 303 | ARG SYMRUSTC_CI 304 | 305 | RUN if [[ -v SYMRUSTC_CI ]] ; then \ 306 | echo "Ignoring the execution" >&2; \ 307 | else \ 308 | cargo install cargo-make; \ 309 | fi 310 | 311 | COPY --chown=ubuntu:ubuntu src/rs belcarra_source/src/rs 312 | COPY --chown=ubuntu:ubuntu examples belcarra_source/examples 313 | 314 | # Updating the harness 315 | RUN if [[ -v SYMRUSTC_CI ]] ; then \ 316 | echo "Ignoring the execution" >&2; \ 317 | else \ 318 | cd $SYMRUSTC_LIBAFL_SOLVING_DIR/fuzzer \ 319 | && rm -rf harness; \ 320 | fi 321 | 322 | # Building the blank libsancov 323 | RUN if [[ -v SYMRUSTC_CI ]] ; then \ 324 | echo "Ignoring the execution" >&2; \ 325 | else \ 326 | cd $SYMRUSTC_LIBAFL_SOLVING_DIR \ 327 | && $SYMRUSTC_HOME_RS/libafl_cargo.sh; \ 328 | fi 329 | 330 | 331 | # 332 | # Build LibAFL solving runtime main 333 | # 334 | FROM builder_libafl_solving AS builder_libafl_solving_main 335 | #TODO: use the rustc version of builder_symrustc_main (with instrumentation disabled) whenever it belongs to the versions that can build LibAFL 336 | 337 | RUN sudo apt-get update \ 338 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 339 | # Installing "nc" to later check if a given port is opened or closed 340 | netcat-openbsd \ 341 | psmisc \ 342 | && sudo apt-get clean 343 | 344 | # Pointing to the Rust runtime back-end 345 | RUN cd -P $SYMRUSTC_RUNTIME_DIR/.. \ 346 | && ln -s $SYMRUSTC_LIBAFL_SOLVING_DIR/target/release "$(basename $SYMRUSTC_RUNTIME_DIR)0" 347 | 348 | 349 | # 350 | # Build end user environment 351 | # 352 | FROM builder_libafl_solving_main AS builder_end_user 353 | 354 | ENV PATH=$SYMRUSTC_HOME_RS:$PATH 355 | ENV HOME=/home/user 356 | WORKDIR $HOME 357 | 358 | RUN sudo chown ubuntu:ubuntu $HOME 359 | 360 | 361 | # 362 | # Build end user environment main 363 | # 364 | FROM builder_end_user AS builder_end_user_main 365 | 366 | ARG SYMRUSTC_DIR_COPY 367 | COPY --chown=ubuntu:ubuntu $SYMRUSTC_DIR_COPY $SYMRUSTC_DIR_COPY 368 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. SPDX-License-Identifier 2 | 3 | .. Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 4 | 5 | SymRustC 6 | ******** 7 | 8 | SymRustC is a hybrid fuzzer for Rust combining concolic 9 | execution using `SymCC `_ and 10 | fuzzing using `LibAFL `_. 11 | 12 | Installation 13 | ============ 14 | 15 | We assume that you have Docker installed and this repo is cloned 16 | into \ ``$PWD``\. The execution of \ ``./build_remote.sh``\ will 17 | install SymRustC inside a fresh Docker container, copy some examples 18 | we provide in \ ``$PWD``\ to the container, and open a shell for 19 | the user inside the container. Note that \ ``./build_remote.sh``\ 20 | does not modify anything in \ ``$PWD``\ . In the same spirit, the 21 | Docker container is currently configured to be minimally invasive. 22 | It will be removed once the shell exits: any modifications made inside 23 | it will immediately be lost. One way to make modifications persistent 24 | is to mount a volume folder on the host into the guest container: 25 | `https://docs.docker.com/engine/reference/commandline/run `_. 26 | 27 | \ ``./build_remote.sh``\ downloads an uploaded image 28 | that we have already built using a local \ ``./build_all.sh``\ . At 29 | the time of writing, the upload is manually performed, so some best 30 | efforts have been made for the image to represent one of the latest 31 | versions of the SymRustC project, if not the last. If some network 32 | problems happen during the image retrieval, or to get the most 33 | recent version, one can always execute \ ``./build_all.sh``\ instead 34 | of \ ``./build_remote.sh``\ to get the same result, and be able to run 35 | SymRustC. 36 | 37 | Usage (inside the container's shell) 38 | ====================================== 39 | 40 | SymRustC comes with two main scripts: a pure concolic engine 41 | \ ``symrustc.sh``\ , and a hybrid engine 42 | \ ``symrustc_hybrid.sh``\ . The use of the concolic 43 | engine is not yet documented in this repository, as its design 44 | architecture is being changed: it will be merged at some point with 45 | the source of a sibling repository 46 | `https://github.com/sfu-rsl/symrustc_toolchain `_. 47 | So for a pure concolic usage, we invite the user to refer to 48 | the repo. 49 | 50 | The main hybrid engine \ ``symrustc_hybrid.sh``\ mandatorily takes one 51 | inital input as a parameter, and this input must have at least one 52 | byte (e.g. \ ``test``\ ). The script expects to be executed inside a Rust 53 | project, i.e. inside a directory where one would usually invoke 54 | \ ``cargo build``\ . 55 | 56 | For example, \ ``examples/source_0_original_1c9_rs``\ is a directory 57 | of a Rust project, with a \ ``Cargo.toml``\ at its root: 58 | 59 | .. code:: shell 60 | 61 | cd examples/source_0_original_1c9_rs \ 62 | && symrustc_hybrid.sh test 63 | 64 | Note that the length of the initial input may influence the fuzzing 65 | quality (e.g. speed of the tool to find a potential bug), whereas its 66 | content may be arbitrary. 67 | 68 | Overall, \ ``symrustc_hybrid.sh``\ takes the same options as 69 | \ ``echo``\ . For example, without \ ``-n``\ , giving 70 | \ ``test``\ alone will make the tool receive the 5 bytes input 71 | \ ``test\n``\ , with a newline in the end. 72 | 73 | Understanding the results 74 | ========================= 75 | 76 | Since our SymRustC hybrid tool runs LibAFL in the end, we might get 77 | the same hybrid-search experience than LibAFL. In 78 | particular, we will obtain as output log the same information produced 79 | by LibAFL. As we configured LibAFL to execute 1 server and 2 clients, 80 | the user will find the relevant output information be respectively 81 | stored in \ ``_*_server``\ , \ ``_*_client1``\ and \ ``_*_client2``\ . 82 | 83 | Example: 84 | 85 | .. code:: shell 86 | 87 | ls _*_server _*_client1 _*_client2 88 | 89 | For the most accurate and complete documentation, the user is then 90 | referred to the source of LibAFL: 91 | `https://github.com/AFLplusplus/LibAFL `_, 92 | as well as its generated documentation: 93 | `https://aflplus.plus/libafl-book/ `_. 94 | Note that while we are using a modified version of LibAFL in SymRustC, 95 | all our modifications on LibAFL are only affecting its execution 96 | engine, and not the way it is presenting its output. 97 | 98 | Output lines in \ ``_*_server``\ correspond to regular printing of 99 | the state of the fuzzing printed at regular intervals. The user can 100 | there notice that each line has a field called \ ``objectives``\ , 101 | followed by a natural number. One of the most important information 102 | here is to detect if this \ ``objectives``\ field ever increases. If 103 | so, it means the tool has found a problem, as we configured LibAFL to 104 | make the \ ``objectives``\ be increased whenever our example binary 105 | exits with an error status. 106 | 107 | If the execution of a binary is not successful, it can be of crucial 108 | importance to find out the input making the error happened, as well as 109 | an informative error message following the termination of the 110 | binary. Since all input and output interaction messages are stored in 111 | \ ``_*_client1``\ or \ ``_*_client2``\ , the user is then invited to 112 | open these files. 113 | 114 | Note that, whenever \ ``objectives``\ increases, most of the time the 115 | client files will contain the input and output reports of the 116 | problematic run. However, we also noticed rare situations where none 117 | of the client files are showing the failing execution, despite a 118 | detected positive \ ``objectives``\ number. At the time of writing, 119 | more investigations on LibAFL's source and documentation might be 120 | necessary to understand the reasons and conditions behind this. 121 | 122 | Customizing the hybrid run 123 | ========================== 124 | 125 | Experimenting with a specific timeout 126 | ------------------------------------- 127 | 128 | Using \ ``$SYMRUSTC_TIMEOUT``\ , one can specify a custom timeout in 129 | seconds for \ ``symrustc_hybrid.sh``\ to stop its execution after the 130 | given duration. 131 | 132 | Example: 133 | 134 | .. code:: shell 135 | 136 | cd examples/source_0_original_1c9_rs \ 137 | && SYMRUSTC_TIMEOUT=300 symrustc_hybrid.sh test 138 | 139 | 140 | Experimenting with a local Rust example 141 | --------------------------------------- 142 | 143 | Instead of using the SymRustC examples, one can import some custom 144 | Rust examples from the host to the container, assuming the examples to 145 | import are following particular template and naming conventions, 146 | which are further described below. This is necessary as the examples 147 | to run with our tool need to have a harness and configure LibAFL. 148 | 149 | We provide a minimal template in 150 | `https://github.com/sfu-rsl/LibAFL/blob/rust_runtime_verbose/20221214/fuzzers/libfuzzer_rust_concolic/fuzzer/harness `_, 151 | and invite the user to modify the body of \ ``main0``\ in the file 152 | \ ``src/lib.rs``\ of the directory link. As \ ``main0``\ is called by 153 | our LibAFL plug-in, we only suggest to modify the body of 154 | \ ``main0``\ and not its type. It remains nevertheless possible to 155 | insert additional dependencies to other Rust crates as desired. The 156 | \ ``args``\ parameter of \ ``main0``\ corresponds to the list of 157 | arguments provided from the command line. So, following standard shell 158 | calling conventions, the initial input will be provided by LibAFL at 159 | position 1; position 0 is for the binary name. 160 | 161 | Once the example is defined, importing it to the container can be done 162 | by first putting it inside some folder inside \ ``$PWD``\ . It 163 | has to be inside \ ``$PWD``\ , because a default Docker configuration 164 | would limit the access scope to arbitrary files in the 165 | filesystem. Finally, on the host side, we set the path of that example 166 | folder to the shell variable \ ``$SYMRUSTC_DIR_COPY``\ (the path can 167 | be either absolute or relative to \ ``$PWD``\ ), and we export this 168 | variable before calling \ ``./build_remote.sh``\ . 169 | 170 | Note that it is not mandatory to give the precise root directory of a 171 | Rust project in \ ``$SYMRUSTC_DIR_COPY``\ : any parent ancestor 172 | directory inside \ ``$PWD``\ would work, because the whole content of 173 | \ ``$SYMRUSTC_DIR_COPY``\ will be copied as such inside the 174 | \ ``$HOME``\ folder of the container. 175 | 176 | Example: 177 | 178 | .. code:: shell 179 | 180 | SYMRUSTC_DIR_COPY=$PWD/examples ./build_remote.sh 181 | 182 | Demo video 183 | ========== 184 | `https://www.youtube.com/watch?v=ySIWT2CDi40 `_ 185 | 186 | Limitations 187 | =========== 188 | Since we leverage `SymCC `_ for 189 | concolic execution and `LibAFL `_ 190 | for fuzzing, we inherit their limitations. The most notable limitation 191 | we have observed is that SymCC does not support all LLVM instructions 192 | and the Rust compiler generates a wide variety of LLVM instructions. 193 | This limits the ability to explore the code paths of a Rust program. 194 | 195 | License 196 | ******* 197 | 198 | The contribution part of the project developed at Simon Fraser 199 | University is licensed under the MIT license. 200 | 201 | SPDX-License-Identifier: MIT 202 | 203 | Publication 204 | *********** 205 | 206 | `Frédéric Tuong `_, `Mohammad Omidvar Tehrani `_, `Marco Gaboardi `_, and `Steven Y. Ko `_. 2023. SymRustC: A Hybrid Fuzzer for Rust (Tool Demonstrations Track). In `Proceedings of the 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA '23) `_, July 17–21, 2023, Seattle, WA, USA. ACM, New York, NY, USA, 4 pages. `https://doi.org/10.1145/3597926.3604927 `_ 207 | -------------------------------------------------------------------------------- /build_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source git_current_branch.sh 9 | 10 | name="$(basename $PWD)_log_${hash}__" 11 | 12 | function tee_log () { 13 | fic="../$name$(date '+%F_%T' | tr -d ':-')" 14 | if [ ! -f "$fic" ] ; then 15 | tee "$fic" 16 | date -R >> "$fic" 17 | else 18 | exit 1 19 | fi 20 | } 21 | 22 | # 23 | 24 | ./build_all_sudo.sh "$SYMRUSTC_BRANCH" "$SYMRUSTC_DIR_COPY" 25 | sudo_docker_if_needed tag belcarra_end_user ghcr.io/sfu-rsl/symrustc_hybrid:latest 26 | if [[ -v SYMRUSTC_DOCKER_PUSH ]] ; then 27 | # echo $TOKEN_GHCR | sudo_if_needed docker login ghcr.io -u $USER --password-stdin 28 | sudo_docker_if_needed push ghcr.io/sfu-rsl/symrustc_hybrid:latest 29 | fi 30 | sudo_docker_if_needed run -it --rm belcarra_$(tac generated/build.sh | grep -m 1 docker | tr ' ' '\n' | tail -n 1) 31 | -------------------------------------------------------------------------------- /build_all_sudo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | export SYMRUSTC_BRANCH="$1"; shift 9 | export SYMRUSTC_DIR_COPY="$1"; shift 10 | 11 | unit=G 12 | size=$(echo $(df -B"$unit" --output=avail $(sudo_docker_if_needed info | grep 'Root' | cut -d ':' -f 2) | tail -n 1)) 13 | 14 | if (( $(echo "$size" | cut -d "$unit" -f 1) < 30 )) ; then 15 | echo "Error: too low remaining disk space: $size" >&2 16 | exit 1 17 | fi 18 | 19 | function docker_b0 () { 20 | sudo_docker_if_needed build "$@" 21 | } 22 | export -f docker_b0 23 | 24 | # 25 | 26 | function docker_b () { 27 | docker_b0 --target "builder_$1" -t "belcarra_$1" --build-arg SYMRUSTC_BRANCH="$SYMRUSTC_BRANCH" --build-arg SYMRUSTC_DIR_COPY="$SYMRUSTC_DIR_COPY" --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes . 28 | } 29 | export -f docker_b 30 | 31 | ./generated/build.sh 32 | 33 | # 34 | 35 | # function docker_b () { 36 | # docker_b0 "$@" 37 | # } 38 | # export -f docker_b 39 | 40 | # ./build_rustc.sh 41 | -------------------------------------------------------------------------------- /build_remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source git_current_branch.sh 9 | 10 | img=end_user_main 11 | 12 | SYMRUSTC_SOURCE=ghcr.io/sfu-rsl/symrustc_hybrid 13 | 14 | sudo_docker_if_needed pull $SYMRUSTC_SOURCE 15 | sudo_docker_if_needed build -f symrustc.Dockerfile --target builder_$img -t belcarra_$img --build-arg SYMRUSTC_SOURCE=$SYMRUSTC_SOURCE --build-arg SYMRUSTC_DIR_COPY=$SYMRUSTC_DIR_COPY . 16 | sudo_docker_if_needed run -it --rm belcarra_$img 17 | -------------------------------------------------------------------------------- /build_rustc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | RUST_SOURCE=builder_rustc_source 9 | 10 | docker_b --target builder_source -t $RUST_SOURCE --build-arg SYMRUSTC_RUST_VERSION="$(echo "$SYMRUSTC_BRANCH" | rev | cut -d '/' -f 1 | rev)" . 11 | docker_b -f rustc.Dockerfile --build-arg RUST_SOURCE=$RUST_SOURCE . 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c0_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c0_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c0_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* The LLVM code obtained from this program would ideally be as close 2 | as possible to the one obtained from: 3 | https://github.com/eurecom-s3/symcc/blob/master/sample.cpp 4 | */ 5 | 6 | use std::ffi::OsString; 7 | use std::fs; 8 | use std::io::Error; 9 | 10 | fn main00(mut args : impl Iterator) -> Result<(), Error> { 11 | match args.next() { 12 | Some(_) => { 13 | match args.next() { 14 | Some(file) => { 15 | let buf = fs::read(file).expect("Error reading the file"); 16 | let buf_len = buf.len(); 17 | let delim = b"\n"; 18 | println!("What's your name?"); 19 | let root1 = b"r"; 20 | let root1_len = root1.len(); 21 | let root2 = b"ro"; 22 | let root2_len = root2.len(); 23 | let root3a = b"roo"; 24 | let root3a_len = root3a.len(); 25 | let root4a = b"root"; 26 | let root4a_len = root4a.len(); 27 | let root3b = b"roa"; 28 | let root3b_len = root3b.len(); 29 | let root4b = b"road"; 30 | let root4b_len = root4b.len(); 31 | if buf_len > root1_len && buf[0 .. root1_len] == *root1 { 32 | if buf_len > root2_len && buf[0 .. root2_len] == *root2 { 33 | if buf_len > root3a_len && buf[0 .. root3a_len] == *root3a { 34 | if buf[0 .. root4a_len] == *root4a 35 | && if buf_len == root4a_len { true } 36 | else if buf_len == root4a_len + 1 { buf.ends_with(delim) } 37 | else { false } { 38 | print!("What is your command (A)? ("); 39 | for c in &buf { 40 | print!(" {:#04x}", c) 41 | } 42 | println!(" )"); 43 | panic!("Artificial bug (A)") 44 | } else { 45 | print!("Hello 4a, ("); 46 | for c in &buf { 47 | print!(" {:#04x}", c) 48 | } 49 | println!(" ) {:?}!", String::from_utf8_lossy(&buf)) 50 | } 51 | } else { 52 | if buf_len > root3b_len && buf[0 .. root3b_len] == *root3b { 53 | if buf[0 .. root4b_len] == *root4b 54 | && if buf_len == root4b_len { true } 55 | else if buf_len == root4b_len + 1 { buf.ends_with(delim) } 56 | else { false } { 57 | print!("What is your command (B)? ("); 58 | for c in &buf { 59 | print!(" {:#04x}", c) 60 | } 61 | println!(" )"); 62 | panic!("Artificial bug (B)") 63 | } else { 64 | print!("Hello 4b, ("); 65 | for c in &buf { 66 | print!(" {:#04x}", c) 67 | } 68 | println!(" ) {:?}!", String::from_utf8_lossy(&buf)) 69 | } 70 | } else { 71 | print!("Hello 3, ("); 72 | for c in &buf { 73 | print!(" {:#04x}", c) 74 | } 75 | println!(" ) {:?}!", String::from_utf8_lossy(&buf)) 76 | } 77 | } 78 | } else { 79 | print!("Hello 2, ("); 80 | for c in &buf { 81 | print!(" {:#04x}", c) 82 | } 83 | println!(" ) {:?}!", String::from_utf8_lossy(&buf)) 84 | } 85 | } else { 86 | print!("Hello 1, ("); 87 | for c in &buf { 88 | print!(" {:#04x}", c) 89 | } 90 | println!(" ) {:?}!", String::from_utf8_lossy(&buf)) 91 | } 92 | Ok(()) 93 | } 94 | None => Ok(()) 95 | } 96 | } 97 | None => Ok(()) 98 | } 99 | } 100 | 101 | pub fn main0(args : Vec) -> Result<(), Error> { 102 | main00(args.iter().cloned()) 103 | } 104 | -------------------------------------------------------------------------------- /examples/source_0_original_1c0_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c1_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c1_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | uu_sort = "0.0.18" -------------------------------------------------------------------------------- /examples/source_0_original_1c1_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::io::Error; 3 | use uu_sort; 4 | 5 | pub fn main0(args : Vec) -> Result<(), Error> { 6 | match uu_sort::uumain(args.iter().cloned()) { 7 | 0 => Ok(()), 8 | code => { 9 | eprintln!("Error exit code: {:?}", code); 10 | Ok(()) 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/source_0_original_1c1_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c2_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c2_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c2_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | /* The LLVM code obtained from this program would ideally be as close 2 | as possible to the one obtained from: 3 | https://github.com/eurecom-s3/symcc/blob/master/sample.cpp 4 | */ 5 | 6 | use std::ffi::OsString; 7 | use std::fs; 8 | use std::io::Error; 9 | 10 | fn main00(mut args : impl Iterator) -> Result<(), Error> { 11 | match args.next() { 12 | Some(_) => { 13 | match args.next() { 14 | Some(file) => { 15 | let buf = fs::read(file).expect("Error reading the file"); 16 | let s = String::from_utf8_lossy(&buf); 17 | if s == "root" { 18 | panic!("Artificial bug (A)") 19 | } else { 20 | print!("Hello ("); 21 | for c in &buf { 22 | print!(" {:#04x}", c) 23 | } 24 | println!(" ) {:?}!", s) 25 | } 26 | Ok(()) 27 | } 28 | None => Ok(()) 29 | } 30 | } 31 | None => Ok(()) 32 | } 33 | } 34 | 35 | pub fn main0(args : Vec) -> Result<(), Error> { 36 | main00(args.iter().cloned()) 37 | } 38 | -------------------------------------------------------------------------------- /examples/source_0_original_1c2_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | csscolorparser = "=0.5.0" -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra-fuzz" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2018" 6 | 7 | [package.metadata] 8 | cargo-fuzz = true 9 | 10 | [dependencies] 11 | libfuzzer-sys = "0.4" 12 | csscolorparser = "=0.5.0" 13 | 14 | [dependencies.belcarra] 15 | path = ".." 16 | 17 | # Prevent this from interfering with workspaces 18 | [workspace] 19 | members = ["."] 20 | 21 | [profile.release] 22 | debug = 1 23 | 24 | [[bin]] 25 | name = "fuzz_target_1" 26 | path = "fuzz_targets/fuzz_target_1.rs" 27 | test = false 28 | doc = false 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/fuzz/fuzz_targets/fuzz_target_1.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use bel; 4 | use libfuzzer_sys::fuzz_target; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | bel::fuzz_target(data); 8 | }); 9 | -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | pub fn fuzz_target(data : &[u8]) -> Result<(), Error> { 6 | let data = String::from_utf8_lossy(&data); 7 | csscolorparser::parse(&data); 8 | Ok(()) 9 | } 10 | 11 | pub fn main0(args : Vec) -> Result<(), Error> { 12 | match args.get(1) { 13 | Some(file) => { 14 | let data = fs::read(file).expect("Error reading the file"); 15 | fuzz_target(&data) 16 | } 17 | None => Ok(()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/source_0_original_1c3_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c4_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c4_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | lz4 = "1.23.2" 13 | lz4_flex = "=0.3.5" 14 | -------------------------------------------------------------------------------- /examples/source_0_original_1c4_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | use lz4_flex::block::decompress::decompress_size_prepended; 6 | use lz4::block::compress as lz4_linked_block_compress; 7 | 8 | fn main00(mut args : impl Iterator) -> Result<(), Error> { 9 | match args.next() { 10 | Some(_) => { 11 | match args.next() { 12 | Some(file) => { 13 | let data = fs::read(file).expect("Error reading the file"); 14 | let compressed = lz4_linked_block_compress(&data, None, true).unwrap(); 15 | let decompressed = decompress_size_prepended(&compressed).unwrap(); 16 | assert_eq!(data, decompressed); 17 | Ok(()) 18 | } 19 | None => Ok(()) 20 | } 21 | } 22 | None => Ok(()) 23 | } 24 | } 25 | 26 | pub fn main0(args : Vec) -> Result<(), Error> { 27 | main00(args.iter().cloned()) 28 | } 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c4_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c5_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c5_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | human_name = "=1.3.0" 13 | -------------------------------------------------------------------------------- /examples/source_0_original_1c5_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | fn main00(mut args : impl Iterator) -> Result<(), Error> { 6 | match args.next() { 7 | Some(_) => { 8 | match args.next() { 9 | Some(file) => { 10 | let buf = fs::read(file).expect("Error reading the file"); 11 | let s = String::from_utf8_lossy(&buf); 12 | human_name::Name::parse(&s); 13 | Ok(()) 14 | } 15 | None => Ok(()) 16 | } 17 | } 18 | None => Ok(()) 19 | } 20 | } 21 | 22 | pub fn main0(args : Vec) -> Result<(), Error> { 23 | main00(args.iter().cloned()) 24 | } 25 | -------------------------------------------------------------------------------- /examples/source_0_original_1c5_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c6_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c6_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | chrono = "=0.4.19" -------------------------------------------------------------------------------- /examples/source_0_original_1c6_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | use chrono; 6 | 7 | fn main00(mut args : impl Iterator) -> Result<(), Error> { 8 | match args.next() { 9 | Some(_) => { 10 | match args.next() { 11 | Some(file) => { 12 | let buf = fs::read(file).expect("Error reading the file"); 13 | let s = String::from_utf8_lossy(&buf); 14 | chrono::DateTime::parse_from_rfc2822(&s); 15 | // https://github.com/chronotope/chrono/commit/ad03bcbdcb27c7010c21fca0f8a3440b69e994fc 16 | // "31 DEC 262143 23:59 -2359" 17 | Ok(()) 18 | } 19 | None => Ok(()) 20 | } 21 | } 22 | None => Ok(()) 23 | } 24 | } 25 | 26 | pub fn main0(args : Vec) -> Result<(), Error> { 27 | main00(args.iter().cloned()) 28 | } 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c6_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | libflate = "=1.1.1" -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra-fuzz" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2018" 6 | 7 | [package.metadata] 8 | cargo-fuzz = true 9 | 10 | [dependencies] 11 | libfuzzer-sys = "0.4" 12 | libflate = "=1.1.1" 13 | 14 | [dependencies.belcarra] 15 | path = ".." 16 | 17 | # Prevent this from interfering with workspaces 18 | [workspace] 19 | members = ["."] 20 | 21 | [profile.release] 22 | debug = 1 23 | 24 | [[bin]] 25 | name = "fuzz_target_1" 26 | path = "fuzz_targets/fuzz_target_1.rs" 27 | test = false 28 | doc = false 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/fuzz/fuzz_targets/fuzz_target_1.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use bel; 4 | use libfuzzer_sys::fuzz_target; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | bel::fuzz_target(data); 8 | }); 9 | -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | // https://github.com/sile/libflate/issues/64 6 | // b"\x04\x04\x04\x05:\x1az*\xfc\x06\x01\x90\x01\x06\x01" 7 | pub fn fuzz_target(data : &[u8]) -> Result<(), Error> { 8 | use libflate::deflate::{Decoder}; 9 | 10 | let mut decoder = Decoder::new(&data[..]); 11 | std::io::copy(&mut decoder, &mut std::io::sink()); 12 | Ok(()) 13 | } 14 | 15 | pub fn main0(args : Vec) -> Result<(), Error> { 16 | match args.get(1) { 17 | Some(file) => { 18 | let data = fs::read(file).expect("Error reading the file"); 19 | fuzz_target(&data) 20 | } 21 | None => Ok(()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/source_0_original_1c7_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | mp4ameta = "=0.11.0" -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra-fuzz" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2018" 6 | 7 | [package.metadata] 8 | cargo-fuzz = true 9 | 10 | [dependencies] 11 | libfuzzer-sys = "0.4" 12 | mp4ameta = "=0.11.0" 13 | 14 | [dependencies.belcarra] 15 | path = ".." 16 | 17 | # Prevent this from interfering with workspaces 18 | [workspace] 19 | members = ["."] 20 | 21 | [profile.release] 22 | debug = 1 23 | 24 | [[bin]] 25 | name = "fuzz_target_1" 26 | path = "fuzz_targets/fuzz_target_1.rs" 27 | test = false 28 | doc = false 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/fuzz/fuzz_targets/fuzz_target_1.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use bel; 4 | use libfuzzer_sys::fuzz_target; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | bel::fuzz_target(data); 8 | }); 9 | -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | // https://github.com/Saecki/mp4ameta/issues/25 6 | // [0, 0, 0, 1, 102, 116, 121, 112, 0, 132, 255, 255, 255, 255, 0, 132] 7 | pub fn fuzz_target(data : &[u8]) -> Result<(), Error> { 8 | use mp4ameta; 9 | 10 | let mut data = std::io::Cursor::new(data); 11 | mp4ameta::Tag::read_from(&mut data); 12 | Ok(()) 13 | } 14 | 15 | pub fn main0(args : Vec) -> Result<(), Error> { 16 | match args.get(1) { 17 | Some(file) => { 18 | let data = fs::read(file).expect("Error reading the file"); 19 | fuzz_target(&data) 20 | } 21 | None => Ok(()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/source_0_original_1c8_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | name = "bel" 10 | 11 | [dependencies] 12 | bincode = "=2.0.0-beta.0" -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/README.md: -------------------------------------------------------------------------------- 1 | This fuzz folder is supposed to be created by running `cargo fuzz init` in the root folder of `bincode`. 2 | 3 | The aim is to regenerate the error fixed in bincode-org/bincode#465. So, we checkout at [v2.0.0-beta.0](https://github.com/bincode-org/bincode/tree/v2.0.0-beta.0), where the problem is not fixed (and no fuzzer folder exists neither). 4 | 5 | If you are interested in performing the fuzzing using libAFL and SymRustC take a look at [this gist](https://gist.github.com/momvart/4c10d5856ec45e4364780d79fbf0d181) which demonstrates how to integrate them with the `libfuzzer_rust_concolic_instance`, 6 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "belcarra-fuzz" 3 | version = "0.0.0" 4 | publish = false 5 | edition = "2018" 6 | 7 | [package.metadata] 8 | cargo-fuzz = true 9 | 10 | [dependencies] 11 | libfuzzer-sys = "0.4" 12 | bincode = "=2.0.0-beta.0" 13 | 14 | [dependencies.belcarra] 15 | path = ".." 16 | 17 | # Prevent this from interfering with workspaces 18 | [workspace] 19 | members = ["."] 20 | 21 | [profile.release] 22 | debug = 1 23 | 24 | [[bin]] 25 | name = "fuzz_target_1" 26 | path = "fuzz_targets/fuzz_target_1.rs" 27 | test = false 28 | doc = false 29 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/fuzz/fuzz_targets/fuzz_target_1.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use bel; 4 | use libfuzzer_sys::fuzz_target; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | bel::fuzz_target(data); 8 | }); 9 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::ffi::OsString; 2 | use std::fs; 3 | use std::io::Error; 4 | 5 | pub fn fuzz_target(data : &[u8]) -> Result<(), Error> { 6 | use std::convert::TryInto; 7 | use std::mem::size_of; 8 | use std::time::Duration; 9 | 10 | if data.len() != size_of::() + size_of::() { 11 | return Ok(()); 12 | } 13 | let (secs, nanos) = data.split_at(size_of::()); 14 | 15 | let mut buffer = [0u8; 14]; 16 | let secs = u64::from_ne_bytes(unsafe { secs.try_into().unwrap_unchecked() }); 17 | let nanos = u32::from_ne_bytes(unsafe { nanos.try_into().unwrap_unchecked() }); 18 | 19 | bincode::encode_into_slice( 20 | &(secs, nanos), 21 | &mut buffer, 22 | bincode::config::Configuration::standard(), 23 | ) 24 | .unwrap(); 25 | 26 | let result: Result<(Duration, usize), _> = 27 | bincode::decode_from_slice(&buffer, bincode::config::Configuration::standard()); 28 | 29 | if let Ok((dur, _)) = result { 30 | if let Some(input_dur) = Duration::checked_add( 31 | Duration::from_secs(secs), 32 | Duration::from_nanos(nanos as u64), 33 | ) { 34 | assert_eq!(dur, input_dur); 35 | } 36 | }; 37 | Ok(()) 38 | } 39 | 40 | pub fn main0(args : Vec) -> Result<(), Error> { 41 | match args.get(1) { 42 | Some(file) => { 43 | let data = fs::read(file).expect("Error reading the file"); 44 | fuzz_target(&data) 45 | } 46 | None => Ok(()) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /examples/source_0_original_1c9_rs/src/main.rs: -------------------------------------------------------------------------------- 1 | use bel; 2 | use std::env; 3 | use std::io::Error; 4 | 5 | fn main() -> Result<(), Error> { 6 | let args: Vec = env::args().collect(); 7 | match args.get(1) { 8 | Some(file) => bel::main0(vec!["".into(), file.into()]), 9 | None => Ok(()) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generated/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Set up Ubuntu environment 6 | docker_b base 7 | 8 | # Set up project source 9 | docker_b source 10 | 11 | # Set up project dependencies 12 | docker_b depend 13 | 14 | # Build AFL 15 | docker_b afl 16 | 17 | # Build SymCC simple backend 18 | docker_b symcc_simple 19 | 20 | # Build LLVM libcxx using SymCC simple backend 21 | docker_b symcc_libcxx 22 | 23 | # Build SymCC Qsym backend 24 | docker_b symcc_qsym 25 | 26 | # Build SymLLVM 27 | docker_b symllvm 28 | 29 | # Build SymRustC core 30 | docker_b symrustc 31 | 32 | # Build SymRustC main 33 | docker_b symrustc_main 34 | 35 | # Set up Ubuntu/Rust environment 36 | docker_b base_rust 37 | 38 | # Build LibAFL solving runtime 39 | docker_b libafl_solving 40 | 41 | # Build LibAFL solving runtime main 42 | docker_b libafl_solving_main 43 | 44 | # Build end user environment 45 | docker_b end_user 46 | 47 | # Build end user environment main 48 | docker_b end_user_main 49 | 50 | -------------------------------------------------------------------------------- /git_current_branch.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | err=0 7 | hash="$(git log -1 --pretty=format:%H)" || err="$?" 8 | 9 | if (( "$err" )); then 10 | if (( $# >= 1 )) ; then 11 | SYMRUSTC_BRANCH="$1"; shift 12 | else 13 | exit "$err" 14 | fi 15 | else 16 | SYMRUSTC_BRANCH="$(git branch --contains "$hash" | grep '*' | cut -d ' ' -f 2-)" 17 | fi 18 | 19 | if [[ ! -v SYMRUSTC_DIR_COPY ]] ; then 20 | SYMRUSTC_DIR_COPY=examples 21 | else 22 | SYMRUSTC_DIR_COPY="$(realpath -e "$SYMRUSTC_DIR_COPY")" 23 | if [[ ! -d "$SYMRUSTC_DIR_COPY" ]] ; then 24 | echo "Error: Expecting a directory" >&2 25 | exit 1 26 | fi 27 | SYMRUSTC_DIR_COPY="$(echo "${SYMRUSTC_DIR_COPY#"$(pwd -P)/"}" | cut -d '/' -f 1)" 28 | if [[ -z "$SYMRUSTC_DIR_COPY" ]] ; then 29 | echo "Warning: Expecting a local directory" >&2 30 | SYMRUSTC_DIR_COPY=examples 31 | fi 32 | fi 33 | 34 | # https://github.com/project-oak/rust-verification-tools/pull/140 35 | function sudo_docker_if_needed () { 36 | fic=/var/run/docker.sock 37 | if [[ -w $fic ]] ; then 38 | docker "$@" 39 | else 40 | echo "Running docker with sudo for writing to $fic" >&2 41 | echo 'See also the security implications of adding someone to the docker group:' >&2 42 | echo 'https://docs.docker.com/engine/security/#docker-daemon-attack-surface' >&2 43 | # https://docs.docker.com/engine/install/linux-postinstall/ 44 | sudo docker "$@" 45 | fi 46 | } 47 | export -f sudo_docker_if_needed 48 | -------------------------------------------------------------------------------- /git_rebase_versions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | remote="$(git remote)" 9 | 10 | function echo_read () { 11 | set +x 12 | echo -n "$1" 13 | read 14 | set -x 15 | } 16 | 17 | function generate () { 18 | ./make_build.sh 19 | git add .github/workflows/build.yml generated/build.sh 20 | git commit --fixup HEAD 21 | git rebase -i --autosquash --autostash HEAD~2 22 | } 23 | 24 | function git_rebase_push () { 25 | local br1=$1; shift 26 | local br2=$1; shift 27 | local count=$1; shift 28 | 29 | err=0 30 | git rebase --onto ${br1} ${br2}~${count} ${br2} || err=$? 31 | if (( err )); then 32 | echo_read "Error: rebase ($err). Conflict resolved? If yes, continue? " 33 | fi 34 | if [[ -v SYMRUSTC_GENERATE ]] || [[ -v SYMRUSTC_GENERATE_INTERACTIVE ]] ; then 35 | git checkout ${br2} 36 | if [[ -v SYMRUSTC_GENERATE_INTERACTIVE ]] ; then 37 | if zenity --info --title 'bool' --text "${br2}: update the generated files?" ; then 38 | generate 39 | fi 40 | else 41 | generate 42 | fi 43 | fi 44 | 45 | git push --force-with-lease "$remote" ${br2} 46 | } 47 | 48 | declare -a git_count=() 49 | 50 | version1z=1.46.0 51 | version2z=full_runtime/$version1z 52 | version3z=verbose/$version1z 53 | version4z=hybrid/$version1z 54 | version5z=extended_examples_verbose/$version1z 55 | version1a=1.55.0 56 | version2a=rust_runtime/$version1a 57 | version3a=symrustc_tools/$version1a 58 | version1b=1.66.1 59 | version1c=extended_examples/$version1b 60 | version1d=extended_examples_ex_image/$version1b 61 | version2d=extended_examples_verbose/$version1b 62 | version1e=extended_examples_verbose_demo/$version1b 63 | version1f=end_user/$version1b 64 | 65 | versions0=( ubuntu_20_04/1.47.0 \ 66 | 1.47.0 ) 67 | versions1=( 1.48.0 \ 68 | 1.49.0 \ 69 | 1.50.0 \ 70 | 1.51.0 \ 71 | 1.52.1 \ 72 | 1.53.0 \ 73 | 1.54.0 \ 74 | $version1a \ 75 | 1.56.1 \ 76 | 1.57.0 \ 77 | 1.58.1 \ 78 | 1.59.0 \ 79 | 1.60.0 \ 80 | 1.61.0 \ 81 | 1.62.1 \ 82 | 1.63.0 \ 83 | 1.64.0 \ 84 | ubuntu_20_10/1.64.0 \ 85 | 1.65.0 \ 86 | $version1b \ 87 | 1.67.1 ) 88 | 89 | # 90 | 91 | git_count+=("$(git rev-list --count ^"$remote/$version1z" "$remote/$version2z")") 92 | git_count+=("$(git rev-list --count ^"$remote/$version1z" "$remote/$version3z")") 93 | git_count+=("$(git rev-list --count ^"$remote/$version1z" "$remote/$version4z")") 94 | git_count+=("$(git rev-list --count ^"$remote/$version1z" "$remote/$version5z")") 95 | 96 | br1=$version1z 97 | for br2 in "${versions0[@]}" 98 | do 99 | git_count+=("$(git rev-list --count ^"$remote/$br1" "$remote/$br2")") 100 | br1=${br2} 101 | done 102 | br0=${br1} 103 | for br2 in "${versions1[@]}" 104 | do 105 | git_count+=("$(git rev-list --count ^"$remote/$br1" "$remote/$br2")") 106 | br1=${br2} 107 | done 108 | br1=${br0} 109 | for br2 in "${versions1[@]}" 110 | do 111 | br2="no_insert/${br2}" 112 | git_count+=("$(git rev-list --count ^"$remote/$br1" "$remote/$br2")") 113 | br1=${br2} 114 | done 115 | git_count+=("$(git rev-list --count ^"$remote/no_insert/$version1a" "$remote/$version2a")") 116 | git_count+=("$(git rev-list --count ^"$remote/no_insert/$version1a" "$remote/$version3a")") 117 | git_count+=("$(git rev-list --count ^"$remote/no_insert/$version1b" "$remote/$version1c")") 118 | git_count+=("$(git rev-list --count ^"$remote/$version1c" "$remote/$version1d")") 119 | git_count+=("$(git rev-list --count ^"$remote/$version1c" "$remote/$version2d")") 120 | git_count+=("$(git rev-list --count ^"$remote/$version2d" "$remote/$version1e")") 121 | git_count+=("$(git rev-list --count ^"$remote/$version1e" "$remote/$version1f")") 122 | 123 | # 124 | 125 | git push --force-with-lease "$remote" $version1z 126 | 127 | # 128 | 129 | git_rebase_push $version1z $version2z "${git_count[0]}"; git_count=("${git_count[@]:1}") 130 | git_rebase_push $version1z $version3z "${git_count[0]}"; git_count=("${git_count[@]:1}") 131 | git_rebase_push $version1z $version4z "${git_count[0]}"; git_count=("${git_count[@]:1}") 132 | git_rebase_push $version1z $version5z "${git_count[0]}"; git_count=("${git_count[@]:1}") 133 | 134 | br1=$version1z 135 | for br2 in "${versions0[@]}" 136 | do 137 | git_rebase_push $br1 $br2 "${git_count[0]}"; git_count=("${git_count[@]:1}") 138 | br1=${br2} 139 | done 140 | br0=${br1} 141 | for br2 in "${versions1[@]}" 142 | do 143 | git_rebase_push $br1 $br2 "${git_count[0]}"; git_count=("${git_count[@]:1}") 144 | br1=${br2} 145 | done 146 | br1=${br0} 147 | for br2 in "${versions1[@]}" 148 | do 149 | br2="no_insert/${br2}" 150 | git_rebase_push $br1 $br2 "${git_count[0]}"; git_count=("${git_count[@]:1}") 151 | br1=${br2} 152 | done 153 | git_rebase_push no_insert/$version1a $version2a "${git_count[0]}"; git_count=("${git_count[@]:1}") 154 | git_rebase_push no_insert/$version1a $version3a "${git_count[0]}"; git_count=("${git_count[@]:1}") 155 | git_rebase_push no_insert/$version1b $version1c "${git_count[0]}"; git_count=("${git_count[@]:1}") 156 | git_rebase_push $version1c $version1d "${git_count[0]}"; git_count=("${git_count[@]:1}") 157 | git_rebase_push $version1c $version2d "${git_count[0]}"; git_count=("${git_count[@]:1}") 158 | git_rebase_push $version2d $version1e "${git_count[0]}"; git_count=("${git_count[@]:1}") 159 | git_rebase_push $version1e $version1f "${git_count[0]}"; git_count=("${git_count[@]:1}") 160 | 161 | # 162 | 163 | git checkout $version1z 164 | -------------------------------------------------------------------------------- /make_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | source git_current_branch.sh 9 | 10 | function parse_dockerfile () { 11 | (echo ; grep -B 2 FROM Dockerfile) | while read 12 | do 13 | read name 14 | read 15 | read run 16 | "$1" "${name:2}" "$(echo "$run" | cut -d ' ' -f 4)" 17 | done 18 | } 19 | 20 | function print_yml () { 21 | echo ' - name: '"$1" 22 | echo -n ' run: ' 23 | echo 'docker build --target '"$2"' -t belcarra_'"$(echo "$2" | cut -d _ -f 2-)"' --build-arg SYMRUSTC_CI=yes --build-arg SYMRUSTC_VERBOSE=true --build-arg SYMRUSTC_BRANCH='"'""$SYMRUSTC_BRANCH""'"' --build-arg SYMRUSTC_DIR_COPY='"'""$SYMRUSTC_DIR_COPY""'"' --build-arg SYMRUSTC_SKIP_FAIL=yes --build-arg SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING=yes .' 24 | echo 25 | } 26 | 27 | function print_sh () { 28 | echo '# '"$1" 29 | echo 'docker_b '"$(echo "$2" | cut -d _ -f 2-)" 30 | echo 31 | } 32 | 33 | fic='.github/workflows/build.yml' 34 | cat > "$fic" <> "$fic" 44 | 45 | fic='generated/build.sh' 46 | cat > "$fic" <<"EOF" 47 | #!/bin/bash 48 | 49 | set -euo pipefail 50 | 51 | EOF 52 | parse_dockerfile print_sh >> "$fic" 53 | -------------------------------------------------------------------------------- /rustc.Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier 2 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 3 | 4 | 5 | # 6 | # Build Rust compiler 7 | # 8 | ARG RUST_SOURCE 9 | FROM $RUST_SOURCE 10 | 11 | RUN sudo apt-get update \ 12 | && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ 13 | curl \ 14 | && sudo apt-get clean 15 | 16 | RUN cd rust_source \ 17 | && /usr/bin/python3 ./x.py build 18 | 19 | ARG SYMRUSTC_RUST_BUILD=$HOME/rust_source/build/x86_64-unknown-linux-gnu 20 | ARG SYMRUSTC_RUST_BUILD_STAGE=$SYMRUSTC_RUST_BUILD/stage1 21 | 22 | ENV SYMRUSTC_CARGO=$SYMRUSTC_RUST_BUILD/stage0/bin/cargo 23 | ENV SYMRUSTC_RUSTC=$SYMRUSTC_RUST_BUILD_STAGE/bin/rustc 24 | ENV SYMRUSTC_LD_LIBRARY_PATH=$SYMRUSTC_RUST_BUILD_STAGE/lib 25 | ENV PATH=$HOME/.cargo/bin:$PATH 26 | 27 | -------------------------------------------------------------------------------- /src/cpp/fold_exec_clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/exec/clang++ 12 | 13 | pushd generated/exec/clang++ 14 | clang++-$SYMRUSTC_LLVM_VERSION "$@" ../../../sample.cpp 15 | popd 16 | 17 | popd 18 | done 19 | -------------------------------------------------------------------------------- /src/cpp/fold_exec_ko-clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/exec/ko-clang++ 12 | 13 | pushd generated/exec/ko-clang++ 14 | ../../../../../../bin/ko-clang++ "$@" ../../../sample.cpp 15 | popd 16 | 17 | popd 18 | done 19 | -------------------------------------------------------------------------------- /src/cpp/fold_exec_sym++_qsym.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | rm -f /tmp/output/* 9 | 10 | for dir in source*cpp 11 | do 12 | pushd "$dir" 13 | mkdir -p generated/exec/sym++_qsym/sample_input 14 | 15 | pushd generated/exec/sym++_qsym 16 | ~/symcc_build/sym++ "$@" ../../../sample.cpp 17 | echo test | (./sample || true) 2>&1 | tee output 18 | csplit -f output_split output '/_sym_push_path_constraint /' '{*}' 19 | if [[ $(ls output_split?* | wc -l) == "1" ]] 20 | then 21 | rm output_split00 22 | else 23 | grep 'New testcase' output_split* > output0 24 | fi 25 | mv /tmp/output/* sample_input || rmdir sample_input 26 | popd 27 | popd 28 | done 29 | -------------------------------------------------------------------------------- /src/cpp/fold_exec_sym++_simple_z3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/exec/sym++_simple_z3 12 | 13 | pushd generated/exec/sym++_simple_z3 14 | ~/symcc_build_simple/sym++ "$@" ../../../sample.cpp 15 | echo test | (./sample || true) 2>&1 | tee output 16 | csplit -f output_split output '/_sym_push_path_constraint /' '{*}' 17 | if [[ $(ls output_split?* | wc -l) == "1" ]] 18 | then 19 | rm output_split00 20 | else 21 | grep 'diverging input' output_split* > output0 22 | fi 23 | popd 24 | popd 25 | done 26 | -------------------------------------------------------------------------------- /src/cpp/fold_llvm_clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/llvm/clang++ 12 | 13 | pushd generated/llvm/clang++ 14 | clang++-$SYMRUSTC_LLVM_VERSION -S -emit-llvm "$@" ../../../sample.cpp 15 | popd 16 | 17 | popd 18 | done 19 | -------------------------------------------------------------------------------- /src/cpp/fold_llvm_ko-clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/llvm/ko-clang++ 12 | 13 | pushd generated/llvm/ko-clang++ 14 | ../../../../../../bin/ko-clang++ -S -emit-llvm "$@" ../../../sample.cpp 15 | popd 16 | 17 | popd 18 | done 19 | -------------------------------------------------------------------------------- /src/cpp/fold_llvm_sym++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | for dir in source*cpp 9 | do 10 | pushd "$dir" 11 | mkdir -p generated/llvm/clang++_isystem 12 | 13 | pushd generated/llvm/clang++_isystem 14 | clang++-$SYMRUSTC_LLVM_VERSION \ 15 | -isystem ~/libcxx_symcc_install/include/c++/v1 \ 16 | -stdlib=libc++ \ 17 | -S -emit-llvm "$@" ../../../sample.cpp 18 | popd 19 | 20 | mkdir -p generated/llvm/sym++ 21 | 22 | pushd generated/llvm/sym++ 23 | ~/symcc_build/sym++ -S -emit-llvm "$@" ../../../sample.cpp 24 | popd 25 | 26 | popd 27 | done 28 | -------------------------------------------------------------------------------- /src/cpp/main_fold_clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | param_llvm="-fno-discard-value-names" # --target=aarch64-linux-gnu -mllvm '-rng-seed=1' 9 | param_exec="-fno-discard-value-names -o sample" # --target=aarch64-linux-gnu -mllvm '-rng-seed=1' 10 | 11 | $SYMRUSTC_HOME_CPP/fold_llvm_clang++.sh $param_llvm 12 | $SYMRUSTC_HOME_CPP/fold_exec_clang++.sh $param_exec 13 | -------------------------------------------------------------------------------- /src/cpp/main_fold_ko-clang++.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | param_llvm="" # --target=aarch64-linux-gnu -fno-discard-value-names -mllvm '-rng-seed=1' 9 | param_exec="-o sample" # --target=aarch64-linux-gnu -fno-discard-value-names -mllvm '-rng-seed=1' 10 | 11 | $SYMRUSTC_HOME_CPP/fold_llvm_ko-clang++.sh $param_llvm 12 | $SYMRUSTC_HOME_CPP/fold_exec_ko-clang++.sh $param_exec 13 | -------------------------------------------------------------------------------- /src/cpp/main_fold_sym++_qsym.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | param_llvm="-fno-discard-value-names" # --target=aarch64-linux-gnu -mllvm '-rng-seed=1' 9 | param_exec="-fno-discard-value-names -o sample" # --target=aarch64-linux-gnu -mllvm '-rng-seed=1' 10 | 11 | $SYMRUSTC_HOME_CPP/fold_llvm_sym++.sh $param_llvm || echo "error exit code: $?" >&2 # FIXME: https://github.com/llvm/llvm-project/issues/57104 12 | $SYMRUSTC_HOME_CPP/fold_exec_sym++_qsym.sh $param_exec || echo "error exit code: $?" >&2 # FIXME: https://github.com/llvm/llvm-project/issues/57104 13 | -------------------------------------------------------------------------------- /src/cpp/main_fold_sym++_simple_z3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | param_exec="-fno-discard-value-names -o sample" # --target=aarch64-linux-gnu -mllvm '-rng-seed=1' 9 | 10 | $SYMRUSTC_HOME_CPP/fold_exec_sym++_simple_z3.sh $param_exec || echo "error exit code: $?" >&2 # FIXME: https://github.com/llvm/llvm-project/issues/57104 11 | -------------------------------------------------------------------------------- /src/llvm/cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | jobs="$(python3 -c 'import os; print(len(os.sched_getaffinity(0)))')" 9 | 10 | "cmake" \ 11 | "$HOME/belcarra_source0/src/rs/rust_source/src/llvm-project/llvm" \ 12 | "-G" \ 13 | "Ninja" \ 14 | "-DLLVM_ENABLE_ASSERTIONS=OFF" \ 15 | "-DLLVM_ENABLE_PLUGINS=OFF" \ 16 | "-DLLVM_TARGETS_TO_BUILD=AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86" \ 17 | "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;M68k" \ 18 | "-DLLVM_INCLUDE_EXAMPLES=OFF" \ 19 | "-DLLVM_INCLUDE_DOCS=OFF" \ 20 | "-DLLVM_INCLUDE_BENCHMARKS=OFF" \ 21 | "-DLLVM_INCLUDE_TESTS=OFF" \ 22 | "-DLLVM_ENABLE_TERMINFO=OFF" \ 23 | "-DLLVM_ENABLE_LIBEDIT=OFF" \ 24 | "-DLLVM_ENABLE_BINDINGS=OFF" \ 25 | "-DLLVM_ENABLE_Z3_SOLVER=OFF" \ 26 | "-DLLVM_PARALLEL_COMPILE_JOBS=$jobs" \ 27 | "-DLLVM_TARGET_ARCH=x86_64" \ 28 | "-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-gnu" \ 29 | "-DLLVM_INSTALL_UTILS=ON" \ 30 | "-DLLVM_ENABLE_ZSTD=OFF" \ 31 | "-DLLVM_ENABLE_ZLIB=ON" \ 32 | "-DLLVM_ENABLE_LIBXML2=OFF" \ 33 | "-DLLVM_VERSION_SUFFIX=-rust-dev" \ 34 | "-DCMAKE_INSTALL_MESSAGE=LAZY" \ 35 | "-DCMAKE_C_COMPILER=cc" \ 36 | "-DCMAKE_CXX_COMPILER=c++" \ 37 | "-DCMAKE_ASM_COMPILER=cc" \ 38 | "-DCMAKE_C_FLAGS=-ffunction-sections -fdata-sections -fPIC -m64" \ 39 | "-DCMAKE_CXX_FLAGS=-ffunction-sections -fdata-sections -fPIC -m64" \ 40 | "-DCMAKE_SHARED_LINKER_FLAGS= -Wl,-Bsymbolic -static-libstdc++" \ 41 | "-DCMAKE_MODULE_LINKER_FLAGS= -Wl,-Bsymbolic -static-libstdc++" \ 42 | "-DCMAKE_EXE_LINKER_FLAGS= -Wl,-Bsymbolic -static-libstdc++" \ 43 | "-DCMAKE_INSTALL_PREFIX=$HOME/belcarra_source0/src/rs/rust_source/build/x86_64-unknown-linux-gnu/llvm" \ 44 | "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" \ 45 | "-DCMAKE_BUILD_TYPE=Release" 46 | 47 | "cmake" "--build" "." "--target" "install" "--config" "Release" "--" "-j" "$jobs" 48 | -------------------------------------------------------------------------------- /src/llvm/cmake0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | sed -E \ 9 | -e 's," "," \\\n ",g' \ 10 | -e 's,/home/ubuntu,$HOME,g' \ 11 | -e 's,(DLLVM_PARALLEL_COMPILE_JOBS)=[[:digit:]]*,\1=$jobs,' 12 | -------------------------------------------------------------------------------- /src/rs/cargo_fuzz.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | date_now="$(date '+%F_%T' | tr -d ':-')" 11 | 12 | # 13 | 14 | cargo fuzz build # force the build to occur outside of our measured benchmark duration 15 | 16 | $SYMRUSTC_HOME_RS/cargo_fuzz0.sh 2>&1 | tee "${SYMRUSTC_LOG_PREFIX}_cargo_fuzz_${date_now}" 17 | -------------------------------------------------------------------------------- /src/rs/cargo_fuzz0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | if [[ ! -v SYMRUSTC_TIMEOUT ]] ; then 9 | SYMRUSTC_TIMEOUT=$SYMRUSTC_TIMEOUT_DEFAULT 10 | fi 11 | 12 | echo "$(date): $$ start" >&2 13 | 14 | exit_code=0 15 | timeout --preserve-status $SYMRUSTC_TIMEOUT cargo fuzz run $(cargo fuzz list | head -n 1) || exit_code=$? 16 | 17 | echo "$(date): $$ exit code: $exit_code" >&2 18 | -------------------------------------------------------------------------------- /src/rs/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | source $SYMRUSTC_HOME_RS/wait_all.sh 11 | 12 | exec $SYMRUSTC_HOME_RS/env0.sh "$@" 13 | -------------------------------------------------------------------------------- /src/rs/env0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args0.sh 9 | 10 | export SYMCC_NO_SYMBOLIC_INPUT=yes 11 | export RUSTFLAGS="-L${SYMRUSTC_RUNTIME_DIR} -Clink-arg=-Wl,-rpath,${SYMRUSTC_RUNTIME_DIR}" 12 | export RUSTC=$SYMRUSTC_RUSTC 13 | 14 | # 15 | 16 | if [[ -v SYMRUSTC_EXEC_CONCOLIC_OFF ]] ; then 17 | # Note: Changing $PATH is optional. For instance, it can be done for supporting Rust programs using clang or clang++ in their build. 18 | PATH=$SYMRUSTC_USER/clang_symcc_off:"$PATH" \ 19 | CARGO_TARGET_DIR=$SYMRUSTC_DIR/target_cargo_off \ 20 | eval fork "$@" 21 | fi 22 | 23 | if [[ ! -v SYMRUSTC_SKIP_CONCOLIC_ON ]] ; then 24 | # Note: Same remarks apply for SymRustC programs. However here, we have to use the "concolic SymCC" versions of clang or clang++. 25 | PATH=$SYMRUSTC_USER/clang_symcc_on:"$PATH" \ 26 | CARGO_TARGET_DIR=$SYMRUSTC_DIR/target_cargo_on \ 27 | RUSTFLAGS="$RUSTFLAGS -C passes=symcc-module,symcc-function -lSymRuntime" \ 28 | eval fork "$@" 29 | # FIXME: The "passes" option is supposed to take a space-separated list. However it seems there is no way to escape a space in $RUSTFLAGS. A solution might be using instead $CARGO_ENCODED_RUSTFLAGS (https://github.com/rust-lang/cargo/issues/6139), however this solution may require more work (e.g. echo "...+...+..." | tr '+' '\1'), or is it restricted to be only used for cargo? Another workaround is to take advantage of the fact that, at the time of writing, rustc does not do anything important with "passes", except first mapping all the space characters to ','. The fix is then to manually use here earlier that character instead of the space... 30 | fi 31 | 32 | wait_all 33 | -------------------------------------------------------------------------------- /src/rs/fold_symrustc_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | source $SYMRUSTC_HOME_RS/wait_all.sh 11 | 12 | export SYMRUSTC_TARGET_NAME=symrustc/build 13 | export SYMRUSTC_HIDE_RESULT=yes 14 | 15 | SYMRUSTC_DIR0="$SYMRUSTC_DIR" 16 | 17 | # FIXME: https://github.com/llvm/llvm-project/issues/57104 18 | # "source_4_symcc_2_rs false -- -Clinker=clang++" # Semantically: should symlink to sym++ to enable concolic annotation. 19 | for dir in "source_0_original_1a_rs true" \ 20 | "source_0_original_1b_rs true" \ 21 | "source_2_base_1a_rs true" \ 22 | "source_4_symcc_1_rs false" 23 | do 24 | dir=( $dir ) 25 | 26 | export SYMRUSTC_DIR="$SYMRUSTC_DIR0/${dir[0]}" 27 | export SYMRUSTC_BUILD_COMP_CONCOLIC=${dir[1]} 28 | fork $SYMRUSTC_HOME_RS/symrustc_build.sh "${dir[@]:2}" 29 | done 30 | 31 | wait_all 32 | 33 | # 34 | 35 | # FIXME: https://github.com/llvm/llvm-project/issues/57104 36 | # "source_4_symcc_2_rs false" 37 | for dir in "source_0_original_1a_rs true" \ 38 | "source_0_original_1b_rs true" \ 39 | "source_2_base_1a_rs true" \ 40 | "source_4_symcc_1_rs false" 41 | do 42 | dir=( $dir ) 43 | 44 | SYMRUSTC_DIR="$SYMRUSTC_DIR0/${dir[0]}" 45 | SYMRUSTC_BUILD_COMP_CONCOLIC=${dir[1]} 46 | source $SYMRUSTC_HOME_RS/symrustc_build_show.sh 47 | done 48 | -------------------------------------------------------------------------------- /src/rs/fold_symrustc_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | SYMRUSTC_DIR0="$SYMRUSTC_DIR" 11 | 12 | # FIXME: https://github.com/llvm/llvm-project/issues/57104 13 | # "source_4_symcc_2_rs 0 9 test" 14 | for dir in "source_0_original_1a_rs 0 8 test" \ 15 | "source_0_original_1b_rs 0 40 test" \ 16 | "source_2_base_1a_rs 1 0" \ 17 | "source_4_symcc_1_rs 0 3 -ne \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03" 18 | do 19 | dir=( $dir ) 20 | 21 | export SYMRUSTC_DIR="$SYMRUSTC_DIR0/${dir[0]}" 22 | export SYMRUSTC_RUN_EXPECTED_CODE=${dir[1]} 23 | export SYMRUSTC_RUN_EXPECTED_COUNT=${dir[2]} 24 | $SYMRUSTC_HOME_RS/symrustc_run.sh "${dir[@]:3}" 25 | done 26 | -------------------------------------------------------------------------------- /src/rs/hexdump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | hexdump="hexdump -v -C" 9 | output_dir=$SYMCC_OUTPUT_DIR/.. 10 | 11 | # 12 | 13 | $hexdump "$1" > $output_dir/hexdump_stdin 14 | 15 | (ls $SYMCC_OUTPUT_DIR/* 2>/dev/null || true) | while read i 16 | do 17 | echo -e "=============================\n$i" 18 | $hexdump "$i" | (git diff --color-words --no-index $output_dir/hexdump_stdin - || true) | tail -n +5 19 | done 2>$output_dir/hexdump_stderr >$output_dir/hexdump_stdout 20 | -------------------------------------------------------------------------------- /src/rs/libafl_cargo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | cat > libsancov.cpp < 10 | 11 | extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *, 12 | uint32_t *) { 13 | return; 14 | } 15 | 16 | extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *) { 17 | return; 18 | } 19 | EOF 20 | 21 | export PATH=$SYMRUSTC_USER/clang_symcc_off:"$PATH" 22 | 23 | clang++ -c -o libsancov.o libsancov.cpp 24 | clang++ -shared -o libsancov.so libsancov.o 25 | -------------------------------------------------------------------------------- /src/rs/libafl_solving_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | source $SYMRUSTC_HOME_RS/parse_args.sh 11 | source $SYMRUSTC_HOME_RS/wait_all.sh 12 | 13 | # Building the client-server main fuzzing loop completely sanitized (example instrumented with libsancov) 14 | 15 | $SYMRUSTC_HOME_RS/libafl_solving_build0.sh & 16 | 17 | # Building the example with SymRustC (example instrumented with SymCC) 18 | 19 | if [[ -v SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_SOLVING ]] ; then 20 | cd -P $SYMRUSTC_DIR 21 | mkdir -p target_cargo_on/debug 22 | curl -LO 'https://github.com/sfu-rsl/symrustc/raw/1.46.0_binary/'"$(echo $PWD | rev | cut -d / -f 1-2 | rev)"'/belcarra' 23 | chmod +x belcarra 24 | mv belcarra target_cargo_on/debug 25 | else 26 | $SYMRUSTC_HOME_RS/symrustc_build.sh "$@" 27 | fi 28 | 29 | # 30 | 31 | wait_all 32 | -------------------------------------------------------------------------------- /src/rs/libafl_solving_build0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | export PATH=$SYMRUSTC_USER/clang_symcc_off:"$PATH" 11 | 12 | cd $SYMRUSTC_LIBAFL_SOLVING_DIR 13 | cargo make test 14 | -------------------------------------------------------------------------------- /src/rs/libafl_solving_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | if [[ -z "${SYMRUSTC_LOG_PREFIX:-}" ]] ; then 11 | SYMRUSTC_LOG_PREFIX="$PWD"/ 12 | fi 13 | 14 | if [[ -v SYMRUSTC_LIBAFL_CONCOLIC ]] ; then 15 | SYMRUSTC_LOG_PREFIX="${SYMRUSTC_LOG_PREFIX}_symrustc" 16 | else 17 | SYMRUSTC_LOG_PREFIX="${SYMRUSTC_LOG_PREFIX}_libafl_fuzz" 18 | fi 19 | 20 | export SYMRUSTC_LOG_PREFIX 21 | 22 | $SYMRUSTC_HOME_RS/libafl_solving_run0.sh "$@" 23 | -------------------------------------------------------------------------------- /src/rs/libafl_solving_run0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euxo pipefail 7 | 8 | # 9 | 10 | source $SYMRUSTC_HOME_RS/parse_args.sh 11 | source $SYMRUSTC_HOME_RS/wait_all.sh 12 | source $SYMRUSTC_HOME_RS/libafl_swap.sh 13 | 14 | # 15 | 16 | mkdir /tmp/output 17 | swap 18 | 19 | # 20 | 21 | if [[ ! -v SYMRUSTC_TIMEOUT ]] ; then 22 | SYMRUSTC_TIMEOUT=$SYMRUSTC_TIMEOUT_DEFAULT 23 | fi 24 | 25 | date_now="$(date '+%F_%T' | tr -d ':-')" 26 | 27 | log_server_grep=log_server 28 | log_server="${SYMRUSTC_LOG_PREFIX}_${date_now}_server" 29 | log_client1="${SYMRUSTC_LOG_PREFIX}_${date_now}_client1" 30 | log_client2="${SYMRUSTC_LOG_PREFIX}_${date_now}_client2" 31 | 32 | pushd $SYMRUSTC_LIBAFL_SOLVING_DIR/fuzzer >/dev/null 33 | 34 | mkdir -p corpus 35 | fic_corpus="corpus/${date_now}" 36 | echo "$@" > $fic_corpus 37 | 38 | ln -s $(find -L $SYMRUSTC_DIR/target_cargo_on/debug -maxdepth 1 -type f -executable | grep . -m 1) target_symcc.out 39 | 40 | fuzz_bin=$(find -L $SYMRUSTC_LIBAFL_SOLVING_DIR/target/release -maxdepth 1 -type f -executable | grep -v '\.so' -m 1) 41 | 42 | fuzz_bin_fic=./fuzz_bin.sh 43 | 44 | cat > $fuzz_bin_fic <<"EOF" 45 | #!/bin/bash 46 | set -euo pipefail 47 | 48 | echo "$(date): $$ start" >&2 49 | exit_code=0 50 | EOF 51 | cat >> $fuzz_bin_fic <> $fuzz_bin_fic <<"EOF" 55 | echo "$(date): $$ exit code: $exit_code" >&2 56 | exit $exit_code 57 | EOF 58 | 59 | chmod +x $fuzz_bin_fic 60 | 61 | readlink -e harness > $log_server 62 | 63 | # starting the server 64 | if [[ -v SYMRUSTC_LIBAFL_SOLVING_OBJECTIVE ]] ; then 65 | mkfifo $log_server_grep 66 | $fuzz_bin_fic | tee -a $log_server | tee $log_server_grep & 67 | else 68 | $fuzz_bin_fic | tee -a $log_server & 69 | fi 70 | 71 | # waiting for the server to listen to new clients 72 | while ! nc -zv localhost 1337 ; do 73 | sleep 1 74 | done 75 | 76 | # starting the clients 77 | if [[ -v SYMRUSTC_LIBAFL_CONCOLIC ]] ; then 78 | $fuzz_bin_fic --concolic >$log_client1 2>&1 & 79 | proc_client1=$! 80 | fi 81 | $fuzz_bin_fic >$log_client2 2>&1 & 82 | proc_client2=$! 83 | 84 | # waiting 85 | if [[ -v SYMRUSTC_LIBAFL_SOLVING_OBJECTIVE ]] ; then 86 | # waiting for a specific message from the server before proceeding further 87 | grep -q 'objectives: 2' $log_server_grep 88 | else 89 | echo "Only executing during a finite period of time, irrespective of objective search" >&2 90 | sleep $SYMRUSTC_TIMEOUT 91 | fi 92 | 93 | # terminating the client first, then any remaining forked processes not yet terminated 94 | if [[ -v SYMRUSTC_LIBAFL_CONCOLIC ]] ; then 95 | kill $proc_client1 || echo "error (client1): kill ($?)" >&2 96 | wait $proc_client1 || echo "error (client1): wait ($?)" >&2 97 | fi 98 | kill $proc_client2 || echo "error (client2): kill ($?)" >&2 99 | wait $proc_client2 || echo "error (client2): wait ($?)" >&2 100 | killall $fuzz_bin || echo "error: killall ($?)" >&2 101 | wait_all 102 | 103 | # cleaning 104 | if [[ -v SYMRUSTC_LIBAFL_SOLVING_OBJECTIVE ]] ; then 105 | rm $log_server_grep 106 | fi 107 | rm $fic_corpus 108 | rm $fuzz_bin_fic 109 | rm target_symcc.out 110 | 111 | popd >/dev/null 112 | 113 | # 114 | 115 | rm -rf /tmp/output 116 | swap 117 | -------------------------------------------------------------------------------- /src/rs/libafl_swap.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | name="$(basename $SYMRUSTC_RUNTIME_DIR)" 7 | 8 | function swap () { 9 | pushd $SYMRUSTC_RUNTIME_DIR/.. >/dev/null 10 | mv -i "${name}" "${name}1" 11 | mv -i "${name}0" "${name}" 12 | mv -i "${name}1" "${name}0" 13 | popd >/dev/null 14 | } 15 | -------------------------------------------------------------------------------- /src/rs/libafl_tracing_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | source $SYMRUSTC_HOME_RS/parse_args.sh 11 | 12 | # 13 | 14 | pushd $SYMRUSTC_LIBAFL_TRACING_DIR >/dev/null 15 | 16 | declare -i err=0 17 | ../../target/debug/dump_constraints --plain-text --output output_build.txt -- \ 18 | $SYMRUSTC_HOME_RS/symrustc_build.sh "$@" \ 19 | || err=$? 20 | 21 | popd >/dev/null 22 | 23 | if [[ -v SYMRUSTC_LIBAFL_EXAMPLE_SKIP_BUILD_TRACING ]] ; then 24 | if ((err != 0)); then 25 | echo "error exit code: $err" >&2 26 | fi 27 | else 28 | exit $err 29 | fi 30 | -------------------------------------------------------------------------------- /src/rs/libafl_tracing_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | source $SYMRUSTC_HOME_RS/parse_args.sh 11 | 12 | # 13 | 14 | pushd $SYMRUSTC_LIBAFL_TRACING_DIR >/dev/null 15 | 16 | export SYMCC_INPUT_FILE="$PWD/$(date '+%F_%T' | tr -d ':-')" 17 | echo "$@" > $SYMCC_INPUT_FILE 18 | 19 | SYMRUSTC_BIN_ARGS=$SYMCC_INPUT_FILE \ 20 | ../../target/debug/dump_constraints --plain-text --output output.txt -- \ 21 | $SYMRUSTC_HOME_RS/symrustc_run.sh 22 | cat output.txt 23 | 24 | rm $SYMCC_INPUT_FILE 25 | 26 | popd >/dev/null 27 | -------------------------------------------------------------------------------- /src/rs/parse_args.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | if [[ ! -v SYMRUSTC_DIR ]] ; then 7 | export SYMRUSTC_DIR="$PWD" 8 | fi 9 | 10 | source $SYMRUSTC_HOME_RS/parse_args0.sh 11 | -------------------------------------------------------------------------------- /src/rs/parse_args0.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | if [[ ! -v SYMRUSTC_VERBOSE ]] ; then 7 | export SYMRUSTC_VERBOSE=false 8 | fi 9 | 10 | if eval $SYMRUSTC_VERBOSE ; then 11 | set -x 12 | fi 13 | -------------------------------------------------------------------------------- /src/rs/rustc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args0.sh 9 | 10 | rustc_input_file="$1"; shift 11 | 12 | target="$SYMRUSTC_DIR/$CARGO_TARGET_DIR" 13 | target_d="$target/debug" 14 | target_d_d="$target_d/deps" 15 | 16 | # 17 | 18 | export SYMCC_OUTPUT_DIR="$target/$SYMRUSTC_TARGET_NAME/output" 19 | 20 | mkdir -p "$target_d_d" \ 21 | "$SYMCC_OUTPUT_DIR" 22 | 23 | # 24 | 25 | metadata=b4b070263fc6e28b 26 | rustc_exit_code=0 27 | 28 | CARGO=$SYMRUSTC_CARGO \ 29 | CARGO_BIN_NAME=belcarra \ 30 | CARGO_CRATE_NAME=belcarra \ 31 | CARGO_MANIFEST_DIR="$SYMRUSTC_DIR" \ 32 | CARGO_PKG_AUTHORS='' \ 33 | CARGO_PKG_DESCRIPTION='' \ 34 | CARGO_PKG_HOMEPAGE='' \ 35 | CARGO_PKG_LICENSE='' \ 36 | CARGO_PKG_LICENSE_FILE='' \ 37 | CARGO_PKG_NAME=belcarra \ 38 | CARGO_PKG_REPOSITORY='' \ 39 | CARGO_PKG_RUST_VERSION='' \ 40 | CARGO_PKG_VERSION=0.1.0 \ 41 | CARGO_PKG_VERSION_MAJOR=0 \ 42 | CARGO_PKG_VERSION_MINOR=1 \ 43 | CARGO_PKG_VERSION_PATCH=0 \ 44 | CARGO_PKG_VERSION_PRE='' \ 45 | CARGO_PRIMARY_PACKAGE=1 \ 46 | LD_LIBRARY_PATH="$target_d_d:$SYMRUSTC_LD_LIBRARY_PATH" \ 47 | \ 48 | $SYMRUSTC_RUSTC \ 49 | --crate-name belcarra \ 50 | --edition=2018 \ 51 | "$rustc_input_file" \ 52 | --error-format=json \ 53 | --json=diagnostic-rendered-ansi,artifacts,future-incompat \ 54 | --crate-type bin \ 55 | --emit=dep-info,link \ 56 | -C embed-bitcode=no \ 57 | -C debuginfo=2 \ 58 | -C metadata=$metadata \ 59 | -C extra-filename=-$metadata \ 60 | --out-dir "$target_d_d" \ 61 | -C incremental="$target_d/incremental" \ 62 | -L dependency="$target_d_d" \ 63 | -L$SYMRUSTC_RUNTIME_DIR \ 64 | -Clink-arg=-Wl,-rpath,$SYMRUSTC_RUNTIME_DIR \ 65 | "$@" \ 66 | || rustc_exit_code=$? 67 | 68 | ln -s "$target_d_d/belcarra-$metadata" "$target_d/belcarra" 69 | 70 | $SYMRUSTC_HOME_RS/hexdump.sh $SYMRUSTC_INPUT_FILE 71 | 72 | if [[ ! -v SYMRUSTC_SKIP_FAIL ]] ; then 73 | exit $rustc_exit_code 74 | else 75 | echo "$target: rustc exit code: $rustc_exit_code" >&2 76 | fi 77 | -------------------------------------------------------------------------------- /src/rs/rustc_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args0.sh 9 | 10 | export SYMCC_INPUT_FILE=$SYMRUSTC_INPUT_FILE 11 | 12 | $SYMRUSTC_HOME_RS/rustc.sh $SYMRUSTC_INPUT_FILE "$@" 13 | -------------------------------------------------------------------------------- /src/rs/rustc_none.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args0.sh 9 | 10 | export SYMCC_NO_SYMBOLIC_INPUT=yes 11 | 12 | $SYMRUSTC_HOME_RS/rustc.sh $SYMRUSTC_INPUT_FILE "$@" 13 | -------------------------------------------------------------------------------- /src/rs/rustc_stdin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args0.sh 9 | 10 | cat $SYMRUSTC_INPUT_FILE | $SYMRUSTC_HOME_RS/rustc.sh - "$@" 11 | -------------------------------------------------------------------------------- /src/rs/symcc_fuzzing_helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | cd $SYMRUSTC_USER/symcc_source/util/symcc_fuzzing_helper 9 | 10 | declare -i err=0 11 | $SYMRUSTC_HOME_RS/env.sh $SYMRUSTC_CARGO install --path $PWD --locked || err=$? 12 | 13 | if ((err != 0)); then 14 | if [[ -v SYMRUSTC_SKIP_FAIL ]]; then 15 | echo "error exit code: $err" >&2 16 | else 17 | exit "$err" 18 | fi 19 | fi 20 | -------------------------------------------------------------------------------- /src/rs/symrustc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | # 9 | 10 | $SYMRUSTC_HOME_RS/symrustc_build.sh 11 | $SYMRUSTC_HOME_RS/symrustc_run.sh "$@" 12 | -------------------------------------------------------------------------------- /src/rs/symrustc_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | if [[ ! -v SYMRUSTC_BUILD_COMP_CONCOLIC ]] ; then 11 | SYMRUSTC_BUILD_COMP_CONCOLIC=false 12 | fi 13 | 14 | # 15 | 16 | source $SYMRUSTC_HOME_RS/wait_all.sh 17 | 18 | # 19 | 20 | export SYMRUSTC_TARGET_NAME=symrustc/build 21 | 22 | if eval $SYMRUSTC_BUILD_COMP_CONCOLIC 23 | # TODO: at the time of writing, examples having several Rust source files (e.g. comprising build.rs) are not yet implemented 24 | then 25 | export SYMRUSTC_INPUT_FILE="$SYMRUSTC_DIR/src/main.rs" 26 | 27 | CARGO_TARGET_DIR=target_rustc_none_on fork $SYMRUSTC_HOME_RS/rustc_none.sh -C "passes=symcc-module symcc-function" -lSymRuntime "$@" 28 | CARGO_TARGET_DIR=target_rustc_none_off fork $SYMRUSTC_HOME_RS/rustc_none.sh "$@" 29 | CARGO_TARGET_DIR=target_rustc_file_on fork $SYMRUSTC_HOME_RS/rustc_file.sh -C "passes=symcc-module symcc-function" -lSymRuntime "$@" 30 | CARGO_TARGET_DIR=target_rustc_file_off fork $SYMRUSTC_HOME_RS/rustc_file.sh "$@" 31 | CARGO_TARGET_DIR=target_rustc_stdin_on fork $SYMRUSTC_HOME_RS/rustc_stdin.sh -C "passes=symcc-module symcc-function" -lSymRuntime "$@" 32 | CARGO_TARGET_DIR=target_rustc_stdin_off fork $SYMRUSTC_HOME_RS/rustc_stdin.sh "$@" 33 | fi 34 | 35 | fork $SYMRUSTC_HOME_RS/env0.sh $SYMRUSTC_CARGO rustc --manifest-path "$SYMRUSTC_DIR/Cargo.toml" "$@" 36 | 37 | wait_all 38 | 39 | # 40 | 41 | if [[ ! -v SYMRUSTC_HIDE_RESULT ]]; then 42 | source $SYMRUSTC_HOME_RS/symrustc_build_show.sh 43 | fi 44 | -------------------------------------------------------------------------------- /src/rs/symrustc_build_show.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | if eval $SYMRUSTC_BUILD_COMP_CONCOLIC; then 7 | function basename2 () { 8 | echo "$1" | rev | cut -d '/' -f 1-2 | rev 9 | } 10 | for target0 in target_rustc_none target_rustc_file target_rustc_stdin 11 | do 12 | for target_pass in on off 13 | do 14 | target="$SYMRUSTC_DIR/${target0}_$target_pass" 15 | echo "Total number of testcases: $(ls "$target/$SYMRUSTC_TARGET_NAME/output" | wc -l) in $(basename2 "$target")" 16 | cat "$target/$SYMRUSTC_TARGET_NAME/hexdump_stdout" 17 | cat "$target/$SYMRUSTC_TARGET_NAME/hexdump_stderr" 18 | done 19 | done >&2 20 | fi 21 | -------------------------------------------------------------------------------- /src/rs/symrustc_hybrid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | # 11 | 12 | pushd $SYMRUSTC_LIBAFL_SOLVING_DIR/fuzzer >/dev/null 13 | 14 | ln -s $SYMRUSTC_DIR harness 15 | 16 | pushd $SYMRUSTC_DIR >/dev/null 17 | 18 | $SYMRUSTC_HOME_RS/libafl_solving_build.sh 19 | 20 | # pure fuzzing execution 21 | if [[ -v SYMRUSTC_LIBAFL_PURE_FUZZING ]] ; then 22 | $SYMRUSTC_HOME_RS/libafl_solving_run.sh "$@" 23 | sleep 1 # forcing the date to change (for filenames relying on the date) 24 | fi 25 | 26 | # hybrid execution 27 | export SYMRUSTC_LIBAFL_CONCOLIC=yes 28 | $SYMRUSTC_HOME_RS/libafl_solving_run.sh "$@" 29 | 30 | popd >/dev/null 31 | 32 | rm harness 33 | 34 | popd >/dev/null 35 | -------------------------------------------------------------------------------- /src/rs/symrustc_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | set -euo pipefail 7 | 8 | source $SYMRUSTC_HOME_RS/parse_args.sh 9 | 10 | if [[ -v SYMRUSTC_RUN_EXPECTED_CODE ]] ; then 11 | declare -i SYMRUSTC_RUN_EXPECTED_CODE=$SYMRUSTC_RUN_EXPECTED_CODE 12 | else 13 | declare -i SYMRUSTC_RUN_EXPECTED_CODE=0 14 | fi 15 | 16 | if [[ ! -v SYMRUSTC_BIN_ARGS ]] ; then 17 | SYMRUSTC_BIN_ARGS='' 18 | fi 19 | 20 | # 21 | 22 | SYMRUSTC_TARGET_NAME=symrustc/run 23 | 24 | SYMRUSTC_DIR0="$(basename "$SYMRUSTC_DIR")" 25 | 26 | function symrustc_exec () { 27 | local target="$1"; shift 28 | local input="$@" 29 | 30 | local target0="$SYMRUSTC_DIR/$target" 31 | local output_dir="$target0/$SYMRUSTC_TARGET_NAME" 32 | export SYMCC_OUTPUT_DIR="$output_dir/output" 33 | 34 | mkdir -p "$SYMCC_OUTPUT_DIR" 35 | 36 | declare -i code_actual=0 37 | echo $input | eval "$(find -L "$target0/debug" -maxdepth 1 -type f -executable | grep . -m 1)" "$SYMRUSTC_BIN_ARGS" || code_actual=$? 38 | echo $input | $SYMRUSTC_HOME_RS/hexdump.sh /dev/stdin 39 | 40 | echo "Total number of testcases: $(ls "$output_dir/output" | wc -l) in ${SYMRUSTC_DIR0}/${target}" >&2 41 | cat "$output_dir/hexdump_stdout" >&2 42 | cat "$output_dir/hexdump_stderr" >&2 43 | 44 | if (( $SYMRUSTC_RUN_EXPECTED_CODE != $code_actual )); then 45 | echo "$target: Unexpected exit code: $code_actual" >&2 46 | if [[ ! -v SYMRUSTC_SKIP_FAIL ]] ; then 47 | exit 1 48 | fi 49 | fi 50 | } 51 | 52 | for target0 in target_cargo target_rustc_none target_rustc_file target_rustc_stdin 53 | do 54 | target_on=${target0}_on 55 | if [[ -d "$SYMRUSTC_DIR/$target_on" ]]; then 56 | symrustc_exec $target_on "$@" 57 | 58 | if [[ -v SYMRUSTC_RUN_EXPECTED_COUNT ]] && [[ $(ls "$SYMCC_OUTPUT_DIR" | wc -l) -ne $SYMRUSTC_RUN_EXPECTED_COUNT ]] ; then 59 | echo "$target_on: check expected to succeed" >&2 60 | if [[ ! -v SYMRUSTC_SKIP_FAIL ]] ; then 61 | exit 1 62 | fi 63 | fi 64 | fi 65 | 66 | target_off=${target0}_off 67 | if [[ -d "$SYMRUSTC_DIR/$target_off" ]]; then 68 | symrustc_exec $target_off "$@" 69 | 70 | declare -i count_actual=$(ls "$SYMCC_OUTPUT_DIR" | wc -l) 71 | if (( $count_actual != 0 )); then 72 | if [[ -v SYMRUSTC_RUN_EXPECTED_COUNT ]] && (( $count_actual > $SYMRUSTC_RUN_EXPECTED_COUNT )); then 73 | echo "$target_off: check not expected to succeed" >&2 74 | exit 1 75 | else 76 | echo "warning: $SYMRUSTC_DIR/$target_off not empty" >&2 77 | fi 78 | fi 79 | fi 80 | done 81 | -------------------------------------------------------------------------------- /src/rs/wait_all.sh: -------------------------------------------------------------------------------- 1 | # 2 | 3 | # SPDX-License-Identifier 4 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 5 | 6 | if [ -v SYMRUSTC_CI ]; then 7 | function fork () { 8 | "$@" 9 | } 10 | else 11 | function fork () { 12 | "$@" & 13 | } 14 | fi 15 | 16 | # https://stackoverflow.com/a/71778264 17 | function wait_all () { 18 | declare -i err=0 werr=0 19 | 20 | while wait -fn || werr=$?; ((werr != 127)); do 21 | if ((err == 0)); then 22 | err=$werr 23 | fi 24 | done 25 | 26 | if ((err != 0)); then 27 | exit $err 28 | fi 29 | } 30 | 31 | # 32 | 33 | export -f fork 34 | export -f wait_all 35 | -------------------------------------------------------------------------------- /symrustc.Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier 2 | # Copyright (C) 2021-2022 Simon Fraser University (www.sfu.ca) 3 | 4 | 5 | # 6 | # Build end user environment main 7 | # 8 | ARG SYMRUSTC_SOURCE 9 | FROM $SYMRUSTC_SOURCE:latest AS builder_end_user_main 10 | 11 | ARG SYMRUSTC_DIR_COPY 12 | COPY --chown=ubuntu:ubuntu $SYMRUSTC_DIR_COPY $SYMRUSTC_DIR_COPY 13 | --------------------------------------------------------------------------------