Bug 37304

Summary: Denial of service through bad NFS packet
Product: Base System Reporter: Frank DENIS <j>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me CC: j
Priority: Normal    
Version: 4.5-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Frank DENIS 2002-04-21 09:20:02 UTC
Special NFS packets can cause a kernel panic on a BSD NFS server.

It doesn't seem to be a FreeBSD specific issue, I've found that OpenBSD is
vulnerable as well.

Fix: While this may not be a correct fix, it may be better to ignore such packets
instead of going into a kernel panic (think about publicly accessible NFS
shares) .

Simple patch follows :
How-To-Repeat: 
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.

With UDP NFS + rdirplus, transfers hang but the server doesn't crash.
With TCP NFS + rdirplus, a kernel panic occurs because the chunk is too
large (it exceeds NFS_MAXPACKET) .
Comment 1 Frank DENIS 2002-04-21 16:41:30 UTC
  Please close that PR, false alert, sorry.
  
  FreeBSD is _not_ vulnerable to this, the real fix occured in nfs_serv.c a
while ago.

  Great news :)
Comment 2 iedowse 2002-04-21 16:47:07 UTC
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;
Comment 3 iedowse freebsd_committer freebsd_triage 2002-04-21 17:15:32 UTC
State Changed
From-To: open->closed

Submitter says this can be closed, as the readdirplus miscalculation 
bug was fixed some time ago. The patch I mentioned in the audit 
trail that fixes a related issue has been committed now too.