• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Révision8b8bb0146b5383188e045ab75a53a0e179614cad (tree)
l'heure2022-01-28 23:29:47
AuteurPeter Maydell <peter.maydell@lina...>
CommiterPeter Maydell

Message de Log

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:

  • 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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220122182444.724087-13-peter.maydell@linaro.org

Change Summary

Modification

--- 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,
256256
257257 eventid = (value & EVENTID_MASK);
258258
259- if (devid >= s->dt.num_ids) {
259+ if (devid >= s->dt.num_entries) {
260260 qemu_log_mask(LOG_GUEST_ERROR,
261261 "%s: invalid command attributes: devid %d>=%d",
262- __func__, devid, s->dt.num_ids);
262+ __func__, devid, s->dt.num_entries);
263263 return CMD_CONTINUE;
264264 }
265265
@@ -300,7 +300,7 @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, uint64_t value,
300300 return CMD_CONTINUE;
301301 }
302302
303- if (icid >= s->ct.num_ids) {
303+ if (icid >= s->ct.num_entries) {
304304 qemu_log_mask(LOG_GUEST_ERROR,
305305 "%s: invalid ICID 0x%x in ITE (table corrupted?)\n",
306306 __func__, icid);
@@ -384,10 +384,10 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
384384
385385 icid = value & ICID_MASK;
386386
387- if (devid >= s->dt.num_ids) {
387+ if (devid >= s->dt.num_entries) {
388388 qemu_log_mask(LOG_GUEST_ERROR,
389389 "%s: invalid command attributes: devid %d>=%d",
390- __func__, devid, s->dt.num_ids);
390+ __func__, devid, s->dt.num_entries);
391391 return CMD_CONTINUE;
392392 }
393393
@@ -400,7 +400,7 @@ static ItsCmdResult process_mapti(GICv3ITSState *s, uint64_t value,
400400 num_eventids = 1ULL << (FIELD_EX64(dte, DTE, SIZE) + 1);
401401 num_intids = 1ULL << (GICD_TYPER_IDBITS + 1);
402402
403- if ((icid >= s->ct.num_ids)
403+ if ((icid >= s->ct.num_entries)
404404 || !dte_valid || (eventid >= num_eventids) ||
405405 (((pIntid < GICV3_LPI_INTID_START) || (pIntid >= num_intids)) &&
406406 (pIntid != INTID_SPURIOUS))) {
@@ -485,7 +485,7 @@ static ItsCmdResult process_mapc(GICv3ITSState *s, uint32_t offset)
485485
486486 valid = (value & CMD_FIELD_VALID_MASK);
487487
488- if ((icid >= s->ct.num_ids) || (rdbase >= s->gicv3->num_cpu)) {
488+ if ((icid >= s->ct.num_entries) || (rdbase >= s->gicv3->num_cpu)) {
489489 qemu_log_mask(LOG_GUEST_ERROR,
490490 "ITS MAPC: invalid collection table attributes "
491491 "icid %d rdbase %" PRIu64 "\n", icid, rdbase);
@@ -566,7 +566,7 @@ static ItsCmdResult process_mapd(GICv3ITSState *s, uint64_t value,
566566
567567 valid = (value & CMD_FIELD_VALID_MASK);
568568
569- if ((devid >= s->dt.num_ids) ||
569+ if ((devid >= s->dt.num_entries) ||
570570 (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
571571 qemu_log_mask(LOG_GUEST_ERROR,
572572 "ITS MAPD: invalid device table attributes "
@@ -791,7 +791,7 @@ static void extract_table_params(GICv3ITSState *s)
791791 L1TABLE_ENTRY_SIZE) *
792792 (page_sz / td->entry_sz));
793793 }
794- td->num_ids = 1ULL << idbits;
794+ td->num_entries = MIN(td->num_entries, 1ULL << idbits);
795795 }
796796 }
797797
--- a/include/hw/intc/arm_gicv3_its_common.h
+++ b/include/hw/intc/arm_gicv3_its_common.h
@@ -47,7 +47,6 @@ typedef struct {
4747 uint16_t entry_sz;
4848 uint32_t page_sz;
4949 uint32_t num_entries;
50- uint32_t num_ids;
5150 uint64_t base_addr;
5251 } TableDesc;
5352