Check whenever pnp roms attempt to redirect int19, and in case it does
log a message and undo the redirect.
A pnp rom should not need this, we have BEVs and BCVs for that.
Nevertheless there are roms in the wild which are redirecting int19.
At least some BIOS implementations for physical hardware have a config
option in the setup to allow/disallow int19 redirections, so just not
allowing this seems to be the way to deal with this situation.
Buglink: https://bugzilla.redhat.com//show_bug.cgi?id=1642135
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/optionroms.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/src/optionroms.c b/src/optionroms.c
index fc992f649f..e90900b790 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -8,6 +8,7 @@
#include "bregs.h" // struct bregs
#include "config.h" // CONFIG_*
#include "farptr.h" // FLATPTR_TO_SEG
+#include "biosvar.h" // GET_IVT
#include "hw/pci.h" // pci_config_readl
#include "hw/pcidevice.h" // foreachpci
#include "hw/pci_ids.h" // PCI_CLASS_DISPLAY_VGA
@@ -308,6 +309,24 @@ fail:
return NULL;
}
+static int boot_irq_captured(void)
+{
+ struct segoff_s current, seabios;
+
+ current = GET_IVT(0x19);
+ seabios = FUNC16(entry_19_official);
+ return ((current.seg != seabios.seg) ||
+ (current.offset != current.offset));
+}
+
+static void boot_irq_restore(void)
+{
+ struct segoff_s seabios;
+
+ seabios = FUNC16(entry_19_official);
+ SET_IVT(0x19, seabios);
+}
+
// Attempt to map and initialize the option rom on a given PCI device.
static void
init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
@@ -327,8 +346,18 @@ init_pcirom(struct pci_device *pci, int isvga, u64 *sources)
if (! rom)
// No ROM present.
return;
+ int irq_was_captured = boot_irq_captured();
+ struct pnp_data *pnp = get_pnp_rom(rom);
setRomSource(sources, rom, RS_PCIROM | (u32)pci);
init_optionrom(rom, pci->bdf, isvga);
+ if (boot_irq_captured() && !irq_was_captured &&
+ !file && !isvga && pnp) {
+ // This PCI rom is misbehaving - recapture the boot irqs
+ char *desc = MAKE_FLATPTR(FLATPTR_TO_SEG(rom), pnp->productname);
+ dprintf(1, "PnP optionrom \"%s\" (bdf %pP) captured int19, restoring\n",
+ desc, pci);
+ boot_irq_restore();
+ }
}
--
2.9.3
Check whenever pnp roms attempt to redirect int19, and in case it does
log a message and undo the redirect.
A pnp rom should not need this, we have BEVs and BCVs for that.
Nevertheless there are roms in the wild which are redirecting int19.
At least some BIOS implementations for physical hardware have a config
option in the setup to allow/disallow int19 redirections, so just not
allowing this seems to be the way to deal with this situation.
Buglink: https://bugzilla.redhat.com//show_bug.cgi?id=1642135
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/optionroms.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/optionroms.c b/src/optionroms.c
index fc992f649f..4ec5504ca9 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -8,6 +8,7 @@
#include "bregs.h" // struct bregs
#include "config.h" // CONFIG_*
#include "farptr.h" // FLATPTR_TO_SEG
+#include "biosvar.h" // GET_IVT
#include "hw/pci.h" // pci_config_readl
#include "hw/pcidevice.h" // foreachpci
#include "hw/pci_ids.h" // PCI_CLASS_DISPLAY_VGA
@@ -136,9 +137,24 @@ init_optionrom(struct rom_header *rom, u16 bdf, int isvga)
tpm_option_rom(newrom, rom->size * 512);
- if (isvga || get_pnp_rom(newrom))
+ struct pnp_data *pnp = get_pnp_rom(newrom);
+ if (isvga || pnp) {
+ struct segoff_s old19, new19;
// Only init vga and PnP roms here.
+ old19 = GET_IVT(0x19);
callrom(newrom, bdf);
+ new19 = GET_IVT(0x19);
+ if (old19.seg != new19.seg ||
+ old19.offset != new19.offset) {
+ dprintf(1, "WARNING! rom tried to hijack int19 "
+ "(vec %04x:%04x, pnp %s, bev %s, bvc %s)\n",
+ new19.seg, new19.offset,
+ pnp ? "yes" : "no",
+ pnp && pnp->bev ? "yes" : "no",
+ pnp && pnp->bcv ? "yes" : "no");
+ SET_IVT(0x19, old19);
+ }
+ }
return rom_confirm(newrom->size * 512);
}
--
2.9.3
Hi,
I noticed, that both bootloader - and kernel code are able to make BIOS ROM section writable again.
This allows hostile code to make modifications to ROM contents, and then run the modified code.
This may allow malicious code to gain privilege escalation from ring0 to ring -2 if I have not
misunderstood this.
Care to verify wheter this is an issue or not?
- k4m1
Hi,
Time to prepare the 1.12.1 stable release for the upcoming qemu 4.0.
These patches went into master since 1.12.0:
# git log --reverse --oneline rel-1.12.0..master
42efebdf1d12 tpm: Check for TPM related ACPI tables before attempting hw probe
628b2e6b0e39 pvscsi: ring_desc do not have to be page aligned
75b428351345 qemu: avoid debug prints if debugcon is not enabled
29ba89e67ff3 output: Avoid thunking to 16bit mode in printf() if no vgabios
d62ca8c9c53f docs: Update mailing list archive links
34fe8660ec42 docs: Fix cut-and-paste error in Mailinglist.md archive link
63d69674666e bootsplash: Added support for 16/24/32bpp in one function
996d3c029713 usb-ehci: Clear pipe token on pipe reallocate
b7dbd200cfe9 tcgbios: Use table to convert hash to buffer size
171fc8979dc7 tcgbios: Implement TPM 2.0 menu item to activate and deactivate PCR banks
42efebdf1d12 is already cherry-picked into the 1.12-stable branch.
996d3c029713 looks like an obvious bugfix to me.
Other requests / candidates?
thanks,
Gerd
Seabios freezes (hangs) on "Press ESC for boot menu". Does not respond to
the keyboard and does not boot from the sata disk. Last post code 0x7b.
Console (full) output in putty_atomC3538.log. Coreboot 4.9 cfg in
coreboot.config. Seabios config in seabios.config.