From 5798f003e409d95fe91a4725e16e82bb65311f65 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Wed, 11 Mar 2026 11:32:45 +0000 Subject: [PATCH 1/2] chore[fuzz]: more jobs Signed-off-by: Joe Isaacs --- .github/workflows/fuzz.yml | 3 +++ .github/workflows/run-fuzzer.yml | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 45a8d95563c..ae730769523 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -23,6 +23,7 @@ jobs: fuzz_target: file_io family: "m8g.large" image: "ubuntu24-full-arm64" + jobs: 2 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} @@ -74,6 +75,7 @@ jobs: fuzz_target: array_ops family: "m8g.large" image: "ubuntu24-full-arm64" + jobs: 2 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} @@ -111,6 +113,7 @@ jobs: fuzz_target: compress_roundtrip family: "m8g.large" image: "ubuntu24-full-arm64" + jobs: 2 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/run-fuzzer.yml b/.github/workflows/run-fuzzer.yml index d32478c2097..2f3d9ca17a4 100644 --- a/.github/workflows/run-fuzzer.yml +++ b/.github/workflows/run-fuzzer.yml @@ -27,6 +27,11 @@ on: required: false type: string default: "" + jobs: + description: "Number of parallel fuzzing jobs (libfuzzer -fork=N). Set to match available vCPUs." + required: false + type: number + default: 1 outputs: crashes_found: description: "Whether crashes were found" @@ -108,11 +113,15 @@ jobs: if [ -n "${{ inputs.extra_features }}" ]; then FEATURES_FLAG="--features ${{ inputs.extra_features }}" fi + FORK_FLAG="" + if [ "${{ inputs.jobs }}" -gt 1 ]; then + FORK_FLAG="-fork=${{ inputs.jobs }}" + fi RUSTFLAGS="--cfg vortex_nightly" RUST_BACKTRACE=1 \ cargo +$NIGHTLY_TOOLCHAIN fuzz run --release --debug-assertions \ $FEATURES_FLAG \ ${{ inputs.fuzz_target }} -- \ - -max_total_time=${{ inputs.max_time }} -rss_limit_mb=0 \ + $FORK_FLAG -max_total_time=${{ inputs.max_time }} -rss_limit_mb=0 \ 2>&1 | tee fuzz_output.log continue-on-error: true From 9ba126a94c80dce8a5a0a52c37154a7d7c39eed8 Mon Sep 17 00:00:00 2001 From: Joe Isaacs Date: Wed, 11 Mar 2026 14:28:13 +0000 Subject: [PATCH 2/2] chore[fuzz]: more jobs Signed-off-by: Joe Isaacs --- .github/workflows/fuzz.yml | 16 +++++----------- .github/workflows/run-fuzzer.yml | 30 +++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index ae730769523..49758ac260e 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -21,9 +21,7 @@ jobs: uses: ./.github/workflows/run-fuzzer.yml with: fuzz_target: file_io - family: "m8g.large" - image: "ubuntu24-full-arm64" - jobs: 2 + jobs: 16 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} @@ -73,9 +71,7 @@ jobs: uses: ./.github/workflows/run-fuzzer.yml with: fuzz_target: array_ops - family: "m8g.large" - image: "ubuntu24-full-arm64" - jobs: 2 + jobs: 16 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} @@ -111,9 +107,7 @@ jobs: uses: ./.github/workflows/run-fuzzer.yml with: fuzz_target: compress_roundtrip - family: "m8g.large" - image: "ubuntu24-full-arm64" - jobs: 2 + jobs: 16 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} @@ -126,9 +120,9 @@ jobs: uses: ./.github/workflows/run-fuzzer.yml with: fuzz_target: compress_gpu - family: "g4dn" - image: "ubuntu24-gpu-x64" + runner: gpu extra_features: "cuda" + jobs: 8 secrets: R2_FUZZ_ACCESS_KEY_ID: ${{ secrets.R2_FUZZ_ACCESS_KEY_ID }} R2_FUZZ_SECRET_ACCESS_KEY: ${{ secrets.R2_FUZZ_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/run-fuzzer.yml b/.github/workflows/run-fuzzer.yml index 2f3d9ca17a4..cef97a52e4e 100644 --- a/.github/workflows/run-fuzzer.yml +++ b/.github/workflows/run-fuzzer.yml @@ -12,16 +12,11 @@ on: required: false type: number default: 7200 - family: - description: "Runner family (e.g., m8g.large for CPU, g5+g4dn+g6 for GPU)" + runner: + description: "Runner name from .github-private runs-on.yml (e.g., arm64-medium, gpu)" required: false type: string - default: "m8g.large" - image: - description: "Runner image (e.g., ubuntu24-full-arm64, ubuntu24-gpu-x64)" - required: false - type: string - default: "ubuntu24-full-arm64" + default: "arm64-medium" extra_features: description: "Extra cargo features to enable (e.g., cuda)" required: false @@ -57,7 +52,7 @@ jobs: timeout-minutes: 230 # almost 4 hours runs-on: >- ${{ github.repository == 'vortex-data/vortex' - && format('runs-on={0}/runner=arm64-medium/disk=large/tag={1}-fuzz', github.run_id, inputs.fuzz_target) + && format('runs-on={0}/runner={1}/disk=large/tag={2}-fuzz', github.run_id, inputs.runner, inputs.fuzz_target) || 'ubuntu-latest' }} outputs: crashes_found: ${{ steps.check.outputs.crashes_found }} @@ -146,6 +141,23 @@ jobs: echo "No crashes found" fi + - name: Reproduce crash for full output + if: steps.check.outputs.crashes_found == 'true' && inputs.jobs > 1 + run: | + # In fork mode, child output (backtrace, panic message) is not captured in + # fuzz_output.log. Replay the crashing input in single-process mode to get + # the full output for the crash reporting pipeline. + FEATURES_FLAG="" + if [ -n "${{ inputs.extra_features }}" ]; then + FEATURES_FLAG="--features ${{ inputs.extra_features }}" + fi + RUSTFLAGS="--cfg vortex_nightly" RUST_BACKTRACE=1 \ + cargo +$NIGHTLY_TOOLCHAIN fuzz run --release --debug-assertions \ + $FEATURES_FLAG \ + ${{ inputs.fuzz_target }} \ + "${{ steps.check.outputs.first_crash }}" \ + 2>&1 | tee fuzz_output.log || true + - name: Archive crash artifacts id: upload_artifacts if: steps.check.outputs.crashes_found == 'true'