Stack-overflow in _eth_get_rss_ex_dst_addr

Bug #1879531 reported by Alexander Bulekov
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Undecided
Unassigned

Bug Description

Hello,
While fuzzing, I found a 1-byte stack-overflow (read) through the
e1000e.

==10318==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffdb76c16c2 at pc 0x55594f1a69e1 bp 0x7ffdb76c15a0 sp 0x7ffdb76c1598
READ of size 1 at 0x7ffdb76c16c2 thread T0
    #0 0x55594f1a69e0 in _eth_get_rss_ex_dst_addr /home/alxndr/Development/qemu/net/eth.c:410:17
    #1 0x55594f1a39da in eth_parse_ipv6_hdr /home/alxndr/Development/qemu/net/eth.c:532:17
    #2 0x55594ebc34f2 in net_tx_pkt_parse_headers /home/alxndr/Development/qemu/hw/net/net_tx_pkt.c:228:14
    #3 0x55594ebc2149 in net_tx_pkt_parse /home/alxndr/Development/qemu/hw/net/net_tx_pkt.c:273:9
    #4 0x55594ec1ba76 in e1000e_process_tx_desc /home/alxndr/Development/qemu/hw/net/e1000e_core.c:737:29
    #5 0x55594ec1aea4 in e1000e_start_xmit /home/alxndr/Development/qemu/hw/net/e1000e_core.c:934:9
    #6 0x55594ec0e70e in e1000e_set_tdt /home/alxndr/Development/qemu/hw/net/e1000e_core.c:2451:9
    #7 0x55594ebec435 in e1000e_core_write /home/alxndr/Development/qemu/hw/net/e1000e_core.c:3261:9
    #8 0x55594ebdf11b in e1000e_mmio_write /home/alxndr/Development/qemu/hw/net/e1000e.c:109:5
    #9 0x55594dfd98b1 in memory_region_write_accessor /home/alxndr/Development/qemu/memory.c:483:5
    #10 0x55594dfd9211 in access_with_adjusted_size /home/alxndr/Development/qemu/memory.c:544:18
    #11 0x55594dfd7c30 in memory_region_dispatch_write /home/alxndr/Development/qemu/memory.c:1476:16
    #12 0x55594dde24b8 in flatview_write_continue /home/alxndr/Development/qemu/exec.c:3137:23
    #13 0x55594ddd12dc in flatview_write /home/alxndr/Development/qemu/exec.c:3177:14
    #14 0x55594ddd0dec in address_space_write /home/alxndr/Development/qemu/exec.c:3268:18
    #15 0x55594dfcdbdc in qtest_process_command /home/alxndr/Development/qemu/qtest.c:567:9
    #16 0x55594dfc3700 in qtest_process_inbuf /home/alxndr/Development/qemu/qtest.c:710:9
    #17 0x55594dfc2cc8 in qtest_read /home/alxndr/Development/qemu/qtest.c:722:5
    #18 0x55594f74b259 in qemu_chr_be_write_impl /home/alxndr/Development/qemu/chardev/char.c:183:9
    #19 0x55594f74b3ee in qemu_chr_be_write /home/alxndr/Development/qemu/chardev/char.c:195:9
    #20 0x55594f7556fc in fd_chr_read /home/alxndr/Development/qemu/chardev/char-fd.c:68:9
    #21 0x55594f7ea488 in qio_channel_fd_source_dispatch /home/alxndr/Development/qemu/io/channel-watch.c:84:12
    #22 0x7f43f6c1d897 in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x4e897)
    #23 0x55594f9dea5d in glib_pollfds_poll /home/alxndr/Development/qemu/util/main-loop.c:219:9
    #24 0x55594f9dd1d7 in os_host_main_loop_wait /home/alxndr/Development/qemu/util/main-loop.c:242:5
    #25 0x55594f9dcd6e in main_loop_wait /home/alxndr/Development/qemu/util/main-loop.c:518:11
    #26 0x55594e44cd01 in qemu_main_loop /home/alxndr/Development/qemu/softmmu/vl.c:1664:9
    #27 0x55594f803c21 in main /home/alxndr/Development/qemu/softmmu/main.c:49:5
    #28 0x7f43f57b4e0a in __libc_start_main /build/glibc-GwnBeO/glibc-2.30/csu/../csu/libc-start.c:308:16
    #29 0x55594dd03889 in _start (/home/alxndr/Development/qemu/build/i386-softmmu/qemu-system-i386+0xdbd889)

Address 0x7ffdb76c16c2 is located in stack of thread T0 at offset 34 in frame
    #0 0x55594f1a303f in eth_parse_ipv6_hdr /home/alxndr/Development/qemu/net/eth.c:486

  This frame has 1 object(s):
    [32, 34) 'ext_hdr' (line 487) <== Memory access at offset 34 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/alxndr/Development/qemu/net/eth.c:410:17 in _eth_get_rss_ex_dst_addr
Shadow bytes around the buggy address:
  0x100036ed0280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed0290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed02a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed02b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed02c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100036ed02d0: 00 00 00 00 f1 f1 f1 f1[02]f3 f3 f3 00 00 00 00
  0x100036ed02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed02f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed0300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed0310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100036ed0320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
  Shadow gap: cc
==10318==ABORTING

I can reproduce it in qemu 5.0 built with address sanitizer using:

cat << EOF | ./qemu-system-i386 -M pc-q35-5.0 -accel qtest -qtest stdio -monitor none -serial none -nographic
outl 0xcf8 0x80001010
outl 0xcfc 0xe1020000
outl 0xcf8 0x80001014
outl 0xcf8 0x80001004
outw 0xcfc 0x7
outl 0xcf8 0x800010a2
write 0x25 0x2b 0x86dd1900ff5df747002bfc90dd1900ff5df747002bfc9add1900ff5df747002bfca4dd1900ff5df747002b
write 0xe1020030 0x409 0x190002e100000000350908077cdd190002e100000000350912077cdd190002e10000000035091c077cdd190002e100000000350926077cdd190002e100000000350930077cdd190002e10000000035093a077cdd190002e100000000350944077cdd190002e10000000035094e077cdd190002e100000000350958077cdd190002e100000000350962077cdd190002e10000000035096c077cdd190002e100000000350976077cdd190002e100000000350980077cdd190002e10000000035098a077cdd190002e100000000350994077cdd190002e10000000035099e077cdd190002e1000000003509a8077cdd190002e1000000003509b2077cdd190002e1000000003509bc077cdd190002e1000000003509c6077cdd190002e1000000003509d0077cdd190002e1000000003509da077cdd190002e1000000003509e4077cdd190002e1000000003509ee077cdd190002e1000000003509f8077cdd190002e100000000350902077cdd190002e10000000035090c077cdd190002e100000000350916077cdd190002e100000000350920077cdd190002e10000000035092a077cdd190002e100000000350934077cdd190002e10000000035093e077cdd190002e100000000350948077cdd190002e100000000350952077cdd190002e10000000035095c077cdd190002e100000000350966077cdd190002e100000000350970077cdd190002e10000000035097a077cdd190002e100000000350984077cdd190002e10000000035098e077cdd190002e100000000350998077cdd190002e1000000003509a2077cdd190002e1000000003509ac077cdd190002e1000000003509b6077cdd190002e1000000003509c0077cdd190002e1000000003509ca077cdd190002e1000000003509d4077cdd190002e1000000003509de077cdd190002e1000000003509e8077cdd190002e1000000003509f2077cdd190002e1000000003509fc077cdd190002e100000000350906077cdd190002e100000000350910077cdd190002e10000000035091a077cdd190002e100000000350924077cdd190002e10000000035092e077cdd190002e100000000350938077cdd190002e100000000350942077cdd190002e10000000035094c077cdd190002e100000000350956077cdd190002e100000000350960077cdd190002e10000000035096a077cdd190002e100000000350974077cdd190002e10000000035097e077cdd190002e100000000350988077cdd190002e100000000350992077cdd190002e10000000035099c077cdd190002e1000000003509a6077cdd190002e1000000003509b0077cdd190002e1000000003509ba077cdd190002e1000000003509c4077cdd190002e1000000003509ce077cdd190002e1000000003509d8077cdd190002e1000000003509e2
EOF

Also attaching these commands. They can be executed with
./qemu-system-i386 -M pc-q35-5.0 -accel qtest -qtest stdio -monitor none -serial none -nographic < attachment

Let me know if I can provide any further info.
-Alex

Revision history for this message
Alexander Bulekov (a1xndr) wrote :
Revision history for this message
Alexander Bulekov (a1xndr) wrote :

From Prasad:

 struct ip6_ext_hdr {
 uint8_t ip6r_nxt; /* next header */
 uint8_t ip6r_len; /* length in units of 8 octets */
};
struct ip6_ext_hdr_routing {
 uint8_t nxt;
 uint8_t len;
 uint8_t rtype;
 uint8_t segleft;
 uint8_t rsvd[4];
};
 Yes, it looks like because 'struct ip6_ext_hdr' type stack variable's address is assigned to
'struct ip6_ext_hdr_routine' type pointer. And such a pointer is accessing '->rtype' variable,
which is not present in 'struct ip6_ext_hdr'.

 diff --git a/include/net/eth.h b/include/net/eth.h
index 7f45c678e7..38f2d52bcd 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -129,6 +129,7 @@ typedef struct ip6_pseudo_header {
 struct ip6_ext_hdr {
 uint8_t ip6r_nxt; /* next header */
 uint8_t ip6r_len; /* length in units of 8 octets */
+ uint32_t padding;
 };
 Above patch should help. It is okay to send this report upstream. Thank you.
--
Prasad J Pandit / Red Hat Product Security Team

Revision history for this message
Alexander Bulekov (a1xndr) wrote :

Minimized Reproducer:
cat << EOF | ./qemu-system-i386 -M pc-q35-5.0 \
-accel qtest -monitor none \
-serial none -nographic -qtest stdio
outl 0xcf8 0x80001010
outl 0xcfc 0xe1020000
outl 0xcf8 0x80001004
outw 0xcfc 0x7
write 0x25 0x1 0x86
write 0x26 0x1 0xdd
write 0x4f 0x1 0x2b
write 0xe1020030 0x4 0x190002e1
write 0xe102003a 0x2 0x0807
write 0xe1020048 0x4 0x12077cdd
write 0xe1020400 0x4 0xba077cdd
write 0xe1020420 0x4 0x190002e1
write 0xe1020428 0x4 0x3509d807
write 0xe1020438 0x1 0xe2
EOF

Revision history for this message
Philippe Mathieu-Daudé (philmd) wrote :

Proposed fix:
https://<email address hidden>/msg773408.html

Peter Maydell (pmaydell)
tags: added: fuzzer
Revision history for this message
Paolo Bonzini (bonzini) wrote :

Updated version: https://<email address hidden>/msg789998.html

Revision history for this message
Thomas Huth (th-huth) wrote :
Changed in qemu:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Bug attachments