summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDov Murik <dovmurik@linux.ibm.com>2022-02-22 07:19:05 +0000
committerGerd Hoffmann <kraxel@redhat.com>2022-03-04 11:24:52 +0100
commit64915058e18c2fbff8c80f9ad2e5be854dee2965 (patch)
treeeb61900e92ff9f9870ce9527d4ad0b83b6558c63
parentbd7819de227f47df72e21558c019147673726a74 (diff)
downloadfocaccia-qemu-64915058e18c2fbff8c80f9ad2e5be854dee2965.tar.gz
focaccia-qemu-64915058e18c2fbff8c80f9ad2e5be854dee2965.zip
hw/i386: Improve bounds checking in OVMF table parsing
When pc_system_parse_ovmf_flash() parses the optional GUIDed table in
the end of the OVMF flash memory area, the table length field is checked
for sizes that are too small, but doesn't error on sizes that are too
big (bigger than the flash content itself).

Add a check for maximal size of the OVMF table, and add an error report
in case the size is invalid.  In such a case, an error like this will be
displayed during launch:

    qemu-system-x86_64: OVMF table has invalid size 4047

and the table parsing is skipped.

Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20220222071906.2632426-2-dovmurik@linux.ibm.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--hw/i386/pc_sysfw_ovmf.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/hw/i386/pc_sysfw_ovmf.c b/hw/i386/pc_sysfw_ovmf.c
index f4dd92c588..df15c9737b 100644
--- a/hw/i386/pc_sysfw_ovmf.c
+++ b/hw/i386/pc_sysfw_ovmf.c
@@ -24,6 +24,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "hw/i386/pc.h"
 #include "cpu.h"
 
@@ -66,7 +67,13 @@ void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size)
     ptr -= sizeof(uint16_t);
     tot_len = le16_to_cpu(*(uint16_t *)ptr) - sizeof(guid) - sizeof(uint16_t);
 
-    if (tot_len <= 0) {
+    if (tot_len < 0 || tot_len > (ptr - flash_ptr)) {
+        error_report("OVMF table has invalid size %d", tot_len);
+        return;
+    }
+
+    if (tot_len == 0) {
+        /* no entries in the OVMF table */
         return;
     }