On 2025-04-29 08:09, Claudio Jeker wrote:
On Mon, Apr 28, 2025 at 01:53:49PM +0200, Claes M Nyberg wrote:
Performing a READDIRPLUS on a symbolic link to a file result in remote
kernel crash.
Reproduce: https://www.youtube.com/watch?v=AhO21aBrWBA
Can you please provide the information in an email and not as a video?
I'm not goinf to look at any video to try to see what is going on.
Of course, sorry.
Here comes a more detailed report including output from console and
remote gdb session.
-=[ Trigger the bug (using https://github.com/claesmnyberg/nfscli)
$ ./516-nfscli 192.168.122.76
NFS v3 CLI v1.5, By Claes M Nyberg <[email protected]>
nfsh 192.168.122.76> getport mount
[2025-04-29 14:08:03] 192.168.122.76: Resolved mount port to 743
nfsh 192.168.122.76> exports
/exports/data ___________________________________ <everyone>
nfsh 192.168.122.76> mnt /exports/data
[2025-04-29 14:08:17] 192.168.122.76: Received 28 bytes fh for
'/exports/data':
0000000014c7ec540c00000045950100d87f95580000000000000000
nfsh 192.168.122.76> ls
0000000014c7ec540c00000045950100d87f95580000000000000000
drwxrwxrwt 2 0 0 512 2025-04-29 13:31:48 .
_____________________________
FH:0000000014c7ec540c00000045950100d87f95580000000000000000
drwxr-xr-x 3 0 0 512 2025-04-29 13:22:34 ..
____________________________
FH:0000000014c7ec540c0000004495010020c489f60000000000000000
-rw-r--r-- 1 4294967294 0 0 2025-04-29 13:52:47 file
__________________________
FH:0000000014c7ec540c000000469501006635dfe40000000000000000
lrwxr-xr-x 1 4294967294 0 4 2025-04-29 13:52:56 link
__________________________
FH:0000000014c7ec540c00000047950100e5b5dabc0000000000000000
[2025-04-29 14:08:22] 192.168.122.76: Read 4 entries, 740 bytes, in 1
calls
nfsh 192.168.122.76> readdirplus
0000000014c7ec540c00000047950100e5b5dabc0000000000000000
-=[ Console (set tty com0, QEMU serial to localhost:4321)
ddb> show panic
*cpu0: ffs_read: short symlink
ddb> trace
db_enter() at db_enter+0x14
panic(ffffffff8253902b) at panic+0xcf
ffs_read(ffff800003b9d1e8) at ffs_read+0x2aa
VOP_READ(fffffd80046ef630,ffff800003b9d368,0,fffffd800587cdf8) at
VOP_READ+0x45
ufs_readdir(ffff800003b9d418) at ufs_readdir+0x117
VOP_READDIR(fffffd80046ef630,ffff800003b9d688,fffffd800587cdf8,ffff800003b9d750)
at VOP_READDIR+0x46
nfsrv_readdirplus(fffffd800587cdc0,ffff80000006f200,ffff800003ae5208,ffff800003b9d7e8)
at nfsrv_readdirplus+0x491
nfssvc_nfsd(ffff800000056440) at nfssvc_nfsd+0x2ed
sys_nfssvc(ffff800003ae5208,ffff800003b9d9f0,ffff800003b9d970) at
sys_nfssvc+0x1b7
syscall(ffff800003b9d9f0) at syscall+0x438
Xsyscall() at Xsyscall+0x128
end of kernel
end trace frame: 0x7d39e8069730, count: -11
-=[ Using GDB (option KGDB kernel)
$ gdb ./bsd.GENERIC.KGDB.gdb
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./bsd.GENERIC.KGDB.gdb...
(gdb) target remote :1234
Remote debugging using :1234
[...]
(gdb) break nfsrv_readdirplus
Breakpoint 1 at 0xffffffff811c34f5: file /usr/src/sys/nfs/nfs_serv.c,
line 2607.
(gdb) c
Continuing.
Breakpoint 1, nfsrv_readdirplus (nfsd=0xfffffd800587cdc0,
slp=0xffff80000006f200, procp=0xffff800003ae5208,
mrq=0xffff800003b9d7e8)
at /usr/src/sys/nfs/nfs_serv.c:2607
2607 struct mbuf *nam = nfsd->nd_nam;
(gdb) break ffs_read
Breakpoint 2 at 0xffffffff81626314: file
/usr/src/sys/ufs/ffs/ffs_vnops.c, line 198.
(gdb) c
Continuing.
Breakpoint 2, ffs_read (v=0xffff800003b9d1e8) at
/usr/src/sys/ufs/ffs/ffs_vnops.c:198
198 uio = ap->a_uio;
(gdb) bt
#0 ffs_read (v=0xffff800003b9d1e8) at
/usr/src/sys/ufs/ffs/ffs_vnops.c:198
#1 0xffffffff81c85be5 in VOP_READ (vp=<optimized out>,
uio=0xffff800003b9d368, ioflag=0, cred=0xfffffd800587cdf8) at
/usr/src/sys/kern/vfs_vops.c:227
#2 0xffffffff811166a7 in ufs_readdir (v=0xffff800003b9d418) at
/usr/src/sys/ufs/ufs/ufs_vnops.c:1366
#3 0xffffffff81c86256 in VOP_READDIR (vp=<optimized out>,
uio=0xffff800003b9d368, cred=0x0, eofflag=0xfffffd800587cdf8) at
/usr/src/sys/kern/vfs_vops.c:450
#4 0xffffffff811c3951 in nfsrv_readdirplus (nfsd=0x8da09bdff2dce475,
slp=0xffff80000006f200, procp=0xffff800003ae5208,
mrq=0xffff800003b9d7e8) at /usr/src/sys/nfs/nfs_serv.c:2692
#5 0xffffffff8205287d in nfssvc_nfsd (nfsd=0xffff800003ae5208) at
/usr/src/sys/nfs/nfs_syscalls.c:407
#6 0xffffffff820521d7 in sys_nfssvc (p=0x9d01c82cfd0e3078,
v=0xffff800003ae5208, retval=<optimized out>) at
/usr/src/sys/nfs/nfs_syscalls.c:197
#7 0xffffffff82249cb8 in mi_syscall (p=0xffff800003b9d970,
code=-140737425843728, argp=0xa8e83f7f33572a9c, retval=<optimized out>,
callp=<optimized out>) at /usr/src/sys/sys/syscall_mi.h:176
#8 syscall (frame=0xa8e83f7f33572a9c) at
/usr/src/sys/arch/amd64/amd64/trap.c:577
#9 0xffffffff82512134 in Xsyscall ()
#10 0x0000000000000004 in ?? ()
#11 0x00000f1cec8231e0 in ?? ()
#12 0x00007d39e8069658 in ?? ()
#13 0x00000f1fa828d9b0 in ?? ()
#14 0x0000000000000000 in ?? ()
(gdb) list
193 int error;
194
195 vp = ap->a_vp;
196 ip = VTOI(vp);
197 mode = DIP(ip, mode);
198 uio = ap->a_uio;
199
200 #ifdef DIAGNOSTIC
201 if (uio->uio_rw != UIO_READ)
202 panic("ffs_read: mode");
(gdb) next
201 if (uio->uio_rw != UIO_READ)
(gdb)
204 if (vp->v_type == VLNK) {
(gdb)
205 if (DIP(ip, size) < ip->i_ump->um_maxsymlinklen)
(gdb)
206 panic("ffs_read: short symlink");
(gdb) bt
#0 ffs_read (v=0xffff800003b9d1e8) at
/usr/src/sys/ufs/ffs/ffs_vnops.c:206
#1 0xffffffff81c85be5 in VOP_READ (vp=<optimized out>, uio=0x5,
ioflag=1, cred=0xfffffd800488a000) at /usr/src/sys/kern/vfs_vops.c:227
#2 0xffffffff811166a7 in ufs_readdir (v=0xffff800003b9d418) at
/usr/src/sys/ufs/ufs/ufs_vnops.c:1366
#3 0xffffffff81c86256 in VOP_READDIR (vp=<optimized out>, uio=0x5,
cred=0x1, eofflag=0xfffffd800488a000) at
/usr/src/sys/kern/vfs_vops.c:450
#4 0xffffffff811c3951 in nfsrv_readdirplus (nfsd=0x8da09bdff2dce475,
slp=0xffff80000006f200, procp=0xffff800003ae5208,
mrq=0xffff800003b9d7e8) at /usr/src/sys/nfs/nfs_serv.c:2692
#5 0xffffffff8205287d in nfssvc_nfsd (nfsd=0xffff800003ae5208) at
/usr/src/sys/nfs/nfs_syscalls.c:407
#6 0xffffffff820521d7 in sys_nfssvc (p=0x9d01c82cfd0e3078,
v=0xffff800003ae5208, retval=<optimized out>) at
/usr/src/sys/nfs/nfs_syscalls.c:197
#7 0xffffffff82249cb8 in mi_syscall (p=0xffff800003b9d970,
code=-140737425843728, argp=0xa8e83f7f33572a9c, retval=<optimized out>,
callp=<optimized out>) at /usr/src/sys/sys/syscall_mi.h:176
#8 syscall (frame=0xa8e83f7f33572a9c) at
/usr/src/sys/arch/amd64/amd64/trap.c:577
#9 0xffffffff82512134 in Xsyscall ()
#10 0x0000000000000004 in ?? ()
#11 0x00000f1cec8231e0 in ?? ()
#12 0x00007d39e8069658 in ?? ()
#13 0x00000f1fa828d9b0 in ?? ()
#14 0x0000000000000000 in ?? ()
(gdb) list /usr/src/sys/ufs/ufs/ufs_vnops.c:1366
1361 auio.uio_segflg = UIO_SYSSPACE;
1362 aiov.iov_len = readcnt;
1363 bufsize = readcnt;
1364 diskbuf = malloc(bufsize, M_TEMP, M_WAITOK);
1365 aiov.iov_base = diskbuf;
1366 error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
1367 readcnt -= auio.uio_resid;
1368 dp = (struct direct *)diskbuf;
1369 edp = &diskbuf[readcnt];
1370
(gdb) list /usr/src/sys/kern/vfs_vops.c:450
445 ASSERT_VP_ISLOCKED(vp);
446
447 if (vp->v_op->vop_readdir == NULL)
448 return (EOPNOTSUPP);
449
450 return ((vp->v_op->vop_readdir)(&a));
451 }
452
453 int
454 VOP_READLINK(struct vnode *vp, struct uio *uio, struct ucred *cred)
(gdb) list /usr/src/sys/nfs/nfs_serv.c:2692
2687 io.uio_rw = UIO_READ;
2688 io.uio_procp = NULL;
2689 eofflag = 0;
269
2691 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2692 error = VOP_READDIR(vp, &io, cred, &eofflag);
2693
2694 off = (u_quad_t)io.uio_offset;
2695 getret = VOP_GETATTR(vp, &at, cred, procp);
2696
(gdb) c
Continuing.