Date: Sun, 21 Apr 2002 08:50:05 -0700 (PDT) From: Ian Dowse <iedowse@maths.tcd.ie> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/37304: Denial of service through bad NFS packet Message-ID: <200204211550.g3LFo5x87089@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/37304; it has been noted by GNATS. From: Ian Dowse <iedowse@maths.tcd.ie> To: Frank Denis <j@pureftpd.org> Cc: FreeBSD-gnats-submit@FreeBSD.org Subject: Re: kern/37304: Denial of service through bad NFS packet Date: Sun, 21 Apr 2002 16:47:07 +0100 In message <200204210818.g3L8IfZ32009@hosting3.clara.carpediem.fr>, Frank Denis writes: >To trigger the kernel crash, a client can mount a NFS export with the >following options : > >tcp,rdirplus,-r=32768,-w=32768 > >The server immediately crashes after some transfers. Was this a FreeBSD client? I wasn't able to reproduce this on a loopback NFS mount on FreeBSD -current or -stable. It would be useful to get a tcpdump of the request packet that actually triggers the crash (with options "-X -s 1600" to get the full data). However, I did find one related bug in the NFS code that might be responsible, but I could only trigger this with a crafted NFS request that contained an over-long readdirplus `count' field. A patch for this issue is below, so it would be interesting to see if it helps. NFS server op functions are never supposed to return a reply that is longer than the NFS protocol permits, regardless of what the client sends, so it is best to leave the `Bad nfs svc reply' error as a panic and fix the real bug. Ian Index: nfs_serv.c =================================================================== RCS file: /home/iedowse/CVS/src/sys/nfs/Attic/nfs_serv.c,v retrieving revision 1.93.2.4 diff -u -r1.93.2.4 nfs_serv.c --- nfs_serv.c 5 Feb 2002 19:09:30 -0000 1.93.2.4 +++ nfs_serv.c 21 Apr 2002 15:16:51 -0000 @@ -2993,6 +2993,8 @@ cnt = fxdr_unsigned(int, *tl); siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); xfer = NFS_SRVMAXDATA(nfsd); + if (cnt > xfer) + cnt = xfer; if (siz > xfer) siz = xfer; fullsiz = siz; @@ -3282,6 +3284,8 @@ off = toff; siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); xfer = NFS_SRVMAXDATA(nfsd); + if (cnt > xfer) + cnt = xfer; if (siz > xfer) siz = xfer; fullsiz = siz; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200204211550.g3LFo5x87089>