Skip to content

Commit 81b82ad

Browse files
committed
ci: buffer fuzz timeout above max_total_time so libFuzzer self-exits
The outer `timeout` wrapping `cargo fuzz run` must exceed -max_total_time. libFuzzer's clock starts after build + corpus-load, so an equal timeout always wins the race and SIGTERMs the process before its graceful "Done" self-exit — every run then logs "run interrupted", making a genuine hang indistinguishable from normal end-of-budget completion. - Quick Fuzz: timeout 120 -> 150 (max_total_time stays 120, +30s slack) - Deep Fuzzing: timeout 28800 -> 28980 (max_total_time stays 28800, +3min slack, within 540min job cap) Exit code 124 (genuine hang killed by timeout) remains tolerated.
1 parent a7737ec commit 81b82ad

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

‎.github/workflows/security.yml‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,12 @@ jobs:
124124
cd fuzz
125125
# Build first - fail fast on compile errors
126126
cargo fuzz build ${{ matrix.target }}
127-
# Run corpus - timeout exit code 124 is acceptable (means it ran)
128-
timeout 120 cargo fuzz run ${{ matrix.target }} -- -runs=0 -max_total_time=120 || [ $? -eq 124 ]
127+
# libFuzzer self-exits at -max_total_time (graceful "Done ..."); the outer
128+
# `timeout` is a +30s hang safety-net only. Buffer matters because libFuzzer's
129+
# clock starts after build/corpus-load, so an equal `timeout` would always
130+
# SIGTERM first ("run interrupted") and the graceful path would be unreachable.
131+
# Exit 124 (timeout fired = genuine hang) is still tolerated.
132+
timeout 150 cargo fuzz run ${{ matrix.target }} -- -runs=0 -max_total_time=120 || [ $? -eq 124 ]
129133
130134
deep-fuzz:
131135
name: Deep Fuzzing (8 hours)
@@ -183,8 +187,14 @@ jobs:
183187
cd fuzz
184188
# Build first - fail fast on compile errors
185189
cargo fuzz build ${{ matrix.target }}
186-
# Run fuzz - timeout exit code 124 is acceptable (means it ran the full duration)
187-
timeout 28800 cargo fuzz run ${{ matrix.target }} -- -max_total_time=28800 || [ $? -eq 124 ]
190+
# libFuzzer self-exits at -max_total_time=8h with a graceful "Done N runs ..."
191+
# (final stats + corpus consolidation). The outer `timeout` is +3min slack so
192+
# it only fires on a genuine hang — NOT as the normal end-of-budget stop. An
193+
# equal `timeout` would always win the race (libFuzzer's clock starts later,
194+
# after build/corpus-load) and every run would log "run interrupted" instead,
195+
# making a real hang indistinguishable from normal completion. Still inside the
196+
# 540min job cap. Exit 124 (hang killed by timeout) remains tolerated.
197+
timeout 28980 cargo fuzz run ${{ matrix.target }} -- -max_total_time=28800 || [ $? -eq 124 ]
188198
189199
- name: Upload crash artifacts
190200
if: always()

0 commit comments

Comments
 (0)