Subject: Re: kern/21696: another panic from nfsrv_commit()
To: None <tech-net@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-net
Date: 05/27/2003 16:07:35
Hi,
I just submitted this.
I submitted it as a PR because I'll be AFK for a few days, and I hope
another developer will pick this up and commit before I'm back :)

Anyway, comments on the patch welcome.

On Tue, May 27, 2003 at 03:34:29PM +0200, Manuel Bouyer wrote:
> 	Some time ago I fixed a bug in NFS commit: when the size of the
> 	region to be commited was 0, a diagnostic check would be triggered:
> login: panic: kernel diagnostic assertion "startoff < endoff || endoff == 0" failed: file "/home/src/sys/arch/alpha/compile/DISCO/../../../../miscfs/genfs/genfs_vnops.c", line 1041
> 	
> 	I got this panic again, but this time because the offset is past the
> 	end of file. In the request that triggered this, len was 0.
> 
> 	The NFS specs don't say anything about out of file commit requests.
> 	I choose to start from the beggining of file.
> 
> >How-To-Repeat:
> 	Have a machine sending bogus NFS_COMMIT requests. I don't know what
> 	machine caused this; I have Linux, Solaris and NetBSD clients on the
> 	network. I have quotas enabled on the file server; this may be related
> 	to a file being trucated because of quotas, and not being noticed by
> 	the client. However, this file server has been running for months in
> 	this configuration.
> 	The new thing is that all solaris boxes have been upgraded to solaris9
> 	10 days ago ...
> >Fix:
> 	The following patch "normalise" such requests to start from the
> 	beggining of the file. Maybe there is a better way of handling it ...
> 	With this patch the panic stopped.
> 
> Index: nfs_serv.c
> ===================================================================
> RCS file: /cvsroot/src/sys/nfs/nfs_serv.c,v
> retrieving revision 1.74
> diff -u -r1.74 nfs_serv.c
> --- nfs_serv.c	2003/05/07 13:10:44	1.74
> +++ nfs_serv.c	2003/05/27 13:23:05
> @@ -3108,6 +3108,8 @@
>  		return (0);
>  	}
>  	for_ret = VOP_GETATTR(vp, &bfor, cred, procp);
> +	if (off > vp->v_size)
> +		off = 0;
>  	end = (cnt > 0) ? off + cnt : vp->v_size;
>  	if (end < off || end > vp->v_size)
>  		end = vp->v_size;
> 
--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     NetBSD: 24 ans d'experience feront toujours la difference
--