git: babfd2e46762 - stable/14 - bhyve: Initialize stack buffer in pci_ahci
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Oct 2024 19:28:13 UTC
The branch stable/14 has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=babfd2e46762cb835fec66945aa60404f247c521
commit babfd2e46762cb835fec66945aa60404f247c521
Author: Pierre Pronchery <pierre@freebsdfoundation.org>
AuthorDate: 2024-07-23 14:34:03 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2024-10-29 19:19:45 +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)
---
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 1eef285a871c..e4c877229425 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -782,7 +782,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)
{
@@ -809,6 +809,7 @@ read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, void *buf,
to += sublen;
prdt++;
}
+ return (size - len);
}
static void
@@ -821,6 +822,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) {
@@ -832,9 +834,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) |