Here m_cat catenates two mbuf, when the first has no buffer, it allocates an M_EXT.
In m_inc, g_malloc called, then return m_cat, the next call to m_cat will trigger oob write.
Seems the m_len is too big.
In my debug, I see the m->m_len is 0x5b0, but datasize in m_inc is 0x40. Is this right?
Thanks,
Li Qiang
==17835==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61f000041dd0 at pc 0x7ffff6e9ad7b bp 0x7fffc6b215d0 sp 0x7fffc6b20d80
WRITE of size 28 at 0x61f000041dd0 thread T4
#0 0x7ffff6e9ad7a (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x5cd7a)
#1 0x55555663fa71 in m_cat slirp/mbuf.c:143
#2 0x555556632cdd in ip_reass slirp/ip_input.c:341
#3 0x555556631609 in ip_input slirp/ip_input.c:190
#4 0x55555663bd91 in slirp_input slirp/slirp.c:874
#5 0x555556600d6f in net_slirp_receive net/slirp.c:121
#6 0x5555565e8192 in nc_sendv_compat net/net.c:701
#7 0x5555565e8322 in qemu_deliver_packet_iov net/net.c:728
#8 0x5555565edda2 in qemu_net_queue_deliver_iov net/queue.c:179
#9 0x5555565edfaa in qemu_net_queue_send_iov net/queue.c:224
#10 0x5555565e8547 in qemu_sendv_packet_async net/net.c:764
#11 0x5555565e8574 in qemu_sendv_packet net/net.c:772
#12 0x55555636657c in net_tx_pkt_sendv hw/net/net_tx_pkt.c:546
#13 0x5555563668f3 in net_tx_pkt_do_sw_fragmentation hw/net/net_tx_pkt.c:588
#14 0x555556366c93 in net_tx_pkt_send hw/net/net_tx_pkt.c:625
#15 0x55555638586c in e1000e_tx_pkt_send hw/net/e1000e_core.c:665
#16 0x555556385fca in e1000e_process_tx_desc hw/net/e1000e_core.c:742
#17 0x555556387680 in e1000e_start_xmit hw/net/e1000e_core.c:933
#18 0x55555638f390 in e1000e_set_tdt hw/net/e1000e_core.c:2450
#19 0x5555563911cb in e1000e_core_write hw/net/e1000e_core.c:3255
#20 0x555556370524 in e1000e_mmio_write hw/net/e1000e.c:105
#21 0x555555d4ec07 in memory_region_write_accessor /home/liqiang02/qemu-devel/qemu/memory.c:527
#22 0x555555d4eee3 in access_with_adjusted_size /home/liqiang02/qemu-devel/qemu/memory.c:594
#23 0x555555d54d16 in memory_region_dispatch_write /home/liqiang02/qemu-devel/qemu/memory.c:1473
#24 0x555555c94b76 in flatview_write_continue /home/liqiang02/qemu-devel/qemu/exec.c:3255
#25 0x555555c94da1 in flatview_write /home/liqiang02/qemu-devel/qemu/exec.c:3294
#26 0x555555c95354 in address_space_write /home/liqiang02/qemu-devel/qemu/exec.c:3384
#27 0x555555c953a5 in address_space_rw /home/liqiang02/qemu-devel/qemu/exec.c:3395
#28 0x555555d92c4d in kvm_cpu_exec /home/liqiang02/qemu-devel/qemu/accel/kvm/kvm-all.c:1979
#29 0x555555d18936 in qemu_kvm_cpu_thread_fn /home/liqiang02/qemu-devel/qemu/cpus.c:1215
#30 0x5555569afef1 in qemu_thread_start util/qemu-thread-posix.c:504
#31 0x7fffdadbd493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
#32 0x7fffdaafface in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8ace)
AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x5cd7a)
Shadow bytes around the buggy address:
0x0c3e80000360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c3e800003b0: fa fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa
0x0c3e800003c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000400: 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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
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
Thread T4 created by T0 here:
#0 0x7ffff6e6ef59 in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f59)
#1 0x5555569b012f in qemu_thread_create util/qemu-thread-posix.c:534
#2 0x555555d1b7b9 in qemu_kvm_start_vcpu /home/liqiang02/qemu-devel/qemu/cpus.c:1935
#3 0x555555d1bf6c in qemu_init_vcpu /home/liqiang02/qemu-devel/qemu/cpus.c:2001
#4 0x555555f682de in x86_cpu_realizefn /home/liqiang02/qemu-devel/qemu/target/i386/cpu.c:4996
#5 0x55555621c00c in device_set_realized hw/core/qdev.c:826
#6 0x5555566f962f in property_set_bool qom/object.c:1984
#7 0x5555566f5bfc in object_property_set qom/object.c:1176
#8 0x5555566fbdce in object_property_set_qobject qom/qom-qobject.c:27
#9 0x5555566f5f19 in object_property_set_bool qom/object.c:1242
#10 0x555555edf7d7 in pc_new_cpu /home/liqiang02/qemu-devel/qemu/hw/i386/pc.c:1107
#11 0x555555edfc98 in pc_cpus_init /home/liqiang02/qemu-devel/qemu/hw/i386/pc.c:1155
#12 0x555555ef2451 in pc_q35_init /home/liqiang02/qemu-devel/qemu/hw/i386/pc_q35.c:130
#13 0x555555ef37f4 in pc_init_v3_0 /home/liqiang02/qemu-devel/qemu/hw/i386/pc_q35.c:320
#14 0x55555622ca6d in machine_run_board_init hw/core/machine.c:830
#15 0x555556099045 in main /home/liqiang02/qemu-devel/qemu/vl.c:4516
#16 0x7fffdaa372e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
Hi,
I have find the overflow point using ASAN.
void
m_cat(struct mbuf *m, struct mbuf *n)
{
/*
* If there's no room, realloc
*/
if (M_FREEROOM(m) < n->m_len)
m_inc(m, m->m_len + n->m_len);
memcpy( m->m_data+ m->m_len, n->m_data, n->m_len);
m->m_len += n->m_len;
m_free(n);
}
/* make m 'size' bytes large from m_data */
void
m_inc(struct mbuf *m, int size)
{
int datasize;
/* some compilers throw up on gotos. This one we can fake. */
if (m->m_size > size) {
return;
}
if (m->m_flags & M_EXT) {
memcpy( m->m_ext, m->m_dat, m->m_size);
datasize = m->m_data - m->m_ext;
m->m_ext = g_realloc(m->m_ext, size + datasize);
} else {
datasize = m->m_data - m->m_dat;
m->m_ext = g_malloc(size + datasize);
m->m_flags |= M_EXT;
}
m->m_data = m->m_ext + datasize;
m->m_size = size + datasize;
}
Here m_cat catenates two mbuf, when the first has no buffer, it allocates an M_EXT.
In m_inc, g_malloc called, then return m_cat, the next call to m_cat will trigger oob write.
Seems the m_len is too big.
In my debug, I see the m->m_len is 0x5b0, but datasize in m_inc is 0x40. Is this right?
Thanks,
Li Qiang
==17835==ERROR: AddressSanitizer: heap-buffer- overflow on address 0x61f000041dd0 at pc 0x7ffff6e9ad7b bp 0x7fffc6b215d0 sp 0x7fffc6b20d80 x86_64- linux-gnu/ libasan. so.3+0x5cd7a) input.c: 341 input.c: 190 packet_ iov net/net.c:728 queue_deliver_ iov net/queue.c:179 queue_send_ iov net/queue.c:224 packet_ async net/net.c:764 net_tx_ pkt.c:546 pkt_do_ sw_fragmentatio n hw/net/ net_tx_ pkt.c:588 net_tx_ pkt.c:625 e1000e_ core.c: 665 process_ tx_desc hw/net/ e1000e_ core.c: 742 e1000e_ core.c: 933 e1000e_ core.c: 2450 e1000e_ core.c: 3255 region_ write_accessor /home/liqiang02 /qemu-devel/ qemu/memory. c:527 with_adjusted_ size /home/liqiang02 /qemu-devel/ qemu/memory. c:594 region_ dispatch_ write /home/liqiang02 /qemu-devel/ qemu/memory. c:1473 write_continue /home/liqiang02 /qemu-devel/ qemu/exec. c:3255 /qemu-devel/ qemu/exec. c:3294 /qemu-devel/ qemu/exec. c:3384 /qemu-devel/ qemu/exec. c:3395 /qemu-devel/ qemu/accel/ kvm/kvm- all.c:1979 cpu_thread_ fn /home/liqiang02 /qemu-devel/ qemu/cpus. c:1215 thread- posix.c: 504 64-linux- gnu/libpthread. so.0+0x7493) 64-linux- gnu/libc. so.6+0xe8ace)
WRITE of size 28 at 0x61f000041dd0 thread T4
#0 0x7ffff6e9ad7a (/usr/lib/
#1 0x55555663fa71 in m_cat slirp/mbuf.c:143
#2 0x555556632cdd in ip_reass slirp/ip_
#3 0x555556631609 in ip_input slirp/ip_
#4 0x55555663bd91 in slirp_input slirp/slirp.c:874
#5 0x555556600d6f in net_slirp_receive net/slirp.c:121
#6 0x5555565e8192 in nc_sendv_compat net/net.c:701
#7 0x5555565e8322 in qemu_deliver_
#8 0x5555565edda2 in qemu_net_
#9 0x5555565edfaa in qemu_net_
#10 0x5555565e8547 in qemu_sendv_
#11 0x5555565e8574 in qemu_sendv_packet net/net.c:772
#12 0x55555636657c in net_tx_pkt_sendv hw/net/
#13 0x5555563668f3 in net_tx_
#14 0x555556366c93 in net_tx_pkt_send hw/net/
#15 0x55555638586c in e1000e_tx_pkt_send hw/net/
#16 0x555556385fca in e1000e_
#17 0x555556387680 in e1000e_start_xmit hw/net/
#18 0x55555638f390 in e1000e_set_tdt hw/net/
#19 0x5555563911cb in e1000e_core_write hw/net/
#20 0x555556370524 in e1000e_mmio_write hw/net/e1000e.c:105
#21 0x555555d4ec07 in memory_
#22 0x555555d4eee3 in access_
#23 0x555555d54d16 in memory_
#24 0x555555c94b76 in flatview_
#25 0x555555c94da1 in flatview_write /home/liqiang02
#26 0x555555c95354 in address_space_write /home/liqiang02
#27 0x555555c953a5 in address_space_rw /home/liqiang02
#28 0x555555d92c4d in kvm_cpu_exec /home/liqiang02
#29 0x555555d18936 in qemu_kvm_
#30 0x5555569afef1 in qemu_thread_start util/qemu-
#31 0x7fffdadbd493 in start_thread (/lib/x86_
#32 0x7fffdaafface in __clone (/lib/x86_
AddressSanitizer can not describe address in more detail (wild memory access suspected). overflow (/usr/lib/ x86_64- linux-gnu/ libasan. so.3+0x5cd7a) pthread_ create (/usr/lib/ x86_64- linux-gnu/ libasan. so.3+0x30f59) thread- posix.c: 534 /qemu-devel/ qemu/cpus. c:1935 /qemu-devel/ qemu/cpus. c:2001 /qemu-devel/ qemu/target/ i386/cpu. c:4996 property_ set_qobject qom/qom- qobject. c:27 property_ set_bool qom/object.c:1242 /qemu-devel/ qemu/hw/ i386/pc. c:1107 /qemu-devel/ qemu/hw/ i386/pc. c:1155 /qemu-devel/ qemu/hw/ i386/pc_ q35.c:130 /qemu-devel/ qemu/hw/ i386/pc_ q35.c:320 run_board_ init hw/core/ machine. c:830 /qemu-devel/ qemu/vl. c:4516 64-linux- gnu/libc. so.6+0x202e0)
SUMMARY: AddressSanitizer: heap-buffer-
Shadow bytes around the buggy address:
0x0c3e80000360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000390: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c3e800003b0: fa fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa
0x0c3e800003c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e800003f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3e80000400: 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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
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
Thread T4 created by T0 here:
#0 0x7ffff6e6ef59 in __interceptor_
#1 0x5555569b012f in qemu_thread_create util/qemu-
#2 0x555555d1b7b9 in qemu_kvm_start_vcpu /home/liqiang02
#3 0x555555d1bf6c in qemu_init_vcpu /home/liqiang02
#4 0x555555f682de in x86_cpu_realizefn /home/liqiang02
#5 0x55555621c00c in device_set_realized hw/core/qdev.c:826
#6 0x5555566f962f in property_set_bool qom/object.c:1984
#7 0x5555566f5bfc in object_property_set qom/object.c:1176
#8 0x5555566fbdce in object_
#9 0x5555566f5f19 in object_
#10 0x555555edf7d7 in pc_new_cpu /home/liqiang02
#11 0x555555edfc98 in pc_cpus_init /home/liqiang02
#12 0x555555ef2451 in pc_q35_init /home/liqiang02
#13 0x555555ef37f4 in pc_init_v3_0 /home/liqiang02
#14 0x55555622ca6d in machine_
#15 0x555556099045 in main /home/liqiang02
#16 0x7fffdaa372e0 in __libc_start_main (/lib/x86_