Révision | 8b8bb0146b5383188e045ab75a53a0e179614cad (tree) |
---|---|
l'heure | 2022-01-28 23:29:47 |
Auteur | Peter Maydell <peter.maydell@lina...> |
Commiter | Peter Maydell |
hw/intc/arm_gicv3_its: Check table bounds against correct limit
Currently when we fill in a TableDesc based on the value the guest
has written to the GITS_BASER<n> register, we calculate both:
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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220122182444.724087-13-peter.maydell@linaro.org
@@ -256,10 +256,10 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value, | ||
256 | 256 | |
257 | 257 | eventid = (value & EVENTID_MASK); |
258 | 258 | |
259 | - if (devid >= s->dt.num_ids) { | |
259 | + if (devid >= s->dt.num_entries) { | |
260 | 260 | qemu_log_mask(LOG_GUEST_ERROR, |
261 | 261 | "%s: invalid command attributes: devid %d>=%d", |
262 | - __func__, devid, s->dt.num_ids); | |
262 | + __func__, devid, s->dt.num_entries); | |
263 | 263 | return CMD_CONTINUE; |
264 | 264 | } |
265 | 265 |
@@ -300,7 +300,7 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value, | ||
300 | 300 | return CMD_CONTINUE; |
301 | 301 | } |
302 | 302 | |
303 | - if (icid >= s->ct.num_ids) { | |
303 | + if (icid >= s->ct.num_entries) { | |
304 | 304 | qemu_log_mask(LOG_GUEST_ERROR, |
305 | 305 | "%s: invalid ICID 0x%x in ITE (table corrupted?)\n", |
306 | 306 | __func__, icid); |
@@ -384,10 +384,10 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value, | ||
384 | 384 | |
385 | 385 | icid = value & ICID_MASK; |
386 | 386 | |
387 | - if (devid >= s->dt.num_ids) { | |
387 | + if (devid >= s->dt.num_entries) { | |
388 | 388 | qemu_log_mask(LOG_GUEST_ERROR, |
389 | 389 | "%s: invalid command attributes: devid %d>=%d", |
390 | - __func__, devid, s->dt.num_ids); | |
390 | + __func__, devid, s->dt.num_entries); | |
391 | 391 | return CMD_CONTINUE; |
392 | 392 | } |
393 | 393 |
@@ -400,7 +400,7 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value, | ||
400 | 400 | num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1); |
401 | 401 | num_intids = 1ULL << (GICD_TYPER_IDBITS + 1); |
402 | 402 | |
403 | - if ((icid >= s->ct.num_ids) | |
403 | + if ((icid >= s->ct.num_entries) | |
404 | 404 | || !dte_valid || (eventid >= num_eventids) || |
405 | 405 | (((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) && |
406 | 406 | (pIntid != INTID_SPURIOUS))) { |
@@ -485,7 +485,7 @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t offset) | ||
485 | 485 | |
486 | 486 | valid = (value & CMD_FIELD_VALID_MASK); |
487 | 487 | |
488 | - if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) { | |
488 | + if ((icid >= s->ct.num_entries) || (rdbase >= s->gicv3->num_cpu)) { | |
489 | 489 | qemu_log_mask(LOG_GUEST_ERROR, |
490 | 490 | "ITS MAPC: invalid collection table attributes " |
491 | 491 | "icid %d rdbase %" PRIu64 "\n", icid, rdbase); |
@@ -566,7 +566,7 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value, | ||
566 | 566 | |
567 | 567 | valid = (value & CMD_FIELD_VALID_MASK); |
568 | 568 | |
569 | - if ((devid >= s->dt.num_ids) || | |
569 | + if ((devid >= s->dt.num_entries) || | |
570 | 570 | (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) { |
571 | 571 | qemu_log_mask(LOG_GUEST_ERROR, |
572 | 572 | "ITS MAPD: invalid device table attributes " |
@@ -791,7 +791,7 @@ static void extract_table_params(GICv3ITSState *s) | ||
791 | 791 | L1TABLE_ENTRY_SIZE) * |
792 | 792 | (page_sz / td->entry_sz)); |
793 | 793 | } |
794 | - td->num_ids = 1ULL << idbits; | |
794 | + td->num_entries = MIN(td->num_entries, 1ULL << idbits); | |
795 | 795 | } |
796 | 796 | } |
797 | 797 |
@@ -47,7 +47,6 @@ typedef struct { | ||
47 | 47 | uint16_t entry_sz; |
48 | 48 | uint32_t page_sz; |
49 | 49 | uint32_t num_entries; |
50 | - uint32_t num_ids; | |
51 | 50 | uint64_t base_addr; |
52 | 51 | } TableDesc; |
53 | 52 |