Fix/fuzz and security ci #1
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: Fuzz Python Env Replay | |
| on: | |
| pull_request: | |
| branches: [ main ] | |
| paths: | |
| - .github/workflows/fuzz-python-env-replay.yml | |
| - .github/workflows/fuzz-python-env-comparison.yml | |
| - .github/workflows/fuzz.yml | |
| - fuzz/fuzz_targets/validate_with_python.rs | |
| - fuzz/src/lib.rs | |
| - fuzz/src/python_env.rs | |
| - fuzz/examples/report_python_env.rs | |
| - fuzz/tests/python_env_contract.rs | |
| - fuzz/README.md | |
| workflow_dispatch: | |
| inputs: | |
| source_run_id: | |
| description: Comparison workflow run id to replay artifacts from | |
| required: false | |
| permissions: | |
| actions: read | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| replay-python-env-artifacts: | |
| name: Replay Python env artifact (${{ matrix.case_name }}, ${{ matrix.policy_name }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - case_name: inherit-leak | |
| source_artifact_name: fuzz-python-env-inherit | |
| input_prefix: leak- | |
| policy_name: inherit | |
| env_policy: inherit | |
| - case_name: inherit-leak | |
| source_artifact_name: fuzz-python-env-inherit | |
| input_prefix: leak- | |
| policy_name: strip-setup-python | |
| env_policy: strip_setup_python | |
| - case_name: inherit-leak | |
| source_artifact_name: fuzz-python-env-inherit | |
| input_prefix: leak- | |
| policy_name: strip-setup-python-and-ld-library-path | |
| env_policy: strip_setup_python_and_ld_library_path | |
| - case_name: strip-setup-python-artifact | |
| source_artifact_name: fuzz-python-env-strip-setup-python | |
| input_prefix: crash- | |
| policy_name: inherit | |
| env_policy: inherit | |
| - case_name: strip-setup-python-artifact | |
| source_artifact_name: fuzz-python-env-strip-setup-python | |
| input_prefix: crash- | |
| policy_name: strip-setup-python | |
| env_policy: strip_setup_python | |
| - case_name: strip-setup-python-artifact | |
| source_artifact_name: fuzz-python-env-strip-setup-python | |
| input_prefix: crash- | |
| policy_name: strip-setup-python-and-ld-library-path | |
| env_policy: strip_setup_python_and_ld_library_path | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@0f1b44df7e9cbb178d781a242338dfa5e243ad7f | |
| with: | |
| toolchain: nightly-2026-04-16 | |
| - name: Install Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install cargo-fuzz | |
| run: cargo install cargo-fuzz --locked --version 0.13.1 | |
| - name: Resolve replay input | |
| id: input | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| INPUT_SOURCE_RUN_ID: ${{ github.event.inputs.source_run_id }} | |
| SOURCE_BRANCH: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }} | |
| SOURCE_ARTIFACT_NAME: ${{ matrix.source_artifact_name }} | |
| INPUT_PREFIX: ${{ matrix.input_prefix }} | |
| run: | | |
| source_run_id="$INPUT_SOURCE_RUN_ID" | |
| if [ "$EVENT_NAME" = "pull_request" ]; then | |
| source_run_id=$(gh run list \ | |
| --branch "$SOURCE_BRANCH" \ | |
| --workflow "Fuzz Python Env Comparison" \ | |
| --limit 20 \ | |
| --json databaseId,status \ | |
| --jq 'map(select(.status=="completed")) | .[0].databaseId // empty') | |
| fi | |
| if [ -z "$source_run_id" ]; then | |
| echo "::error::Could not determine a completed Fuzz Python Env Comparison run id" | |
| exit 1 | |
| fi | |
| case "$source_run_id" in | |
| ''|*[!0-9]*) | |
| echo "::error::source_run_id must resolve to a GitHub Actions run id" | |
| exit 1 | |
| ;; | |
| esac | |
| mkdir -p fuzz/replay-input fuzz/artifacts/python-env-replay | |
| gh run download "$source_run_id" -n "$SOURCE_ARTIFACT_NAME" -D fuzz/replay-input | |
| input_file=$(find fuzz/replay-input -maxdepth 1 -type f -name "${INPUT_PREFIX}*" | sort | head -n 1) | |
| if [ -z "$input_file" ]; then | |
| echo "::error::No ${INPUT_PREFIX}* input found in artifact ${SOURCE_ARTIFACT_NAME}" | |
| find fuzz/replay-input -maxdepth 1 -type f -print | |
| exit 1 | |
| fi | |
| source_sha=$(gh api "repos/${{ github.repository }}/actions/runs/$source_run_id" --jq .head_sha) | |
| printf 'source_run_id=%s\n' "$source_run_id" >> "$GITHUB_OUTPUT" | |
| printf 'input_file=%s\n' "$input_file" >> "$GITHUB_OUTPUT" | |
| printf 'input_name=%s\n' "$(basename "$input_file")" >> "$GITHUB_OUTPUT" | |
| printf 'input_size=%s\n' "$(wc -c < "$input_file" | tr -d ' ')" >> "$GITHUB_OUTPUT" | |
| printf 'source_sha=%s\n' "$source_sha" >> "$GITHUB_OUTPUT" | |
| - name: Record replay metadata | |
| run: | | |
| prefix="fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}" | |
| cp "${{ steps.input.outputs.input_file }}" "${prefix}-input.bin" | |
| { | |
| echo "source_run_id=${{ steps.input.outputs.source_run_id }}" | |
| echo "source_sha=${{ steps.input.outputs.source_sha }}" | |
| echo "source_artifact_name=${{ matrix.source_artifact_name }}" | |
| echo "input_name=${{ steps.input.outputs.input_name }}" | |
| echo "input_size=${{ steps.input.outputs.input_size }}" | |
| echo "policy=${{ matrix.env_policy }}" | |
| echo "workflow_sha=${{ github.sha }}" | |
| } > "${prefix}-metadata.txt" | |
| - name: Report effective Python environment | |
| env: | |
| PICKLE_FUZZ_PYTHON_ENV_POLICY: ${{ matrix.env_policy }} | |
| run: | | |
| prefix="fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}" | |
| cargo run --manifest-path fuzz/Cargo.toml --example report_python_env --quiet \ | |
| > "${prefix}-env.txt" | |
| - name: Replay saved fuzz artifact | |
| id: replay | |
| env: | |
| PICKLE_FUZZ_PYTHON_ENV_POLICY: ${{ matrix.env_policy }} | |
| run: | | |
| prefix="fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}" | |
| rm -rf fuzz/artifacts/validate_with_python | |
| mkdir -p fuzz/artifacts/validate_with_python | |
| set -o pipefail | |
| status=0 | |
| cargo fuzz run validate_with_python "${{ steps.input.outputs.input_file }}" -- \ | |
| -runs=1 \ | |
| -print_final_stats=1 \ | |
| -verbosity=1 | tee "${prefix}-replay.log" || status=$? | |
| printf 'cargo_status=%s\n' "$status" >> "$GITHUB_OUTPUT" | |
| - name: Classify replay outcome | |
| id: classify | |
| env: | |
| CARGO_STATUS: ${{ steps.replay.outputs.cargo_status }} | |
| run: | | |
| prefix="fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}" | |
| input_name='${{ steps.input.outputs.input_name }}' | |
| input_size='${{ steps.input.outputs.input_size }}' | |
| outcome=clean | |
| found_files='' | |
| for kind in crash timeout oom leak; do | |
| found=$(find fuzz/artifacts/validate_with_python -maxdepth 1 -type f -name "${kind}-*" | sort || true) | |
| if [ -n "$found" ]; then | |
| outcome=$kind | |
| found_files=$found | |
| break | |
| fi | |
| done | |
| if [ "$outcome" = clean ] && [ "${CARGO_STATUS:-0}" != "0" ]; then | |
| outcome=nonzero-no-artifact | |
| fi | |
| { | |
| echo "replay_outcome=$outcome" | |
| echo "cargo_status=${CARGO_STATUS:-0}" | |
| echo "matching_files<<EOF" | |
| printf '%s\n' "$found_files" | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| { | |
| echo "replay_outcome=$outcome" | |
| echo "cargo_status=${CARGO_STATUS:-0}" | |
| if [ -n "$found_files" ]; then | |
| echo "matching_files:" | |
| printf '%s\n' "$found_files" | |
| fi | |
| } >> "${prefix}-metadata.txt" | |
| { | |
| echo "### Replay result" | |
| echo | |
| echo "- Case: \`${{ matrix.case_name }}\`" | |
| echo "- Policy: \`${{ matrix.env_policy }}\`" | |
| echo "- Source run id: \`${{ steps.input.outputs.source_run_id }}\`" | |
| echo "- Source input: \`${input_name}\` (${input_size} bytes)" | |
| echo "- Outcome: \`$outcome\`" | |
| echo "- cargo fuzz exit status: \`${CARGO_STATUS:-0}\`" | |
| if [ -n "$found_files" ]; then | |
| echo "- Matching files:" | |
| printf '%s\n' "$found_files" | while IFS= read -r file; do | |
| echo " - \`$file\`" | |
| done | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload replay artifacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: fuzz-python-env-replay-${{ matrix.case_name }}-${{ matrix.policy_name }} | |
| path: | | |
| fuzz/artifacts/validate_with_python/ | |
| fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}-input.bin | |
| fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}-metadata.txt | |
| fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}-env.txt | |
| fuzz/artifacts/python-env-replay/${{ matrix.case_name }}-${{ matrix.policy_name }}-replay.log | |
| if-no-files-found: error |