SIGSEGV in memcpy in v9fs_co_readdir_many
Host environment
- Operating system: ALT Linux
- OS/kernel version: 5.16
- Architecture: x86-64
- QEMU flavor: qemu-system-x86_64
- QEMU version: QEMU emulator version 6.2.0 (qemu-6.2.0-alt1)
- QEMU command line:
qemu-system-x86_64 -enable-kvm -m 40270M -smp cores=20 -nodefaults -nographic -no-reboot -fsdev local,id=root,path=/,security_model=none,multidevs=remap -device virtio-9p-pci,fsdev=root,mount_tag=/dev/root -device virtio-rng-pci -serial mon:stdio -kernel /boot/vmlinuz-5.16.2-un-def-alt1 -initrd /usr/src/tmp/initramfs-5.16.2-un-def-alt1.img -bios bios.bin -append console=ttyS0 mitigations=off nokaslr quiet panic=-1 SCRIPT=/usr/src/tmp/tmp.g5TpLWtJa1 UDEVD=y NOTTY no_timer_check
Emulated/Virtualized environment
- Operating system: ALT Linux
- OS/kernel version: 5.16.2
- Architecture: x86-64
Description of problem
When running btrfs tests in vm (using virtme
-like setup with 9pfs) occasionally qemu crashes with (coredumpctl info
output):
...
Message: Process 1764494 (qemu-system-x86) of user 502 dumped core.
Stack trace of thread 1764817:
#0 0x00005555559ebeed v9fs_co_readdir_many (/usr/bin/qemu-system-x86_64 + 0x497eed)
#1 0x00005555559ec2e9 v9fs_readdir (/usr/bin/qemu-system-x86_64 + 0x4982e9)
#2 0x0000555555eb7983 coroutine_trampoline (/usr/bin/qemu-system-x86_64 + 0x963983)
#3 0x00007ffff73e0be0 n/a (n/a + 0x0)
Additional information
coredumpctl debug:
Failed to read a valid object file image from memory.
Core was generated by `qemu-system-x86_64 -enable-kvm -m 40270M -smp cores=20 -nodefaults -nographic -'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00005555559ebeed in memcpy (__len=<optimized out>, __src=<optimized out>, __dest=<optimized out>, __dest=<optimized out>, __src=<optimized out>,
__len=<optimized out>) at /usr/include/bits/string_fortified.h:29
29 return __builtin___memcpy_chk (__dest, __src, __len,
[Current thread is 1 (LWP 1764817)]
(gdb) list ../hw/9pfs/codir.c:147
142 *entries = e = g_malloc0(sizeof(V9fsDirEnt));
143 } else {
144 e = e->next = g_malloc0(sizeof(V9fsDirEnt));
145 }
146 e->dent = g_malloc0(sizeof(struct dirent));
147 memcpy(e->dent, dent, sizeof(struct dirent));
148
149 /* perform a full stat() for directory entry if requested by caller */
150 if (dostat) {
151 err = s->ops->name_to_path(
(gdb) bt
#0 0x00005555559ebeed in memcpy (__len=<optimized out>, __src=<optimized out>, __dest=<optimized out>, __dest=<optimized out>, __src=<optimized out>,
__len=<optimized out>) at /usr/include/bits/string_fortified.h:29
#1 do_readdir_many (dostat=<optimized out>, maxsize=<optimized out>, offset=<optimized out>, entries=<optimized out>, fidp=<optimized out>,
pdu=0x555557353500) at ../hw/9pfs/codir.c:147
#2 v9fs_co_readdir_many (pdu=pdu@entry=0x555557353500, fidp=fidp@entry=0x555556cdd280, entries=entries@entry=0x7ff5bf7f7f58, offset=<optimized out>,
maxsize=<optimized out>, dostat=<optimized out>) at ../hw/9pfs/codir.c:226
#3 0x00005555559ec2e9 in v9fs_do_readdir (max_count=<optimized out>, offset=<optimized out>, fidp=0x555556cdd280, pdu=0x555557353500) at ../hw/9pfs/9p.c:2430
#4 v9fs_readdir (opaque=0x555557353500) at ../hw/9pfs/9p.c:2543
#5 0x0000555555eb7983 in coroutine_trampoline (i0=<optimized out>, i1=<optimized out>) at ../util/coroutine-ucontext.c:173
#6 0x00007ffff73e0be0 in ?? ()
#7 0x00007fffffffd480 in ?? ()
#8 0x0000000000000000 in ?? ()
(gdb) x/11i 0x00005555559ebeed - 27
0x5555559ebed2 <v9fs_co_readdir_many+530>: call 0x555555928480 <g_malloc0@plt>
0x5555559ebed7 <v9fs_co_readdir_many+535>: mov %rbp,%rsi
0x5555559ebeda <v9fs_co_readdir_many+538>: mov %rax,(%r12)
0x5555559ebede <v9fs_co_readdir_many+542>: mov 0x0(%rbp),%rdx
0x5555559ebee2 <v9fs_co_readdir_many+546>: lea 0x8(%rax),%rdi
0x5555559ebee6 <v9fs_co_readdir_many+550>: and $0xfffffffffffffff8,%rdi
0x5555559ebeea <v9fs_co_readdir_many+554>: mov %rdx,(%rax)
=> 0x5555559ebeed <v9fs_co_readdir_many+557>: mov 0x110(%rbp),%rdx
0x5555559ebef4 <v9fs_co_readdir_many+564>: mov %rdx,0x110(%rax)
0x5555559ebefb <v9fs_co_readdir_many+571>: sub %rdi,%rax
0x5555559ebefe <v9fs_co_readdir_many+574>: sub %rax,%rsi
(gdb) i r rdx rax rip
rdx 0x29287d 2697341
rax 0x7ff4bc12ccf0 140689104096496
rip 0x5555559ebeed 0x5555559ebeed <v9fs_co_readdir_many+557>
(gdb) x/11x 0x7ff4bc12ccf0
0x7ff4bc12ccf0: 0x0029287d 0x00000000 0x00000000 0x00000000
0x7ff4bc12cd00: 0x00000000 0x00000000 0x00000000 0x00000000
0x7ff4bc12cd10: 0x00000000 0x00000000 0x00000000
(gdb) frame 1
#1 do_readdir_many (dostat=<optimized out>, maxsize=<optimized out>, offset=<optimized out>, entries=<optimized out>, fidp=<optimized out>,
pdu=0x555557353500) at ../hw/9pfs/codir.c:147
147 memcpy(e->dent, dent, sizeof(struct dirent));
(gdb) p e
$3 = (struct V9fsDirEnt *) 0x7ff4bc12caa0
(gdb) p e->dent
$4 = (struct dirent *) 0x7ff4bc12ccf0
(gdb) p dent
$5 = (struct dirent *) 0x7ff4ec04cef0