git: 114ba4f2cdc7 - stable/13 - bhyve: Initialize stack buffer in pci_ahci

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Tue, 19 Nov 2024 21:17:02 UTC
The branch stable/13 has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=114ba4f2cdc7e9da255ddf9d08726006dbfd7e28

commit 114ba4f2cdc7e9da255ddf9d08726006dbfd7e28
Author:     Pierre Pronchery <pierre@freebsdfoundation.org>
AuthorDate: 2024-07-23 14:34:03 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2024-11-19 17:38:10 +0000

    bhyve: Initialize stack buffer in pci_ahci
    
    In the function ahci_handle_dsm_trim, if the call to read_prdt fails,
    the variable buf[512] is used while it contains uninitialized data.
    
    It is easy to make the call to read_prdt fail, for instance if
    hdr->prdtl == NULL, the function will return without writing anything in
    buf.
    
    In addition, this code could be hardened by checking the value of done
    before accessing &buf[done].
    
    Reported by:    Synacktiv
    Reviewed by:    markj
    Security:       HYP-15
    Sponsored by:   The Alpha-Omega Project
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D46090
    
    (cherry picked from commit 71fa171c6480d60f4d9c01dea1c71a7249e7b8ab)
    (cherry picked from commit babfd2e46762cb835fec66945aa60404f247c521)
---
 usr.sbin/bhyve/pci_ahci.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c
index 8a48eb00e9b0..33ca389944f8 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -781,7 +781,7 @@ ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis)
 	assert(err == 0);
 }
 
-static inline void
+static inline unsigned int
 read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf,
     unsigned int size)
 {
@@ -808,6 +808,7 @@ read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf,
 		to += sublen;
 		prdt++;
 	}
+	return (size - len);
 }
 
 static void
@@ -820,6 +821,7 @@ ahci_handle_dsm_trim(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done
 	uint32_t len, elen;
 	int err, first, ncq;
 	uint8_t buf[512];
+	unsigned int written;
 
 	first = (done == 0);
 	if (cfis[2] == ATA_DATA_SET_MANAGEMENT) {
@@ -831,9 +833,12 @@ ahci_handle_dsm_trim(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done
 		len *= 512;
 		ncq = 1;
 	}
-	read_prdt(p, slot, cfis, buf, sizeof(buf));
+	written = read_prdt(p, slot, cfis, buf, sizeof(buf));
+	memset(buf + written, 0, sizeof(buf) - written);
 
 next:
+	if (done >= sizeof(buf) - 8)
+		return;
 	entry = &buf[done];
 	elba = ((uint64_t)entry[5] << 40) |
 		((uint64_t)entry[4] << 32) |