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: