aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorvin Köhne <CorvinK@beckhoff.com>2022-04-01 08:18:52 +0000
committerEmmanuel Vadot <manu@FreeBSD.org>2022-04-01 09:13:16 +0000
commit45ddbf211274eb28c0ccd0042640de57015dd390 (patch)
tree9dbef63b34f8de88e9fd4cc5bc0703f149d82e3a
parent4fc5a607fdf47ce5148e01d62ea474a4b6b0b238 (diff)
downloadsrc-45ddbf211274eb28c0ccd0042640de57015dd390.tar.gz
src-45ddbf211274eb28c0ccd0042640de57015dd390.zip
bhyve: avoid overflow of BAR index
At the moment, writes to BAR registers that aren't 4 byte aligned are ignored. So, there's no overflow yet. Nevertheless, if this behaviour changes in the future, it could unintentionally, introduce a buffer overflow. Additionally, some compiler or tools will detect this potential overflow and complain about it. Reviewed by: markj Signed-off-by: Corvin Köhne <c.koehne@beckhoff.com> Reported-by: Andy Fiddaman <andy@omniosce.org> Differential Revision: https://reviews.freebsd.org/D34689
-rw-r--r--usr.sbin/bhyve/pci_emul.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index 6005513eafe4..ab90c01c2394 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -166,6 +166,18 @@ CFGREAD(struct pci_devinst *pi, int coff, int bytes)
return (pci_get_cfgdata32(pi, coff));
}
+static int
+is_pcir_bar(int coff)
+{
+ return (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1));
+}
+
+static int
+is_pcir_bios(int coff)
+{
+ return (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4);
+}
+
/*
* I/O access
*/
@@ -2107,19 +2119,23 @@ pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func,
/*
* Special handling for write to BAR and ROM registers
*/
- if ((coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) ||
- (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4)) {
+ if (is_pcir_bar(coff) || is_pcir_bios(coff)) {
/*
* Ignore writes to BAR registers that are not
* 4-byte aligned.
*/
if (bytes != 4 || (coff & 0x3) != 0)
return;
- if (coff != PCIR_BIOS) {
+
+ if (is_pcir_bar(coff)) {
idx = (coff - PCIR_BAR(0)) / 4;
- } else {
+ } else if (is_pcir_bios(coff)) {
idx = PCI_ROM_IDX;
+ } else {
+ errx(4, "%s: invalid BAR offset %d", __func__,
+ coff);
}
+
mask = ~(pi->pi_bar[idx].size - 1);
switch (pi->pi_bar[idx].type) {
case PCIBAR_NONE: