[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 12/14] hw/intc/arm_gicv3_its: Check table bounds against correct
From: |
Peter Maydell |
Subject: |
[PATCH 12/14] hw/intc/arm_gicv3_its: Check table bounds against correct limit |
Date: |
Sat, 22 Jan 2022 18:24:42 +0000 |
Currently when we fill in a TableDesc based on the value the guest
has written to the GITS_BASER<n> register, we calculate both:
* num_entries : the number of entries in the table, constrained
by the amount of memory the guest has given it
* num_ids : the number of IDs we support for this table,
constrained by the implementation choices and the architecture
(eg DeviceIDs are 16 bits, so num_ids is 1 << 16)
When validating ITS commands, however, we check only num_ids,
thus allowing a broken guest to specify table entries that
index off the end of it. This will only corrupt guest memory,
but the ITS is supposed to reject such commands as invalid.
Instead of calculating both num_entries and num_ids, set
num_entries to the minimum of the two limits, and check that.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/intc/arm_gicv3_its_common.h | 1 -
hw/intc/arm_gicv3_its.c | 18 +++++++++---------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/include/hw/intc/arm_gicv3_its_common.h
b/include/hw/intc/arm_gicv3_its_common.h
index b32c697207f..3e2ad2dff60 100644
--- a/include/hw/intc/arm_gicv3_its_common.h
+++ b/include/hw/intc/arm_gicv3_its_common.h
@@ -47,7 +47,6 @@ typedef struct {
uint16_t entry_sz;
uint32_t page_sz;
uint32_t num_entries;
- uint32_t num_ids;
uint64_t base_addr;
} TableDesc;
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index 237198845d7..3f2ead45369 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -256,10 +256,10 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s,
uint64_t value,
eventid = (value & EVENTID_MASK);
- if (devid >= s->dt.num_ids) {
+ if (devid >= s->dt.num_entries) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: devid %d>=%d",
- __func__, devid, s->dt.num_ids);
+ __func__, devid, s->dt.num_entries);
return CMD_CONTINUE;
}
@@ -300,7 +300,7 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s,
uint64_t value,
return CMD_CONTINUE;
}
- if (icid >= s->ct.num_ids) {
+ if (icid >= s->ct.num_entries) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
__func__, icid);
@@ -384,10 +384,10 @@ static ItsCmdResult process_mapti(GICv3ITSState *s,
uint64_t value,
icid = value & ICID_MASK;
- if (devid >= s->dt.num_ids) {
+ if (devid >= s->dt.num_entries) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid command attributes: devid %d>=%d",
- __func__, devid, s->dt.num_ids);
+ __func__, devid, s->dt.num_entries);
return CMD_CONTINUE;
}
@@ -400,7 +400,7 @@ static ItsCmdResult process_mapti(GICv3ITSState *s,
uint64_t value,
num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
- if ((icid >= s->ct.num_ids)
+ if ((icid >= s->ct.num_entries)
|| !dte_valid || (eventid >= num_eventids) ||
(((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) &&
(pIntid != INTID_SPURIOUS))) {
@@ -485,7 +485,7 @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t
offset)
valid = (value & CMD_FIELD_VALID_MASK);
- if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) {
+ if ((icid >= s->ct.num_entries) || (rdbase >= s->gicv3->num_cpu)) {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS MAPC: invalid collection table attributes "
"icid %d rdbase %" PRIu64 "\n", icid, rdbase);
@@ -566,7 +566,7 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t
value,
valid = (value & CMD_FIELD_VALID_MASK);
- if ((devid >= s->dt.num_ids) ||
+ if ((devid >= s->dt.num_entries) ||
(size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
qemu_log_mask(LOG_GUEST_ERROR,
"ITS MAPD: invalid device table attributes "
@@ -791,7 +791,7 @@ static void extract_table_params(GICv3ITSState *s)
L1TABLE_ENTRY_SIZE) *
(page_sz / td->entry_sz));
}
- td->num_ids = 1ULL << idbits;
+ td->num_entries = MIN(td->num_entries, 1ULL << idbits);
}
}
--
2.25.1
- [PATCH 11/14] hw/intc/arm_gicv3_its: Make GITS_BASER<n> RAZ/WI for unimplemented registers, (continued)
- [PATCH 11/14] hw/intc/arm_gicv3_its: Make GITS_BASER<n> RAZ/WI for unimplemented registers, Peter Maydell, 2022/01/22
- [PATCH 04/14] hw/intc/arm_gicv3_its: Don't clear GITS_CREADR when GITS_CTLR.ENABLED is set, Peter Maydell, 2022/01/22
- [PATCH 06/14] hw/intc/arm_gicv3: Honour GICD_CTLR.EnableGrp1NS for LPIs, Peter Maydell, 2022/01/22
- [PATCH 05/14] hw/intc/arm_gicv3_its: Don't clear GITS_CWRITER on writes to GITS_CBASER, Peter Maydell, 2022/01/22
- [PATCH 09/14] hw/intc/arm_gicv3: Set GICR_CTLR.CES if LPIs are supported, Peter Maydell, 2022/01/22
- [PATCH 12/14] hw/intc/arm_gicv3_its: Check table bounds against correct limit,
Peter Maydell <=
- [PATCH 08/14] hw/intc/arm_gicv3_redist: Remove unnecessary zero checks, Peter Maydell, 2022/01/22
- [PATCH 01/14] target/arm: Log CPU index in 'Taking exception' log, Peter Maydell, 2022/01/22