hw/misc/avr_power.c (AVR power mask register helper)
Version
commit: 2339d0a1
tag: v10.2.0-690-g2339d0a1cf
Device and source file
hw/misc/avr_power.c (AVR power mask register helper)
I pulled the address from the live memory map (`info mtree -f`): `0x00800064-0x00800064` (`avr-power`), so the access at `0x800064` is in-range.
Description of problem
The AVR power mask helper only implements byte-wide access at offset 0, but the read/write callbacks still use `assert(size == 1)` and `assert(offset == 0)` as the enforcement mechanism.
On `mega2560`, a `writew` landing at `0x800064` makes the callback run with a split offset, and the `offset == 0` assert fires immediately.
Key code:
```c
/* hw/misc/avr_power.c */
static void avr_mask_write(void *opaque, hwaddr offset,
uint64_t val64, unsigned size)
{
assert(size == 1);
assert(offset == 0);
...
}
static const MemoryRegionOps avr_mask_ops = {
.read = avr_mask_read,
.write = avr_mask_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.max_access_size = 1,
},
};
```
Root cause analysis
Input source: malformed but guest-reachable MMIO access width/offset. Missing validation: the callback relies on assertions instead of rejecting the access. Bug class: guest-triggerable assertion / host DoS. Impact: a bad-width access terminates the emulator.
Steps to Reproduce
Configuration
```bash
./configure --target-list=avr-softmmu --enable-debug --disable-strip
make -j"$(nproc)"
```
Reproducer (qtest)
Once I had the mapped addresses from the running machine, the following qtest script reproduced it:
```bash
cat <<'EOF' | ./qemu-system-avr -M mega2560 -nographic -display none -nodefaults -serial none -monitor none -qtest stdio -accel qtest
writew 0x800064 0x4142
EOF
```
Observed output (excerpt)
```text
[I 0.000000] OPENED
[R +0.002863] writew 0x800064 0x4142
qemu-system-avr: ../qemu-2339d0a1cfac6ecc667e6e062a593865c1541c35/hw/misc/avr_power.c:58: avr_mask_write: Assertion `offset == 0' failed.
[local] exit code: -6
```
Note
A plain byte write to the same register block is fine. The crash needs the split 16-bit access.
issue