Skip to content

Commit

Permalink
hw/display/sm501: Validate local memory size index in sm501_system_co…
Browse files Browse the repository at this point in the history
…nfig_write

Ensure that the local_mem_size_index is within valid bounds and does not
exceed the allocated memory size before updating it in sm501_system_config_write
to prevent out-of-bounds read.

ASAN log:
==3067247==ERROR: AddressSanitizer: global-buffer-overflow on address 0x55c6586e4d3c at pc 0x55c655d4e0ac bp 0x7ffc9d5c6a10 sp 0x7ffc9d5c6a08
READ of size 4 at 0x55c6586e4d3c thread T0
    #0 0x55c655d4e0ab in sm501_2d_operation qemu/hw/display/sm501.c:729:21
    #1 0x55c655d4b8a1 in sm501_2d_engine_write qemu/hw/display/sm501.c:1551:13

Reproducer:
cat << EOF | qemu-system-x86_64  \
-display none -machine accel=qtest, -m 512M -machine q35 -nodefaults \
-device sm501 -qtest stdio
outl 0xcf8 0x80000814
outl 0xcfc 0xe4000000
outl 0xcf8 0x80000804
outw 0xcfc 0x02
writel 0xe4000010 0xe000
writel 0xe4100010 0x10000
writel 0xe4100008 0x10001
writel 0xe410000c 0x80000000
EOF

Signed-off-by: Zheyu Ma <[email protected]>
Message-Id: <[email protected]>
  • Loading branch information
ZheyuMa authored and Patchew Applier committed Jul 3, 2024
1 parent 1a2d52c commit 9de6741
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions hw/display/sm501.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,11 +1020,21 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
s->gpio_63_32_control = value & 0xFF80FFFF;
break;
case SM501_DRAM_CONTROL:
s->local_mem_size_index = (value >> 13) & 0x7;
/* TODO : check validity of size change */
{
int local_mem_size_index = (value >> 13) & 0x7;
if (local_mem_size_index < ARRAY_SIZE(sm501_mem_local_size) &&
sm501_mem_local_size[local_mem_size_index] <=
memory_region_size(&s->local_mem_region)) {
s->local_mem_size_index = local_mem_size_index;
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"sm501: Invalid local_mem_size_index value: %d or memory size too large\n",
local_mem_size_index);
}
s->dram_control &= 0x80000000;
s->dram_control |= value & 0x7FFFFFC3;
break;
}
case SM501_ARBTRTN_CONTROL:
s->arbitration_control = value & 0x37777777;
break;
Expand Down

0 comments on commit 9de6741

Please sign in to comment.