git: bfe8e339eb77 - main - bhyve: Fix a global buffer overread in the PCI hda device model.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);