Fuzzing #216
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Fuzzing | |
| on: | |
| schedule: | |
| # Run daily at 2 AM UTC | |
| - cron: '0 2 * * *' | |
| workflow_dispatch: | |
| pull_request: | |
| paths: | |
| - 'src/**' | |
| - 'fuzz/**' | |
| - '.github/workflows/fuzz.yml' | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| fuzz: | |
| name: Fuzz Testing | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| target: | |
| - protocol_parsing | |
| - jsonrpc_handling | |
| - transport_layer | |
| - auth_flows | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Remove rust-toolchain.toml to allow nightly | |
| run: rm -f rust-toolchain.toml | |
| - name: Install Rust nightly | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: llvm-tools-preview | |
| - name: Install cargo-fuzz | |
| run: cargo install cargo-fuzz | |
| - name: Cache fuzz corpus | |
| uses: actions/cache@v5 | |
| with: | |
| path: fuzz/corpus | |
| key: fuzz-corpus-${{ matrix.target }}-${{ github.sha }} | |
| restore-keys: | | |
| fuzz-corpus-${{ matrix.target }}- | |
| - name: Run fuzzing (${{ matrix.target }}) | |
| run: | | |
| cargo fuzz run ${{ matrix.target }} -- \ | |
| -max_total_time=300 \ | |
| -print_final_stats=1 \ | |
| -detect_leaks=0 | |
| timeout-minutes: 10 | |
| - name: Minimize corpus | |
| if: github.event_name == 'schedule' | |
| run: cargo fuzz cmin ${{ matrix.target }} | |
| - name: Upload crash artifacts | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: fuzz-crashes-${{ matrix.target }} | |
| path: fuzz/artifacts/${{ matrix.target }}/ | |
| - name: Upload corpus | |
| if: github.event_name == 'schedule' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: fuzz-corpus-${{ matrix.target }} | |
| path: fuzz/corpus/${{ matrix.target }}/ | |
| fuzz-coverage: | |
| name: Fuzzing Coverage | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Remove rust-toolchain.toml to allow nightly | |
| run: rm -f rust-toolchain.toml | |
| - name: Install Rust nightly | |
| uses: dtolnay/rust-toolchain@nightly | |
| with: | |
| components: llvm-tools-preview | |
| - name: Install tools | |
| run: | | |
| cargo install cargo-fuzz | |
| cargo install rustfilt | |
| - name: Cache fuzz corpus | |
| uses: actions/cache@v5 | |
| with: | |
| path: fuzz/corpus | |
| key: fuzz-corpus-all-${{ github.sha }} | |
| restore-keys: | | |
| fuzz-corpus-all- | |
| fuzz-corpus- | |
| - name: Generate minimal corpus if needed | |
| run: | | |
| for target in protocol_parsing jsonrpc_handling transport_layer auth_flows; do | |
| # Create corpus directory if it doesn't exist | |
| mkdir -p fuzz/corpus/$target | |
| # If corpus is empty, run fuzzer briefly to generate some inputs | |
| if [ -z "$(ls -A fuzz/corpus/$target 2>/dev/null)" ]; then | |
| echo "No corpus found for $target, generating minimal corpus..." | |
| cargo fuzz run $target -- \ | |
| -max_total_time=10 \ | |
| -print_final_stats=1 \ | |
| -detect_leaks=0 || true | |
| fi | |
| done | |
| - name: Generate coverage | |
| run: | | |
| for target in protocol_parsing jsonrpc_handling transport_layer auth_flows; do | |
| cargo fuzz coverage $target | |
| done | |
| - name: Upload coverage reports | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: fuzz-coverage | |
| path: fuzz/coverage/ | |
| fuzz-24h: | |
| name: 24-Hour Fuzzing | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Remove rust-toolchain.toml to allow nightly | |
| run: rm -f rust-toolchain.toml | |
| - name: Install Rust nightly | |
| uses: dtolnay/rust-toolchain@nightly | |
| - name: Install cargo-fuzz | |
| run: cargo install cargo-fuzz | |
| - name: Run 24-hour fuzzing | |
| run: | | |
| # Run each target for 6 hours (total 24 hours) | |
| for target in protocol_parsing jsonrpc_handling transport_layer auth_flows; do | |
| echo "Starting 6-hour fuzz for $target" | |
| cargo fuzz run $target -- \ | |
| -max_total_time=21600 \ | |
| -print_final_stats=1 \ | |
| -detect_leaks=0 || true | |
| done | |
| timeout-minutes: 1440 # 24 hours | |
| - name: Upload results | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: fuzz-24h-results | |
| path: | | |
| fuzz/corpus/ | |
| fuzz/artifacts/ | |
| fuzz/*.log |