In this from Bhyve's pci_hda.c: static int 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); ...; hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset]; ...; if (set_reg_handler) set_reg_handler(sc, offset, old); hda_set_reg_table[] has 385 entries. The guest gets to specify offset, and it can be up to 8580 (HDA_LAST_OFFSET, enforced in hda_get_reg_by_offset). So a malicious guest has a bunch of options for where the call to set_reg_handler() can end up. You can demo this by adding HDAC_WRITE_4(&sc->mem, 0x4a4, 0x0); at the start of hdac_reset() in /sys/dev/sound/pci/hda/hdac.c and booting the resulting guest kernel on Bhyve.
Thank you for your report and analysis Robert. ^Triage: Ed may also be interested in this (see base 9349d3784578)
A commit in branch main references this bug: 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(-)
A commit in branch stable/13 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=f31dc54deed4bfc2779a991758033c36a9bf6fd1 commit f31dc54deed4bfc2779a991758033c36a9bf6fd1 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2023-01-20 17:57:45 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2023-01-26 22:28:56 +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 (cherry picked from commit bfe8e339eb77910c2eb739b45aaa936148b33897) usr.sbin/bhyve/pci_hda.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
Fix merged to stable/13. Code not present in stable/12.