From kato@migmatite.eps.nagoya-u.ac.jp  Tue Feb  3 04:51:18 1998
Received: from marble.eps.nagoya-u.ac.jp (marble.eps.nagoya-u.ac.jp [133.6.124.146])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id EAA18910
          for <FreeBSD-gnats-submit@freebsd.org>; Tue, 3 Feb 1998 04:51:17 -0800 (PST)
          (envelope-from kato@migmatite.eps.nagoya-u.ac.jp)
Received: (from kato@localhost) by marble.eps.nagoya-u.ac.jp (8.8.8/3.4W4) id VAA00361; Tue, 3 Feb 1998 21:31:30 +0900 (JST)
Message-Id: <199802031231.VAA00361@marble.eps.nagoya-u.ac.jp>
Date: Tue, 3 Feb 1998 21:31:30 +0900 (JST)
From: kato@migmatite.eps.nagoya-u.ac.jp
Reply-To: kato@migmatite.eps.nagoya-u.ac.jp
To: FreeBSD-gnats-submit@freebsd.org
Subject: pagefault in umap_bypass() and umap_mapids()
X-Send-Pr-Version: 3.2

>Number:         5632
>Category:       kern
>Synopsis:       pagefault in umap_bypass() when cred == NOCRED.
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb  3 05:00:01 PST 1998
>Closed-Date:    Sat Feb 7 01:03:11 PST 1998
>Last-Modified:  Sat Feb  7 01:03:44 PST 1998
>Originator:     KATO Takenori
>Release:        FreeBSD 3.0-CURRENT i386
>Organization:
Dept. Earth Plarnet. Sci, Nagoya Univ.
>Environment:
current & RELENG_2_2

>Description:

Because umap_bypass() and umap_mapids() do not check whether the
pointer to credential is NOCRED or not, pagefault occurs in those
functions.  For exapmle, vclean calls vinbalbuf at cred = NOCRED and
vinvalbuf calls VOP_FSYNC().  In this case, pointer to credential is
NOCRED, but umap_bypass() always calls crdup(), which assumes the
pointer to credential is not NOCRED.  The umap_mapids also assumes
that the pointer to credential is not NOCRED.

>How-To-Repeat:
One example is unmounting umapfs.

>Fix:
Check the pointer to credential as follows:

---------- BEGIN ----------
*** umap_subr.c.ORIG	Tue Feb  3 20:41:24 1998
--- umap_subr.c	Tue Feb  3 21:03:37 1998
***************
*** 356,361 ****
--- 356,364 ----
  	uid_t uid;
  	gid_t gid;
  
+ 	if (credp == NOCRED)
+ 		return;
+ 
  	unentries =  MOUNTTOUMAPMOUNT(v_mount)->info_nentries;
  	usermap =  &(MOUNTTOUMAPMOUNT(v_mount)->info_mapdata[0][0]);
  	gnentries =  MOUNTTOUMAPMOUNT(v_mount)->info_gnentries;
*** umap_vnops.c.ORIG	Tue Feb  3 20:32:02 1998
--- umap_vnops.c	Tue Feb  3 20:47:18 1998
***************
*** 149,155 ****
  		/* Save old values */
  
  		savecredp = (*credpp);
! 		(*credpp) = crdup(savecredp);
  		credp = *credpp;
  
  		if (umap_bug_bypass && credp->cr_uid != 0)
--- 149,156 ----
  		/* Save old values */
  
  		savecredp = (*credpp);
! 		if (savecredp != NOCRED)
! 			(*credpp) = crdup(savecredp);
  		credp = *credpp;
  
  		if (umap_bug_bypass && credp->cr_uid != 0)
***************
*** 176,182 ****
  
  		compcredp = (*compnamepp)->cn_cred;
  		savecompcredp = compcredp;
! 		compcredp = (*compnamepp)->cn_cred = crdup(savecompcredp);
  
  		if (umap_bug_bypass && compcredp->cr_uid != 0)
  			printf("umap_bypass: component credit user was %ld, group %ld\n",
--- 177,185 ----
  
  		compcredp = (*compnamepp)->cn_cred;
  		savecompcredp = compcredp;
! 		if (savecompcredp != NOCRED)
! 			(*compnamepp)->cn_cred = crdup(savecompcredp);
! 		compcredp = (*compnamepp)->cn_cred;
  
  		if (umap_bug_bypass && compcredp->cr_uid != 0)
  			printf("umap_bypass: component credit user was %ld, group %ld\n",
***************
*** 238,248 ****
  			printf("umap_bypass: returning-user was %ld\n",
  					credp->cr_uid);
  
! 		crfree(credp);
! 		(*credpp) = savecredp;
! 		if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
! 		 	printf("umap_bypass: returning-user now %ld\n\n",
! 			    (*credpp)->cr_uid);
  	}
  
  	if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET) {
--- 241,253 ----
  			printf("umap_bypass: returning-user was %ld\n",
  					credp->cr_uid);
  
! 		if (savecredp != NOCRED) {
! 			crfree(credp);
! 			(*credpp) = savecredp;
! 			if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
! 				printf("umap_bypass: returning-user now %ld\n\n",
! 					   (*credpp)->cr_uid);
! 		}
  	}
  
  	if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET) {
***************
*** 250,260 ****
  		printf("umap_bypass: returning-component-user was %ld\n",
  				compcredp->cr_uid);
  
! 		crfree(compcredp);
! 		(*compnamepp)->cn_cred = savecompcredp;
! 		if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
! 		 	printf("umap_bypass: returning-component-user now %ld\n",
! 					compcredp->cr_uid);
  	}
  
  	return (error);
--- 255,267 ----
  		printf("umap_bypass: returning-component-user was %ld\n",
  				compcredp->cr_uid);
  
! 		if (savecompcredp != NOCRED) {
! 			crfree(compcredp);
! 			(*compnamepp)->cn_cred = savecompcredp;
! 			if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
! 				printf("umap_bypass: returning-component-user now %ld\n",
! 					   compcredp->cr_uid);
! 		}
  	}
  
  	return (error);
---------- END ----------
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: kato 
State-Changed-When: Sat Feb 7 01:03:11 PST 1998 
State-Changed-Why:  
Fixed. 
>Unformatted:
