fix: build #4
Workflow file for this run
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: AFL++ Long Fuzzing Campaign | |
| on: | |
| push: | |
| branches: | |
| - '**' # Run on push to any branch for testing | |
| paths: | |
| - '.github/workflows/fuzz-long.yml' # Only trigger on workflow changes | |
| # TODO: Uncomment after testing | |
| # schedule: | |
| # # Run nightly at 2 AM UTC | |
| # - cron: '0 2 * * *' | |
| # # Run weekly deep fuzzing on Sunday at 3 AM UTC | |
| # - cron: '0 3 * * 0' | |
| workflow_dispatch: | |
| inputs: | |
| duration_minutes: | |
| description: 'Fuzzing duration in minutes' | |
| required: false | |
| default: '30' | |
| type: string | |
| parallel_instances: | |
| description: 'Number of parallel AFL++ instances' | |
| required: false | |
| default: '1' | |
| type: string | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: false # Let long runs complete | |
| jobs: | |
| fuzz-long: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 # 1 hour max (includes build time) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # Run multiple parallel instances for better coverage | |
| instance: [0] # Can be expanded to [0, 1, 2, 3] for parallel fuzzing | |
| container: | |
| image: ghcr.io/romange/ubuntu-dev:24 | |
| options: --security-opt seccomp=unconfined --sysctl "net.ipv6.conf.all.disable_ipv6=0" | |
| credentials: | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v5 | |
| with: | |
| submodules: true | |
| - name: Install AFL++ | |
| run: | | |
| echo "Installing AFL++..." | |
| apt-get update -qq | |
| apt-get install -y -qq afl++ lld-17 > /dev/null | |
| echo "AFL++ installed successfully" | |
| afl-fuzz -h | head -5 | |
| afl-clang-lto --version | |
| - name: Configure system for fuzzing | |
| run: | | |
| echo "Configuring system for AFL++ fuzzing..." | |
| afl-system-config | |
| echo "System configured" | |
| - name: Build Dragonfly with AFL++ | |
| run: | | |
| echo "Building Dragonfly with AFL++ instrumentation..." | |
| ./helio/blaze.sh -DUSE_AFL:BOOL=ON | |
| cd ./build-dbg && ninja dragonfly && cd .. | |
| echo "Build complete" | |
| ls -lh ./build-dbg/dragonfly | |
| - name: Run AFL++ long fuzzing session | |
| env: | |
| # Do NOT use AFL_BENCH_UNTIL_CRASH - we want to collect all crashes | |
| AFL_NO_UI: 1 # Disable UI for CI | |
| AFL_AUTORESUME: 1 # Auto-resume if output exists | |
| AFL_SKIP_CPUFREQ: 1 # Skip CPU freq check in containers | |
| AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1 # Suppress warnings | |
| AFL_TESTCACHE_SIZE: 500 # Larger cache for long runs | |
| AFL_FAST_CAL: 1 # Faster calibration | |
| run: | | |
| echo "Starting AFL++ long fuzzing campaign..." | |
| DURATION_MINUTES="${{ github.event.inputs.duration_minutes || '30' }}" | |
| INSTANCE_ID="${{ matrix.instance }}" | |
| echo "Configuration:" | |
| echo " Duration: ${DURATION_MINUTES} minutes" | |
| echo " Instance: ${INSTANCE_ID}" | |
| echo " Mode: Long campaign (collect all crashes)" | |
| cd fuzz | |
| export BUILD_DIR="${GITHUB_WORKSPACE}/build-dbg" | |
| # For parallel fuzzing, modify the fuzzer name | |
| # Instance 0 = main fuzzer, others = secondary fuzzers | |
| if [ "$INSTANCE_ID" -eq 0 ]; then | |
| # Main fuzzer with deterministic mode | |
| export AFL_FINAL_SYNC=1 | |
| timeout ${DURATION_MINUTES}m ./run_fuzzer.sh || EXIT_CODE=$? | |
| else | |
| # Secondary fuzzers would need modified run_fuzzer.sh | |
| # For now, just run main fuzzer | |
| timeout ${DURATION_MINUTES}m ./run_fuzzer.sh || EXIT_CODE=$? | |
| fi | |
| if [ "${EXIT_CODE:-0}" -eq 124 ]; then | |
| echo "Fuzzing completed (timeout reached after ${DURATION_MINUTES} minutes)" | |
| elif [ "${EXIT_CODE:-0}" -eq 0 ]; then | |
| echo "Fuzzing completed normally" | |
| else | |
| echo "Fuzzing exited with code ${EXIT_CODE}" | |
| fi | |
| - name: Analyze results | |
| if: always() | |
| id: analyze | |
| run: | | |
| echo "Analyzing fuzzing results..." | |
| CRASHES_DIR="fuzz/artifacts/resp/default/crashes" | |
| HANGS_DIR="fuzz/artifacts/resp/default/hangs" | |
| QUEUE_DIR="fuzz/artifacts/resp/default/queue" | |
| # Count results | |
| CRASH_COUNT=0 | |
| HANG_COUNT=0 | |
| CORPUS_SIZE=0 | |
| if [ -d "$CRASHES_DIR" ]; then | |
| CRASH_COUNT=$(find "$CRASHES_DIR" -type f ! -name "README.txt" 2>/dev/null | wc -l) | |
| fi | |
| if [ -d "$HANGS_DIR" ]; then | |
| HANG_COUNT=$(find "$HANGS_DIR" -type f ! -name "README.txt" 2>/dev/null | wc -l) | |
| fi | |
| if [ -d "$QUEUE_DIR" ]; then | |
| CORPUS_SIZE=$(find "$QUEUE_DIR" -type f ! -name ".state" 2>/dev/null | wc -l) | |
| fi | |
| echo "crash_count=$CRASH_COUNT" >> $GITHUB_OUTPUT | |
| echo "hang_count=$HANG_COUNT" >> $GITHUB_OUTPUT | |
| echo "corpus_size=$CORPUS_SIZE" >> $GITHUB_OUTPUT | |
| echo "Fuzzing Campaign Results:" | |
| echo " Crashes: $CRASH_COUNT" | |
| echo " Hangs: $HANG_COUNT" | |
| echo " Corpus size: $CORPUS_SIZE" | |
| # Extract stats | |
| STATS_FILE="fuzz/artifacts/resp/default/fuzzer_stats" | |
| if [ -f "$STATS_FILE" ]; then | |
| echo "" | |
| echo "Key Statistics:" | |
| grep -E "execs_done|execs_per_sec|paths_total|corpus_count|unique_crashes|unique_hangs|last_crash|last_hang" "$STATS_FILE" || true | |
| fi | |
| - name: Upload crash artifacts | |
| if: always() && steps.analyze.outputs.crash_count > 0 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fuzz-long-crashes-${{ github.run_number }}-instance-${{ matrix.instance }} | |
| path: fuzz/artifacts/resp/default/crashes/ | |
| retention-days: 10 | |
| - name: Upload hang artifacts | |
| if: always() && steps.analyze.outputs.hang_count > 0 | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fuzz-long-hangs-${{ github.run_number }}-instance-${{ matrix.instance }} | |
| path: fuzz/artifacts/resp/default/hangs/ | |
| retention-days: 10 | |
| - name: Upload fuzzing statistics | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fuzz-long-stats-${{ github.run_number }}-instance-${{ matrix.instance }} | |
| path: | | |
| fuzz/artifacts/resp/default/fuzzer_stats | |
| fuzz/artifacts/resp/default/plot_data | |
| retention-days: 10 |