Skip to content

Commit c9fe563

Browse files
ZheyuMaPatchew Applier
authored and
Patchew Applier
committed
hw/display/sm501: Fix potential overflow in memory size index
This patch addresses potential issues in the sm501 memory size configuration. Specifically, it adds validation checks to ensure that the local_mem_size_index value written to the SM501_DRAM_CONTROL register is within valid bounds. It ensures that the selected memory size does not exceed the available VRAM size. Additionally, the read operation for the SM501_DRAM_CONTROL register is modified to return the raw dram_control value without combining it with the local_mem_size_index. 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]>
1 parent e2f346a commit c9fe563

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

hw/display/sm501.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
961961
ret = 0x050100A0;
962962
break;
963963
case SM501_DRAM_CONTROL:
964-
ret = (s->dram_control & 0x07F107C0) | s->local_mem_size_index << 13;
964+
ret = s->dram_control;
965965
break;
966966
case SM501_ARBTRTN_CONTROL:
967967
ret = s->arbitration_control;
@@ -1020,11 +1020,24 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
10201020
s->gpio_63_32_control = value & 0xFF80FFFF;
10211021
break;
10221022
case SM501_DRAM_CONTROL:
1023-
s->local_mem_size_index = (value >> 13) & 0x7;
1024-
/* TODO : check validity of size change */
1023+
{
1024+
int local_mem_size_index = (value >> 13) & 0x7;
1025+
if (local_mem_size_index >= ARRAY_SIZE(sm501_mem_local_size)) {
1026+
qemu_log_mask(LOG_GUEST_ERROR,
1027+
"sm501: Invalid local_mem_size_index value: %d\n",
1028+
local_mem_size_index);
1029+
} else if (sm501_mem_local_size[local_mem_size_index] >
1030+
memory_region_size(&s->local_mem_region)) {
1031+
qemu_log_mask(LOG_GUEST_ERROR,
1032+
"sm501: Memory size %d cannot be more than vram_size\n",
1033+
sm501_mem_local_size[local_mem_size_index]);
1034+
} else {
1035+
s->local_mem_size_index = local_mem_size_index;
1036+
}
10251037
s->dram_control &= 0x80000000;
10261038
s->dram_control |= value & 0x7FFFFFC3;
10271039
break;
1040+
}
10281041
case SM501_ARBTRTN_CONTROL:
10291042
s->arbitration_control = value & 0x37777777;
10301043
break;

0 commit comments

Comments
 (0)