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.



Reply via email to