mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-26 11:32:23 -06:00
hw/ssi/xilinx_spips: fix an out of bound access
The spips, qspips, and zynqmp-qspips share the same realize function (xilinx_spips_realize) and initialize their io memory region with different mmio_ops passed through the class. The size of the memory region is set to the largest area (0x200 bytes for zynqmp-qspips) thus it is possible to write out of s->regs[addr] in xilinx_spips_write for spips and qspips. This fixes that wrong behavior. Reviewed-by: Luc Michel <luc.michel@amd.com> Signed-off-by: Frederic Konrad <fkonrad@amd.com> Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com> Message-id: 20231124143505.1493184-2-fkonrad@amd.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
6e782ffd55
commit
90bb6d6764
2 changed files with 9 additions and 1 deletions
|
@ -973,6 +973,8 @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
|
||||||
|
|
||||||
DB_PRINT_L(0, "addr=" HWADDR_FMT_plx " = %x\n", addr, (unsigned)value);
|
DB_PRINT_L(0, "addr=" HWADDR_FMT_plx " = %x\n", addr, (unsigned)value);
|
||||||
addr >>= 2;
|
addr >>= 2;
|
||||||
|
assert(addr < XLNX_SPIPS_R_MAX);
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case R_CONFIG:
|
case R_CONFIG:
|
||||||
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
|
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
|
||||||
|
@ -1299,7 +1301,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
|
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
|
||||||
"spi", XLNX_ZYNQMP_SPIPS_R_MAX * 4);
|
"spi", xsc->reg_size);
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
|
|
||||||
s->irqline = -1;
|
s->irqline = -1;
|
||||||
|
@ -1435,6 +1437,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
|
||||||
|
|
||||||
dc->realize = xilinx_qspips_realize;
|
dc->realize = xilinx_qspips_realize;
|
||||||
xsc->reg_ops = &qspips_ops;
|
xsc->reg_ops = &qspips_ops;
|
||||||
|
xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A_Q;
|
xsc->rx_fifo_size = RXFF_A_Q;
|
||||||
xsc->tx_fifo_size = TXFF_A_Q;
|
xsc->tx_fifo_size = TXFF_A_Q;
|
||||||
}
|
}
|
||||||
|
@ -1450,6 +1453,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
|
||||||
dc->vmsd = &vmstate_xilinx_spips;
|
dc->vmsd = &vmstate_xilinx_spips;
|
||||||
|
|
||||||
xsc->reg_ops = &spips_ops;
|
xsc->reg_ops = &spips_ops;
|
||||||
|
xsc->reg_size = XLNX_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A;
|
xsc->rx_fifo_size = RXFF_A;
|
||||||
xsc->tx_fifo_size = TXFF_A;
|
xsc->tx_fifo_size = TXFF_A;
|
||||||
}
|
}
|
||||||
|
@ -1464,6 +1468,7 @@ static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
|
||||||
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
|
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
|
||||||
device_class_set_props(dc, xilinx_zynqmp_qspips_properties);
|
device_class_set_props(dc, xilinx_zynqmp_qspips_properties);
|
||||||
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
|
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
|
||||||
|
xsc->reg_size = XLNX_ZYNQMP_SPIPS_R_MAX * 4;
|
||||||
xsc->rx_fifo_size = RXFF_A_Q;
|
xsc->rx_fifo_size = RXFF_A_Q;
|
||||||
xsc->tx_fifo_size = TXFF_A_Q;
|
xsc->tx_fifo_size = TXFF_A_Q;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
|
|
||||||
typedef struct XilinxSPIPS XilinxSPIPS;
|
typedef struct XilinxSPIPS XilinxSPIPS;
|
||||||
|
|
||||||
|
/* For SPIPS, QSPIPS. */
|
||||||
#define XLNX_SPIPS_R_MAX (0x100 / 4)
|
#define XLNX_SPIPS_R_MAX (0x100 / 4)
|
||||||
|
/* For ZYNQMP_QSPIPS. */
|
||||||
#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
|
#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
|
||||||
|
|
||||||
/* Bite off 4k chunks at a time */
|
/* Bite off 4k chunks at a time */
|
||||||
|
@ -125,6 +127,7 @@ struct XilinxSPIPSClass {
|
||||||
SysBusDeviceClass parent_class;
|
SysBusDeviceClass parent_class;
|
||||||
|
|
||||||
const MemoryRegionOps *reg_ops;
|
const MemoryRegionOps *reg_ops;
|
||||||
|
uint64_t reg_size;
|
||||||
|
|
||||||
uint32_t rx_fifo_size;
|
uint32_t rx_fifo_size;
|
||||||
uint32_t tx_fifo_size;
|
uint32_t tx_fifo_size;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue