diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 96ce07e..4bc303a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,10 +23,6 @@ jobs: tags: ruzzy cache-from: type=gha cache-to: type=gha,mode=max - build-args: | - CLANG_ARCH=x86_64 - CLANG_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz - CLANG_CHECKSUM=884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3 - name: Run tests run: | docker run \ diff --git a/Dockerfile b/Dockerfile index 6062662..371f6bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,16 @@ FROM debian:12-slim RUN apt update && apt install -y \ - binutils \ - gcc \ - g++ \ - libc-dev \ - make \ + build-essential \ + clang \ ruby \ ruby-dev \ - wget \ - xz-utils \ && rm -rf /var/lib/apt/lists/* ENV APP_DIR="/app" -ENV CLANG_DIR="$APP_DIR/clang" RUN mkdir $APP_DIR -RUN mkdir $CLANG_DIR WORKDIR $APP_DIR -ARG CLANG_ARCH=aarch64 -ARG CLANG_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-aarch64-linux-gnu.tar.xz -ARG CLANG_CHECKSUM=6dd62762285326f223f40b8e4f2864b5c372de3f7de0731cb7cd55ca5287b75a - -ENV CLANG_ARCH=${CLANG_ARCH} -ENV CLANG_URL=${CLANG_URL} -ENV CLANG_CHECKSUM=${CLANG_CHECKSUM} - -ENV CLANG_FILE clang.tar.xz -RUN wget -q -O $CLANG_FILE $CLANG_URL && \ - echo "$CLANG_CHECKSUM $CLANG_FILE" | sha256sum -c - && \ - tar xf $CLANG_FILE -C $CLANG_DIR --strip-components 1 && \ - rm $CLANG_FILE - -ENV PATH="$PATH:$CLANG_DIR/bin" ENV CC="clang" ENV CXX="clang++" ENV LDSHARED="clang -shared" diff --git a/README.md b/README.md index c7fdd28..f53207d 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,13 @@ It should quickly produce a crash like the following: ``` INFO: Running with entropic power schedule (0xFF, 100). INFO: Seed: 2527961537 -==3==ERROR: AddressSanitizer: stack-use-after-return on address 0xffffa8000920 at pc 0xffffa96a1a58 bp 0xfffff04ddbb0 sp 0xfffff04ddba8 ... -SUMMARY: AddressSanitizer: stack-use-after-return /var/lib/gems/3.1.0/gems/ruzzy-0.5.0/ext/dummy/dummy.c:18:24 in _c_dummy_test_one_input +==45==ERROR: AddressSanitizer: heap-use-after-free on address 0x50c0009bab80 at pc 0xffff99ea1b44 bp 0xffffce8a67d0 sp 0xffffce8a67c8 ... -==1541==ABORTING -MS: 2 ChangeByte-CrossOver-; base unit: b408860bc2c0584b8e0bb6fa3443005a3ef39854 +SUMMARY: AddressSanitizer: heap-use-after-free /var/lib/gems/3.1.0/gems/ruzzy-0.6.0/ext/dummy/dummy.c:18:24 in _c_dummy_test_one_input +... +==45==ABORTING +MS: 4 EraseBytes-CopyPart-CopyPart-ChangeBit-; base unit: 410e5346bca8ee150ffd507311dd85789f2e171e 0x48,0x49, HI artifact_prefix='./'; Test unit written to ./crash-253420c1158bc6382093d409ce2e9cff5806e980 @@ -245,19 +246,6 @@ You can build the Ruzzy Docker image with the following command: docker build --tag ruzzy . ``` -_You may want to grab a cup of coffee, the initial build can take a while._ - -By default, this will build a Docker image for AArch64 architectures (e.g. M-series MacBooks). If you need to run Ruzzy on other architectures, like x86, you can use the following [build arguments](https://docs.docker.com/build/guide/build-args/): - -``` -docker build \ - --build-arg CLANG_ARCH=x86_64 \ - --build-arg CLANG_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz \ - --build-arg CLANG_CHECKSUM=884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3 \ - --tag ruzzy \ - . -``` - Then, you can shell into the container using the following command: ``` diff --git a/ext/cruzzy/extconf.rb b/ext/cruzzy/extconf.rb index fa8627f..7a92448 100644 --- a/ext/cruzzy/extconf.rb +++ b/ext/cruzzy/extconf.rb @@ -64,6 +64,7 @@ def merge_sanitizer_libfuzzer_lib(sanitizer_lib, fuzzer_no_main_lib, merged_outp '-Wl,--no-whole-archive', '-lpthread', '-ldl', + '-lstdc++', '-shared', '-o', merged_output @@ -137,4 +138,6 @@ def merge_sanitizer_libfuzzer_lib(sanitizer_lib, fuzzer_no_main_lib, merged_outp # For more information, see https://github.com/ruby/ruby/blob/master/lib/mkmf.rb. $LOCAL_LIBS = fuzzer_no_main_lib +$LIBS << ' -lstdc++' + create_makefile('cruzzy/cruzzy') diff --git a/ext/dummy/dummy.c b/ext/dummy/dummy.c index bb18613..295b86f 100644 --- a/ext/dummy/dummy.c +++ b/ext/dummy/dummy.c @@ -6,18 +6,17 @@ // https://llvm.org/docs/LibFuzzer.html#toy-example static int _c_dummy_test_one_input(const uint8_t *data, size_t size) { - char test[] = {'a', 'b', 'c'}; + volatile char boom = 'x'; if (size == 2) { if (data[0] == 'H') { if (data[1] == 'I') { - // This code exists specifically to test the driver and ensure - // libFuzzer is functioning as expected, so we can safely ignore - // the warning. - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Warray-bounds" - test[1024] = 'd'; - #pragma clang diagnostic pop + // Intentional heap-use-after-free for testing purposes + char * volatile ptr = malloc(128); + ptr[0] = 'x'; + free(ptr); + boom = ptr[0]; + (void) boom; } } } diff --git a/test/test_ruzzy.rb b/test/test_ruzzy.rb index 78593bb..5a2f0e7 100644 --- a/test/test_ruzzy.rb +++ b/test/test_ruzzy.rb @@ -16,7 +16,7 @@ # which may cause false positives in the tests. This is obviously not ideal, # but I can't think of a better and easier solution right now. EXPECTED_OUTPUT_RETURN = 'TypeError: fuzz target function did not return an integer or nil' -EXPECTED_OUTPUT_SUCCESS = 'ERROR: AddressSanitizer: stack-use-after-return' +EXPECTED_OUTPUT_SUCCESS = 'ERROR: AddressSanitizer: heap-use-after-free' EXPECTED_OUTPUT_BRANCH = 'RuntimeError: TEST HARNESS BRANCH' EXPECTED_OUTPUT_CMP = 'RuntimeError: TEST HARNESS CMP' EXPECTED_OUTPUT_DIV = 'RuntimeError: TEST HARNESS DIV'