From: Kirill A. Korinsky Subject: sys/vfs: protect vfs_syncwait() bufhead traversal To: OpenBSD tech Date: Mon, 03 Aug 2026 00:51:46 +0200 tech@, vfs_syncwait() traverses bufhead without splbio(), allowing I/O completion to release the current buffer before LIST_FOREACH() reads its next pointer; protect the traversal, drop the priority before bawrite(), then restart because synchronous completion may release the acquired buffer. Have I missed something? Index: sys/kern/vfs_subr.c =================================================================== RCS file: /home/cvs/src/sys/kern/vfs_subr.c,v diff -u -p -r1.335 vfs_subr.c --- sys/kern/vfs_subr.c 30 Jun 2026 14:04:03 -0000 1.335 +++ sys/kern/vfs_subr.c 2 Aug 2026 22:43:13 -0000 @@ -1839,7 +1839,9 @@ vfs_syncwait(struct proc *p, int verbose /* Wait for sync to finish. */ dcount = 10000; for (iter = 0; iter < 20; iter++) { + restart: nbusy = 0; + s = splbio(); LIST_FOREACH(bp, &bufhead, b_list) { if ((bp->b_flags & (B_BUSY|B_INVAL|B_READ)) == B_BUSY) nbusy++; @@ -1853,19 +1855,19 @@ vfs_syncwait(struct proc *p, int verbose * own with testing.. XXX */ if (bp->b_flags & B_DELWRI) { - s = splbio(); bufcache_take(bp); buf_acquire(bp); splx(s); - nbusy++; bawrite(bp); if (dcount-- <= 0) { if (verbose) printf("softdep "); return 1; } + goto restart; } } + splx(s); if (nbusy == 0) break; if (verbose) -- wbr, Kirill