Skip to content

Commit 0e12233

Browse files
committed
wip
Signed-off-by: Joe Isaacs <[email protected]>
1 parent 3a06737 commit 0e12233

File tree

1 file changed

+141
-10
lines changed

1 file changed

+141
-10
lines changed

.github/workflows/fuzz.yml

Lines changed: 141 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
outputs:
2020
crashes_found: ${{ steps.check.outputs.crashes_found }}
2121
crash_count: ${{ steps.check.outputs.crash_count }}
22+
first_crash_name: ${{ steps.check.outputs.first_crash_name }}
2223
steps:
2324
- uses: runs-on/action@v2
2425
with:
@@ -55,9 +56,19 @@ jobs:
5556
run: |
5657
if [ -d "fuzz/artifacts" ] && [ "$(ls -A fuzz/artifacts 2>/dev/null)" ]; then
5758
echo "crashes_found=true" >> $GITHUB_OUTPUT
58-
CRASH_COUNT=$(find fuzz/artifacts -type f \( -name "crash-*" -o -name "leak-*" -o -name "timeout-*" -o -name "oom-*" \) | wc -l)
59-
echo "crash_count=$CRASH_COUNT" >> $GITHUB_OUTPUT
60-
echo "Found $CRASH_COUNT crash(es)"
59+
60+
# Get the first crash file only
61+
FIRST_CRASH=$(find fuzz/artifacts -type f \( -name "crash-*" -o -name "leak-*" -o -name "timeout-*" -o -name "oom-*" \) | head -1)
62+
63+
if [ -n "$FIRST_CRASH" ]; then
64+
echo "first_crash=$FIRST_CRASH" >> $GITHUB_OUTPUT
65+
echo "first_crash_name=$(basename $FIRST_CRASH)" >> $GITHUB_OUTPUT
66+
67+
# Count all crashes for reporting
68+
CRASH_COUNT=$(find fuzz/artifacts -type f \( -name "crash-*" -o -name "leak-*" -o -name "timeout-*" -o -name "oom-*" \) | wc -l)
69+
echo "crash_count=$CRASH_COUNT" >> $GITHUB_OUTPUT
70+
echo "Found $CRASH_COUNT crash(es), will process first: $(basename $FIRST_CRASH)"
71+
fi
6172
else
6273
echo "crashes_found=false" >> $GITHUB_OUTPUT
6374
echo "crash_count=0" >> $GITHUB_OUTPUT
@@ -115,16 +126,136 @@ jobs:
115126
name: io-fuzzing-logs
116127
path: ./logs
117128

118-
- name: List downloaded files
129+
- name: Extract first crash only
119130
run: |
120-
echo "=== Crash Artifacts ==="
121-
ls -lah crash_artifacts/ || echo "No crash artifacts"
131+
# Only keep the first crash file for analysis
132+
FIRST_CRASH="${{ needs.io_fuzz.outputs.first_crash_name }}"
133+
echo "Processing only first crash: $FIRST_CRASH"
134+
135+
# Create a clean directory with just the first crash
136+
mkdir -p ./first_crash
137+
if [ -f "crash_artifacts/$FIRST_CRASH" ]; then
138+
cp "crash_artifacts/$FIRST_CRASH" ./first_crash/
139+
echo "Copied first crash to ./first_crash/"
140+
else
141+
echo "Warning: Could not find crash file $FIRST_CRASH"
142+
echo "Available files:"
143+
ls -la crash_artifacts/ || echo "No files in crash_artifacts"
144+
fi
145+
146+
- name: Show crash info
147+
run: |
148+
echo "=== Crash Summary ==="
149+
echo "Total crashes found: ${{ needs.io_fuzz.outputs.crash_count }}"
150+
echo "Processing first crash: ${{ needs.io_fuzz.outputs.first_crash_name }}"
122151
echo ""
123-
echo "=== Fuzzer Logs ==="
124-
ls -lah logs/ || echo "No logs"
152+
echo "=== First crash file size ==="
153+
ls -lh first_crash/ || echo "No crash file"
125154
echo ""
126-
echo "=== Log preview (first 50 lines) ==="
127-
head -50 logs/fuzz_output.log || echo "No log file"
155+
echo "=== Fuzzer log preview (last 100 lines, where crashes are reported) ==="
156+
tail -100 logs/fuzz_output.log || echo "No log file"
157+
158+
- name: Create GitHub issue
159+
env:
160+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
161+
run: |
162+
# Extract crash type from filename
163+
CRASH_FILE="${{ needs.io_fuzz.outputs.first_crash_name }}"
164+
if [[ "$CRASH_FILE" == crash-* ]]; then
165+
CRASH_TYPE="Crash"
166+
elif [[ "$CRASH_FILE" == leak-* ]]; then
167+
CRASH_TYPE="Memory Leak"
168+
elif [[ "$CRASH_FILE" == timeout-* ]]; then
169+
CRASH_TYPE="Timeout"
170+
elif [[ "$CRASH_FILE" == oom-* ]]; then
171+
CRASH_TYPE="Out of Memory"
172+
else
173+
CRASH_TYPE="Unknown"
174+
fi
175+
176+
# Create issue with gh CLI
177+
gh issue create \
178+
--repo ${{ github.repository }} \
179+
--title "Fuzzing $CRASH_TYPE: file_io - $(date -u +%Y-%m-%d)" \
180+
--label "bug,fuzzing,file_io-fuzz,needs-triage" \
181+
--body-file - <<'EOF'
182+
## Fuzzing Crash Report
183+
184+
The `file_io` fuzzing target detected a $CRASH_TYPE during a scheduled fuzzing run.
185+
186+
### Summary
187+
188+
- **Crash Type**: $CRASH_TYPE
189+
- **Target**: `file_io`
190+
- **Crash File**: `${{ needs.io_fuzz.outputs.first_crash_name }}`
191+
- **Total Crashes Found**: ${{ needs.io_fuzz.outputs.crash_count }}
192+
- **Workflow Run**: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
193+
- **Timestamp**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
194+
- **Branch**: ${{ github.ref_name }}
195+
- **Commit**: ${{ github.sha }}
196+
197+
### Crash Artifacts
198+
199+
Download crash artifacts from the workflow run:
200+
**https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}**
201+
202+
Artifacts available:
203+
- `io-fuzzing-crash-artifacts` - All crash files found (includes ${{ needs.io_fuzz.outputs.crash_count }} crashes)
204+
- `io-fuzzing-logs` - Complete fuzzer output with stack traces
205+
206+
### Reproduction Steps
207+
208+
1. Download the `io-fuzzing-crash-artifacts` from the workflow run above
209+
2. Extract the crash file to your local `fuzz/artifacts/file_io/` directory
210+
3. Reproduce the crash locally:
211+
212+
```bash
213+
cargo +nightly fuzz run file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
214+
```
215+
216+
4. Get full backtrace:
217+
218+
```bash
219+
RUST_BACKTRACE=full cargo +nightly fuzz run file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
220+
```
221+
222+
5. Minimize the test case (optional):
223+
224+
```bash
225+
cargo +nightly fuzz tmin file_io fuzz/artifacts/file_io/${{ needs.io_fuzz.outputs.first_crash_name }}
226+
```
227+
228+
### Investigation Checklist
229+
230+
- [ ] Download crash artifacts from workflow run
231+
- [ ] Reproduce crash locally with full backtrace
232+
- [ ] Analyze stack trace and identify root cause
233+
- [ ] Determine severity (security vs stability)
234+
- [ ] Check if this is a duplicate of an existing issue
235+
- [ ] Minimize test case if needed
236+
- [ ] Create fix PR with reference to this issue
237+
- [ ] Add regression test
238+
- [ ] Verify fix with: `cargo +nightly fuzz run file_io <crash-file>`
239+
240+
### Environment
241+
242+
- **Runner**: ubuntu24-full-arm64
243+
- **Rust Toolchain**: nightly
244+
- **Fuzz Duration**: 7200 seconds (2 hours)
245+
- **Fuzzer**: cargo-fuzz (libFuzzer)
246+
247+
### Additional Context
248+
249+
This issue was automatically created by the fuzzing workflow. If multiple crashes were found, this issue represents the first crash detected. All crash artifacts are available for download.
250+
251+
**Note**: If this issue is a duplicate of an existing bug, please close it and reference the original issue.
252+
253+
---
254+
255+
*Automatically created by fuzzing workflow*
256+
*Workflow file: [fuzz.yml](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/fuzz.yml)*
257+
*Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}*
258+
EOF
128259
129260
ops_fuzz:
130261
name: "Array Operations Fuzz"

0 commit comments

Comments
 (0)