Commit a2d4e44b485222a8972ea9e555b148148c655bb9
1 parent
3bcb80f1
Fix PCI config space overflow, by Herbert Xu.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2238 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
16 additions
and
8 deletions
hw/pci.c
| ... | ... | @@ -242,16 +242,23 @@ uint32_t pci_default_read_config(PCIDevice *d, |
| 242 | 242 | uint32_t address, int len) |
| 243 | 243 | { |
| 244 | 244 | uint32_t val; |
| 245 | + | |
| 245 | 246 | switch(len) { |
| 246 | - case 1: | |
| 247 | - val = d->config[address]; | |
| 248 | - break; | |
| 249 | - case 2: | |
| 250 | - val = le16_to_cpu(*(uint16_t *)(d->config + address)); | |
| 251 | - break; | |
| 252 | 247 | default: |
| 253 | 248 | case 4: |
| 254 | - val = le32_to_cpu(*(uint32_t *)(d->config + address)); | |
| 249 | + if (address <= 0xfc) { | |
| 250 | + val = le32_to_cpu(*(uint32_t *)(d->config + address)); | |
| 251 | + break; | |
| 252 | + } | |
| 253 | + /* fall through */ | |
| 254 | + case 2: | |
| 255 | + if (address <= 0xfe) { | |
| 256 | + val = le16_to_cpu(*(uint16_t *)(d->config + address)); | |
| 257 | + break; | |
| 258 | + } | |
| 259 | + /* fall through */ | |
| 260 | + case 1: | |
| 261 | + val = d->config[address]; | |
| 255 | 262 | break; |
| 256 | 263 | } |
| 257 | 264 | return val; |
| ... | ... | @@ -341,7 +348,8 @@ void pci_default_write_config(PCIDevice *d, |
| 341 | 348 | if (can_write) { |
| 342 | 349 | d->config[addr] = val; |
| 343 | 350 | } |
| 344 | - addr++; | |
| 351 | + if (++addr > 0xff) | |
| 352 | + break; | |
| 345 | 353 | val >>= 8; |
| 346 | 354 | } |
| 347 | 355 | ... | ... |