Re: 2.6.2-rc2-mm2

From: Tim Hockin
Date: Fri Jan 30 2004 - 17:32:48 EST


On Fri, Jan 30, 2004 at 02:00:24PM -0800, Andrew Morton wrote:
> Tim Hockin <thockin@xxxxxxx> wrote:
> >
> > In fact, here is a rough cut (would need a coupel exported syms, too). The
> > lack of any way to handle errors bothers me. printk and fail? yeesh.
>
> Seems to be a good way to go. It doesn't seem likely that any other parts
> of the kernel will want to be setting the group ownership in this way.

How's the attached patch? Do you need me to BK it, or is the patch enough?

--
Tim Hockin
Sun Microsystems, Linux Software Engineering
thockin@xxxxxxx
All opinions are my own, not Sun's
===== kernel/sys.c 1.70 vs edited =====
--- 1.70/kernel/sys.c Thu Jan 29 13:41:05 2004
+++ edited/kernel/sys.c Fri Jan 30 14:27:09 2004
@@ -1132,6 +1132,8 @@
return NULL;
}

+EXPORT_SYMBOL(groups_alloc);
+
void groups_free(struct group_info *group_info)
{
if (group_info->ngroups > NGROUPS_SMALL) {
@@ -1142,6 +1144,8 @@
kfree(group_info);
}

+EXPORT_SYMBOL(groups_free);
+
/* export the group_info to a user-space array */
static int groups_to_user(gid_t __user *grouplist,
struct group_info *group_info)
@@ -1251,6 +1255,8 @@

return 0;
}
+
+EXPORT_SYMBOL(set_current_groups);

asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
{
===== fs/nfsd/auth.c 1.3 vs edited =====
--- 1.3/fs/nfsd/auth.c Thu Jan 29 13:40:50 2004
+++ edited/fs/nfsd/auth.c Fri Jan 30 14:28:20 2004
@@ -10,15 +10,14 @@
#include <linux/sunrpc/svcauth.h>
#include <linux/nfsd/nfsd.h>

-extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
-
#define CAP_NFSD_MASK (CAP_FS_MASK|CAP_TO_MASK(CAP_SYS_RESOURCE))
void
nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
{
struct svc_cred *cred = &rqstp->rq_cred;
- int i;
+ int i, j;
gid_t groups[SVC_CRED_NGROUPS];
+ struct group_info *group_info;

if (exp->ex_flags & NFSEXP_ALLSQUASH) {
cred->cr_uid = exp->ex_anon_uid;
@@ -48,7 +47,13 @@
break;
groups[i] = group;
}
- sys_setgroups(i, groups);
+ group_info = groups_alloc(i);
+ /* should be error checking, but we can't return ENOMEM! */
+ for (j = 0; j < i; j++)
+ GROUP_AT(group_info, j) = groups[j];
+ if (set_current_groups(group_info))
+ put_group_info(group_info);
+ /* should be error handling but we return void */

if ((cred->cr_uid)) {
cap_t(current->cap_effective) &= ~CAP_NFSD_MASK;