mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
[QEMU] pci: Unaligned config read/write overflow
The default config read/write handlers allows a 4-byte read/write at address 255. This can clobber the field after the config area. This happens to be the PCIBus pointer in the PCIDevice structure. This patch stops this from reducing the read/write to the (largest multiple of 2) number of bytes within the config area. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
1 parent
6c06dcdb86
commit
2b87d5adbb
1 file changed
+16
-8
+16
-8
@@ -221,16 +221,23 @@ uint32_t pci_default_read_config(PCIDevice *d,
|
||||
uint32_t address, int len)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
switch(len) {
|
||||
case 1:
|
||||
val = d->config[address];
|
||||
break;
|
||||
case 2:
|
||||
val = le16_to_cpu(*(uint16_t *)(d->config + address));
|
||||
break;
|
||||
default:
|
||||
case 4:
|
||||
val = le32_to_cpu(*(uint32_t *)(d->config + address));
|
||||
if (address <= 0xfc) {
|
||||
val = le32_to_cpu(*(uint32_t *)(d->config + address));
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case 2:
|
||||
if (address <= 0xfe) {
|
||||
val = le16_to_cpu(*(uint16_t *)(d->config + address));
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case 1:
|
||||
val = d->config[address];
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
@@ -333,7 +340,8 @@ void pci_default_write_config(PCIDevice *d,
|
||||
|
||||
d->config[addr] = val;
|
||||
}
|
||||
addr++;
|
||||
if (++addr > 0xff)
|
||||
break;
|
||||
val >>= 8;
|
||||
}
|
||||
|
||||
|
||||