DragonFlyBSD Kernel Audit
← triage · dashboard
DF-2263

EOF drain loop in sastart re-processes freed bio (double biodone / kernel hang)

Summary

In sastart SA_FLAG_ERR_PENDING path when SA_FLAG_EOF_PENDING set and additional bios remain queued code does biodone(done_bio) goto again without refreshing local bio pointer. Label again re-runs bioq_remove(bp=bio->bio_buf) bp->b_resid=bp->b_bcount biodone(done_bio) on SAME already-removed already-completed bio. bioq_first() keeps returning still-queued successor this is unbounded loop calling biodone() on same bio indefinitely. Each iteration decrements queue_count underflowing it. On second biodone bp may have been relpbuf()d by physio waiter buf re-handed to parallel physio on another CPU so bp->bio_buf deref and second biodone(bio) operate on recycled buffer completing wrong not-yet-submitted I/O corrupting buffer state. bpdone KASSERTs bp->b_cmd!=BUF_CMD_DONE second biodone panics DEBUG kernels. Reachable: user with SYSCAP_RESTRICTEDROOT opens tape device fixed-block mode triggers concurrent queued reads encountering filemark SA_FLAG_EOF_PENDING set in saerror. Impact: kernel lockup with SIM lock held CAM queue stalled queue_count underflow repeated biodone hard local DoS; likely bp reuse by parallel physio corrupts buffer-cache state.

Discussion (0)

No comments yet.