Subject: kern/5538: Misc. UMAPFS errors
To: None <gnats-bugs@gnats.netbsd.org, perseant@hhhh.org>
From: None <perseant@hitl.washington.edu>
List: netbsd-bugs
Date: 06/04/1998 09:56:59
>Number:         5538
>Category:       kern
>Synopsis:       Umap FS crashes during rename, and does not correctly map group credentials
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jun  4 10:05:01 1998
>Last-Modified:
>Originator:     Konrad Schroder
>Organization:
Konrad Schroder           http://www.hitl.washington.edu/people/perseant/
System Administrator                         perseant@hitl.washington.edu
Human Interface Technology Lab                      Voice: (206) 616-1478
Box 352142, University of Washington, 98195, USA      FAX: (206) 543-5380

>Release:        2 June 1998
>Environment:
System: NetBSD itchy 1.3.2 NetBSD 1.3.2 (PRISM) #13: Thu Jun  4 09:02:09 PDT 1998     perseant@itchy:/usr/src/sys/arch/sparc/compile/PRISM sparc

>Description:
	There are actually two problems.  The first is that umap_bypass (and
	probably null_bypass, though I haven't checked) doesn't check the
	vp's for NULLVP before it tries to check whether they are the current
	fs type to map them.  In the case of (at least) VOP_RENAME, one of
	the vp's passed in can be NULLVP, so we dereference a null pointer.

	The second problem is that the existing group-mapping code assumes
	that 0 terminates the list of groupids in a credential structure;
	but this is not true---there is a count for that.  The effect of
	this problem is that if someone in Wheel group needs one of their
	other group-ids mapped, they're SOL.

	Less important, I had to make some (trivial) changes to be able to
	compile with UMAPFS_DIAGNOSTIC.

	All of these problems should be fixed by the enclosed patch.
>How-To-Repeat:
	[This is from memory, I may have reversed the fields in /etc/gids]
	itchy% su
	itchy# cat > /etc/uids
	1
	2547 2547
	^D
	itchy# cat > /etc/gids
	1
	3 4
	^D
	itchy# mkdir /tmp/fred
	itchy# chgrp 3 /tmp/fred
	itchy# chmod 775 /tmp/fred
	itchy# exit
	itchy# mount_umap -u /etc/uids -g /etc/gids /tmp /var/test
	itchy% id -G
	2547 0 2 3 5 7
	itchy% touch /tmp/bar
	itchy% cd /var/test/fred
	itchy% ls -ld .
	drwxrwxr-x 2 root 3 7168 Jun  4 09:37 .
	itchy% touch /var/test/fred/foo
	touch: Permission denied
	itchy% cd /var/test
	itchy% mv bar baz
	[system crashes]
>Fix:

*** umapfs.dist/umap_subr.c	Thu Sep 11 04:20:58 1997
--- umapfs/umap_subr.c	Thu Jun  4 09:30:40 1998
***************
*** 434,446 ****
  		structure. */
  
! 	i = 0;
! 	while (credp->cr_groups[i] != 0) {
  		gid = (gid_t) umap_findid(credp->cr_groups[i],
  					  groupmap, gnentries);
- 
  		if (gid != -1)
! 			credp->cr_groups[i++] = gid;
  		else
! 			credp->cr_groups[i++] = NULLGROUP;
  	}
  }
--- 434,444 ----
  		structure. */
  
! 	for(i=0; i<credp->cr_ngroups; i++) {
  		gid = (gid_t) umap_findid(credp->cr_groups[i],
  					groupmap, gnentries);
  		if(gid != -1)
! 			credp->cr_groups[i] = gid;
  		else
! 			credp->cr_groups[i] = NULLGROUP;
  	}
  }
*** umapfs.dist/umap_vfsops.c	Mon Oct  6 04:26:46 1997
--- umapfs/umap_vfsops.c	Tue Jun  2 12:41:12 1998
***************
*** 154,158 ****
  	printf("umap_mount:nentries %d\n",args.nentries);
  	for (i = 0; i < args.nentries; i++)
! 		printf("   %d maps to %d\n", amp->info_mapdata[i][0],
  	 	    amp->info_mapdata[i][1]);
  #endif
--- 163,167 ----
  	printf("umap_mount:nentries %d\n",args.nentries);
  	for (i = 0; i < args.nentries; i++)
! 		printf("   %ld maps to %ld\n", amp->info_mapdata[i][0],
  	 	    amp->info_mapdata[i][1]);
  #endif
***************
*** 166,170 ****
  	printf("umap_mount:gnentries %d\n",args.gnentries);
  	for (i = 0; i < args.gnentries; i++)
! 		printf("\tgroup %d maps to %d\n", 
  		    amp->info_gmapdata[i][0],
  	 	    amp->info_gmapdata[i][1]);
--- 175,179 ----
  	printf("umap_mount:gnentries %d\n",args.gnentries);
  	for (i = 0; i < args.gnentries; i++)
! 		printf("\tgroup %ld maps to %ld\n", 
  		    amp->info_gmapdata[i][0],
  	 	    amp->info_gmapdata[i][1]);
*** umapfs.dist/umap_vnops.c	Mon Oct  6 04:26:46 1997
--- umapfs/umap_vnops.c	Thu Jun  4 09:27:13 1998
***************
*** 151,163 ****
  		 */
  
! 		if (i && (*this_vp_p)->v_op != umap_vnodeop_p) {
  			old_vps[i] = NULL;
  		} else {
  			old_vps[i] = *this_vp_p;
  			*(vps_p[i]) = UMAPVPTOLOWERVP(*this_vp_p);
! 			if (reles & 1)
  				VREF(*this_vp_p);
  		}
! 			
  	}
  
--- 151,163 ----
  		 */
  
! 		if (i && ((*this_vp_p) == NULLVP || (*this_vp_p)->v_op != umap_vnodeop_p)) {
  			old_vps[i] = NULL;
  		} else {
  			old_vps[i] = *this_vp_p;
  			*(vps_p[i]) = UMAPVPTOLOWERVP(*this_vp_p);
! 			if (reles & 1) {
  				VREF(*this_vp_p);
  			}
! 		}
  	}
  
***************
*** 178,184 ****
  		credp = *credpp;
  
! 		if (umap_bug_bypass && credp->cr_uid != 0)
! 			printf("umap_bypass: user was %d, group %d\n", 
  			    credp->cr_uid, credp->cr_gid);
  
  		/* Map all ids in the credential structure. */
--- 178,190 ----
  		credp = *credpp;
  
! 		if (umap_bug_bypass && credp->cr_uid != 0) {
! 			printf("umap_bypass: user was %d, group %d (", 
  			    credp->cr_uid, credp->cr_gid);
+ 			for(i=0; i<credp->cr_ngroups; i++) {
+ 				printf("%d%s", credp->cr_groups[i],
+ 					(i==credp->cr_ngroups-1?"":","));
+ 			}
+ 			printf(")\n");
+ 		}
  
  		/* Map all ids in the credential structure. */
***************
*** 186,192 ****
  		umap_mapids(vp1->v_mount, credp);
  
! 		if (umap_bug_bypass && credp->cr_uid != 0)
  			printf("umap_bypass: user now %d, group %d\n", 
  			    credp->cr_uid, credp->cr_gid);
  	}
  
--- 192,204 ----
  		umap_mapids(vp1->v_mount, credp);
  
! 		if (umap_bug_bypass && credp->cr_uid != 0) {
  			printf("umap_bypass: user now %d, group %d\n", 
  			    credp->cr_uid, credp->cr_gid);
+ 			for(i=0; i<credp->cr_ngroups; i++) {
+ 				printf("%d%s", credp->cr_groups[i],
+ 					(i==credp->cr_ngroups-1?"":","));
+ 			}
+ 			printf(")\n");
+ 		}
  	}
  
>Audit-Trail:
>Unformatted: