pci: Fix silent truncation of pcie_aer_inject_error argument
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>
This commit is contained in:
parent
0bcaaff8d8
commit
236aafa61c
|
@ -30,6 +30,7 @@
|
||||||
#include "hw/pci/pci_bus.h"
|
#include "hw/pci/pci_bus.h"
|
||||||
#include "hw/pci/pcie_regs.h"
|
#include "hw/pci/pcie_regs.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
|
|
||||||
//#define DEBUG_PCIE
|
//#define DEBUG_PCIE
|
||||||
#ifdef 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 *id = qdict_get_str(qdict, "id");
|
||||||
const char *error_name;
|
const char *error_name;
|
||||||
uint32_t error_status;
|
uint32_t error_status;
|
||||||
|
unsigned int num;
|
||||||
bool correctable;
|
bool correctable;
|
||||||
PCIDevice *dev;
|
PCIDevice *dev;
|
||||||
PCIEAERErr err;
|
PCIEAERErr err;
|
||||||
|
@ -983,14 +985,13 @@ static int do_pcie_aer_inject_error(Monitor *mon,
|
||||||
|
|
||||||
error_name = qdict_get_str(qdict, "error_status");
|
error_name = qdict_get_str(qdict, "error_status");
|
||||||
if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
|
if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
|
||||||
char *e = NULL;
|
if (qemu_strtoui(error_name, NULL, 0, &num) < 0) {
|
||||||
error_status = strtoul(error_name, &e, 0);
|
|
||||||
correctable = qdict_get_try_bool(qdict, "correctable", false);
|
|
||||||
if (!e || *e != '\0') {
|
|
||||||
monitor_printf(mon, "invalid error status value. \"%s\"",
|
monitor_printf(mon, "invalid error status value. \"%s\"",
|
||||||
error_name);
|
error_name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
error_status = num;
|
||||||
|
correctable = qdict_get_try_bool(qdict, "correctable", false);
|
||||||
}
|
}
|
||||||
err.status = error_status;
|
err.status = error_status;
|
||||||
err.source_id = pci_requester_id(dev);
|
err.source_id = pci_requester_id(dev);
|
||||||
|
|
Loading…
Reference in New Issue