_hammer_ip_reseek() KKASSERTs on an EDEADLK-capable seek: INVARIANTS panic (or silent early iteration-EOF on release builds) when the btree re-seek deadlocks
| Field | Value |
|---|---|
| ID | DF-3013 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:H |
| CWE | CWE-754 |
| File | sys/vfs/hammer/hammer_object.c |
| Lines | 1492-1493 (vs :1443-1451; btree.c:869 documents EDEADLK) |
| Area | vfs/hammer |
| Confidence | speculative |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:vfs |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
_hammer_ip_seek_btree() explicitly tolerates EDEADLK from hammer_btree_iterate and propagates it, but _hammer_ip_reseek() wraps the call in KKASSERT(error == 0). Under flusher/frontend contention during a merged iteration whose rec_generation changed, an EDEADLK there panics an INVARIANTS kernel; on release builds error is __debugvar and the cursor has already been flagged DISKEOF|ATEDISK, so the iteration silently terminates early — e.g. hammer_ip_delete_range/delete_clean stop early, readdir misses entries. hammer_ip_first() handles the same error correctly, proving the reseek path is the outlier. Race-dependent, reachable from any unpriv merged iteration under heavy flusher contention. No PoC attempted (race, Low). Fix: handle EDEADLK instead of asserting — leave the DISKEOF|ATEDISK flags and propagate to hammer_ip_next()'s callers (all implement the terminate-cursor-and-retry protocol).
Timeline
- 2026-09-02 Discovered during pass-2 audit of hammer_object.c (GLM 5.3).
No comments yet.