|
| 1 | +name: pickle-fuzzer |
| 2 | +description: Install and run the pickle-fuzzer CLI to generate pickle bytecode. |
| 3 | +author: Cisco AI Defense |
| 4 | + |
| 5 | +inputs: |
| 6 | + mode: |
| 7 | + description: "Mode to run: cli (default) or atheris." |
| 8 | + required: false |
| 9 | + default: "cli" |
| 10 | + version: |
| 11 | + description: > |
| 12 | + Release tag to download (e.g., v1.2.3). Defaults to the action ref if it |
| 13 | + looks like a tag; otherwise uses the latest release. |
| 14 | + required: false |
| 15 | + default: "" |
| 16 | + args: |
| 17 | + description: > |
| 18 | + Arguments passed directly to pickle-fuzzer. If set, other inputs are |
| 19 | + ignored. |
| 20 | + required: false |
| 21 | + default: "" |
| 22 | + output_dir: |
| 23 | + description: Output directory for batch generation (maps to --dir). |
| 24 | + required: false |
| 25 | + default: "" |
| 26 | + output_file: |
| 27 | + description: Output file path for single file mode (positional FILE). |
| 28 | + required: false |
| 29 | + default: "" |
| 30 | + samples: |
| 31 | + description: Number of samples to generate (maps to --samples). |
| 32 | + required: false |
| 33 | + default: "" |
| 34 | + protocol: |
| 35 | + description: Pickle protocol version 0-5 (maps to --protocol). |
| 36 | + required: false |
| 37 | + default: "" |
| 38 | + seed: |
| 39 | + description: Seed for reproducible generation (maps to --seed). |
| 40 | + required: false |
| 41 | + default: "" |
| 42 | + min_opcodes: |
| 43 | + description: Minimum opcodes to generate (maps to --min-opcodes). |
| 44 | + required: false |
| 45 | + default: "" |
| 46 | + max_opcodes: |
| 47 | + description: Maximum opcodes to generate (maps to --max-opcodes). |
| 48 | + required: false |
| 49 | + default: "" |
| 50 | + mutators: |
| 51 | + description: > |
| 52 | + Comma or space separated mutators (maps to repeated --mutators flags). |
| 53 | + required: false |
| 54 | + default: "" |
| 55 | + mutation_rate: |
| 56 | + description: Mutation probability 0.0-1.0 (maps to --mutation-rate). |
| 57 | + required: false |
| 58 | + default: "" |
| 59 | + unsafe_mutations: |
| 60 | + description: Allow mutations that may produce invalid pickles. |
| 61 | + required: false |
| 62 | + default: "false" |
| 63 | + allow_ext: |
| 64 | + description: Allow EXT* opcodes (requires extension registry). |
| 65 | + required: false |
| 66 | + default: "false" |
| 67 | + allow_buffer: |
| 68 | + description: Allow buffer opcodes (requires out-of-band buffer support). |
| 69 | + required: false |
| 70 | + default: "false" |
| 71 | + install_only: |
| 72 | + description: Only install pickle-fuzzer without running it. |
| 73 | + required: false |
| 74 | + default: "false" |
| 75 | + python_version: |
| 76 | + description: Python version for atheris mode. |
| 77 | + required: false |
| 78 | + default: "3.11" |
| 79 | + harness: |
| 80 | + description: Path to the Atheris harness script (required for atheris mode). |
| 81 | + required: false |
| 82 | + default: "" |
| 83 | + harness_args: |
| 84 | + description: Arguments passed to the harness script (atheris mode). |
| 85 | + required: false |
| 86 | + default: "" |
| 87 | + |
| 88 | +outputs: |
| 89 | + binary-path: |
| 90 | + description: Path to the installed pickle-fuzzer binary. |
| 91 | + value: ${{ steps.install.outputs.binary-path }} |
| 92 | + resolved-version: |
| 93 | + description: Version tag resolved for download. |
| 94 | + value: ${{ steps.install.outputs.resolved-version }} |
| 95 | + |
| 96 | +runs: |
| 97 | + using: composite |
| 98 | + steps: |
| 99 | + - name: Validate mode |
| 100 | + shell: bash |
| 101 | + run: | |
| 102 | + case "${{ inputs.mode }}" in |
| 103 | + cli|atheris) ;; |
| 104 | + *) echo "Unsupported mode: ${{ inputs.mode }}" >&2; exit 1 ;; |
| 105 | + esac |
| 106 | +
|
| 107 | + - id: install |
| 108 | + if: ${{ inputs.mode == 'cli' }} |
| 109 | + env: |
| 110 | + INPUT_VERSION: ${{ inputs.version }} |
| 111 | + INPUT_ARGS: ${{ inputs.args }} |
| 112 | + INPUT_OUTPUT_DIR: ${{ inputs.output_dir }} |
| 113 | + INPUT_OUTPUT_FILE: ${{ inputs.output_file }} |
| 114 | + INPUT_SAMPLES: ${{ inputs.samples }} |
| 115 | + INPUT_PROTOCOL: ${{ inputs.protocol }} |
| 116 | + INPUT_SEED: ${{ inputs.seed }} |
| 117 | + INPUT_MIN_OPCODES: ${{ inputs.min_opcodes }} |
| 118 | + INPUT_MAX_OPCODES: ${{ inputs.max_opcodes }} |
| 119 | + INPUT_MUTATORS: ${{ inputs.mutators }} |
| 120 | + INPUT_MUTATION_RATE: ${{ inputs.mutation_rate }} |
| 121 | + INPUT_UNSAFE_MUTATIONS: ${{ inputs.unsafe_mutations }} |
| 122 | + INPUT_ALLOW_EXT: ${{ inputs.allow_ext }} |
| 123 | + INPUT_ALLOW_BUFFER: ${{ inputs.allow_buffer }} |
| 124 | + INPUT_INSTALL_ONLY: ${{ inputs.install_only }} |
| 125 | + shell: bash |
| 126 | + run: | |
| 127 | + "${GITHUB_ACTION_PATH}/scripts/action-install.sh" |
| 128 | +
|
| 129 | + - name: Run pickle-fuzzer |
| 130 | + if: ${{ inputs.mode == 'cli' && inputs.install_only != 'true' && inputs.install_only != '1' && inputs.install_only != 'yes' }} |
| 131 | + env: |
| 132 | + INPUT_VERSION: ${{ inputs.version }} |
| 133 | + INPUT_ARGS: ${{ inputs.args }} |
| 134 | + INPUT_OUTPUT_DIR: ${{ inputs.output_dir }} |
| 135 | + INPUT_OUTPUT_FILE: ${{ inputs.output_file }} |
| 136 | + INPUT_SAMPLES: ${{ inputs.samples }} |
| 137 | + INPUT_PROTOCOL: ${{ inputs.protocol }} |
| 138 | + INPUT_SEED: ${{ inputs.seed }} |
| 139 | + INPUT_MIN_OPCODES: ${{ inputs.min_opcodes }} |
| 140 | + INPUT_MAX_OPCODES: ${{ inputs.max_opcodes }} |
| 141 | + INPUT_MUTATORS: ${{ inputs.mutators }} |
| 142 | + INPUT_MUTATION_RATE: ${{ inputs.mutation_rate }} |
| 143 | + INPUT_UNSAFE_MUTATIONS: ${{ inputs.unsafe_mutations }} |
| 144 | + INPUT_ALLOW_EXT: ${{ inputs.allow_ext }} |
| 145 | + INPUT_ALLOW_BUFFER: ${{ inputs.allow_buffer }} |
| 146 | + INPUT_INSTALL_ONLY: ${{ inputs.install_only }} |
| 147 | + shell: bash |
| 148 | + run: | |
| 149 | + "${GITHUB_ACTION_PATH}/scripts/action-run.sh" |
| 150 | +
|
| 151 | + - name: Setup Python (atheris) |
| 152 | + if: ${{ inputs.mode == 'atheris' }} |
| 153 | + uses: actions/setup-python@v5 |
| 154 | + with: |
| 155 | + python-version: ${{ inputs.python_version }} |
| 156 | + |
| 157 | + - name: Install Rust toolchain (atheris) |
| 158 | + if: ${{ inputs.mode == 'atheris' }} |
| 159 | + uses: dtolnay/rust-toolchain@stable |
| 160 | + |
| 161 | + - name: Run Atheris harness |
| 162 | + if: ${{ inputs.mode == 'atheris' }} |
| 163 | + env: |
| 164 | + INPUT_HARNESS: ${{ inputs.harness }} |
| 165 | + INPUT_HARNESS_ARGS: ${{ inputs.harness_args }} |
| 166 | + shell: bash |
| 167 | + run: | |
| 168 | + "${GITHUB_ACTION_PATH}/scripts/action-atheris.sh" |
0 commit comments