git: 65a5b32c225a - stable/14 - buf: Avoid calling bufdomain() on newly initialized bufs

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 22 Sep 2026 14:49:22 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=65a5b32c225a2d6845d6f90470f9b01ba52c432a

commit 65a5b32c225a2d6845d6f90470f9b01ba52c432a
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-04 12:46:29 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-22 13:01:16 +0000

    buf: Avoid calling bufdomain() on newly initialized bufs
    
    bufinit() inserts newly initialized bufs into the QUEUE_EMPTY queue, at
    which point they haven't yet been assigned a domain.  Thus, bufdomain()
    returns &bdomain[-1], which trips the array-bounds sanitizer.
    
    This is harmless since we don't use the result in that case, but let's
    avoid the invalid access to begin with.  This is sufficient to let an
    amd64 kernel boot to a login prompt with -fsanitize=array-bounds
    configured.
    
    Reported by:    Andrew Griffiths <andrew@calif.io>
    Reviewed by:    rlibby, kib
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D59381
    
    (cherry picked from commit e1d903bbfaf91060c43209b35b78a9992fbffe5e)
---
 sys/kern/vfs_bio.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 62d70c04f6ea..ea86b8589bfa 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -2024,16 +2024,13 @@ bd_flushall(struct bufdomain *bd)
 static void
 bq_insert(struct bufqueue *bq, struct buf *bp, bool unlock)
 {
-	struct bufdomain *bd;
-
 	if (bp->b_qindex != QUEUE_NONE)
 		panic("bq_insert: free buffer %p onto another queue?", bp);
 
-	bd = bufdomain(bp);
 	if (bp->b_flags & B_AGE) {
 		/* Place this buf directly on the real queue. */
 		if (bq->bq_index == QUEUE_CLEAN)
-			bq = bd->bd_cleanq;
+			bq = bufdomain(bp)->bd_cleanq;
 		BQ_LOCK(bq);
 		TAILQ_INSERT_HEAD(&bq->bq_queue, bp, b_freelist);
 	} else {
@@ -2053,9 +2050,12 @@ bq_insert(struct bufqueue *bq, struct buf *bp, bool unlock)
 		BUF_UNLOCK(bp);
 
 	if (bp->b_qindex == QUEUE_CLEAN) {
+		struct bufdomain *bd;
+
 		/*
 		 * Flush the per-cpu queue and notify any waiters.
 		 */
+		bd = bufdomain(bp);
 		if (bd->bd_wanted || (bq != bd->bd_cleanq &&
 		    bq->bq_len >= bd->bd_lim))
 			bd_flush(bd, bq);