git: bfe8e339eb77 - main - bhyve: Fix a global buffer overread in the PCI hda device model.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 20 Jan 2023 17:59:15 UTC
The branch main has been updated by jhb:

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

commit bfe8e339eb77910c2eb739b45aaa936148b33897
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2023-01-20 17:57:45 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2023-01-20 17:57:45 +0000

    bhyve: Fix a global buffer overread in the PCI hda device model.
    
    hda_write did not validate the relative register offset before using
    it as an index into the hda_set_reg_table array to lookup a function
    pointer to execute after updating the register's value.
    
    PR:             264435
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    Reviewed by:    corvink, markj, emaste
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D38127
---
 usr.sbin/bhyve/pci_hda.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/usr.sbin/bhyve/pci_hda.c b/usr.sbin/bhyve/pci_hda.c
index 9b0d4bd02ba0..bb8fba1a54bb 100644
--- a/usr.sbin/bhyve/pci_hda.c
+++ b/usr.sbin/bhyve/pci_hda.c
@@ -30,6 +30,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
 #include <time.h>
 
 #include "pci_hda.h"
@@ -51,8 +52,6 @@ __FBSDID("$FreeBSD$");
 #define HDA_CODEC_MAX		0x0f
 #define HDA_LAST_OFFSET						\
 	(0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
-#define HDA_SET_REG_TABLE_SZ					\
-	(0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
 #define HDA_CORB_ENTRY_LEN	0x04
 #define HDA_RIRB_ENTRY_LEN	0x08
 #define HDA_BDL_ENTRY_LEN	0x10
@@ -246,8 +245,6 @@ static const hda_set_reg_handler hda_set_reg_table[] = {
 	HDAC_OSTREAM(1, HDA_ISS_NO, HDA_OSS_NO)
 	HDAC_OSTREAM(2, HDA_ISS_NO, HDA_OSS_NO)
 	HDAC_OSTREAM(3, HDA_ISS_NO, HDA_OSS_NO)
-
-	[HDA_SET_REG_TABLE_SZ] = NULL,
 };
 
 static const uint16_t hda_corb_sizes[] = {
@@ -714,7 +711,10 @@ hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value)
 	uint32_t old = hda_get_reg_by_offset(sc, offset);
 	uint32_t masks[] = {0x00000000, 0x000000ff, 0x0000ffff,
 			0x00ffffff, 0xffffffff};
-	hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset];
+	hda_set_reg_handler set_reg_handler = NULL;
+
+	if (offset < nitems(hda_set_reg_table))
+		set_reg_handler = hda_set_reg_table[offset];
 
 	hda_set_field_by_offset(sc, offset, masks[size], value);