]> git.proxmox.com Git - mirror_qemu.git/commitdiff
pci: Fix silent truncation of pcie_aer_inject_error argument
authorMarkus Armbruster <armbru@redhat.com>
Thu, 1 Dec 2022 12:11:28 +0000 (13:11 +0100)
committerMarkus Armbruster <armbru@redhat.com>
Mon, 19 Dec 2022 15:21:56 +0000 (16:21 +0100)
PCI AER error status is 32 bit.  The HMP command supports both
symbolic and numeric error status: anything that isn't a known
symbolic value is parsed as number with strtol().  Issues:

* Empty argument yields value zero.

* Range errors from strtol() are ignored, value is UINT32_MAX.

* Values not representable in uint32_t are silently truncated.

Fix to reject such input by switching to strtoui().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20221201121133.3813857-9-armbru@redhat.com>

hw/pci/pcie_aer.c

index eff62f3945576f34ee622322ee545a815f4725a7..58d20816d6f6d204978fccd94ea03a77e381545f 100644 (file)
@@ -30,6 +30,7 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pcie_regs.h"
 #include "qapi/error.h"
+#include "qemu/cutils.h"
 
 //#define DEBUG_PCIE
 #ifdef DEBUG_PCIE
@@ -963,6 +964,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
     const char *id = qdict_get_str(qdict, "id");
     const char *error_name;
     uint32_t error_status;
+    unsigned int num;
     bool correctable;
     PCIDevice *dev;
     PCIEAERErr err;
@@ -983,14 +985,13 @@ static int do_pcie_aer_inject_error(Monitor *mon,
 
     error_name = qdict_get_str(qdict, "error_status");
     if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
-        char *e = NULL;
-        error_status = strtoul(error_name, &e, 0);
-        correctable = qdict_get_try_bool(qdict, "correctable", false);
-        if (!e || *e != '\0') {
+        if (qemu_strtoui(error_name, NULL, 0, &num) < 0) {
             monitor_printf(mon, "invalid error status value. \"%s\"",
                            error_name);
             return -EINVAL;
         }
+        error_status = num;
+        correctable = qdict_get_try_bool(qdict, "correctable", false);
     }
     err.status = error_status;
     err.source_id = pci_requester_id(dev);