Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Feb 1998 21:31:30 +0900 (JST)
From:      kato@migmatite.eps.nagoya-u.ac.jp
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   kern/5632: pagefault in umap_bypass() and umap_mapids()
Message-ID:  <199802031231.VAA00361@marble.eps.nagoya-u.ac.jp>

next in thread | raw e-mail | index | archive | help

>Number:         5632
>Category:       kern
>Synopsis:       pagefault in umap_bypass() when cred == NOCRED.
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb  3 05:00:01 PST 1998
>Last-Modified:
>Originator:     KATO Takenori
>Organization:
Dept. Earth Plarnet. Sci, Nagoya Univ.
>Release:        FreeBSD 3.0-CURRENT i386
>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 ----------
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802031231.VAA00361>