summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux/linux_misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linux/linux_misc.c')
-rw-r--r--sys/compat/linux/linux_misc.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index e3d1cdb..2bb7b39 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -970,9 +970,19 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
l_gid_t linux_gidset[NGROUPS];
gid_t *bsd_gidset;
int ngrp, error;
+ struct proc *p;
ngrp = args->gidsetsize;
- oldcred = td->td_proc->p_ucred;
+ if (ngrp >= NGROUPS)
+ return (EINVAL);
+ error = copyin((caddr_t)args->grouplist, linux_gidset,
+ ngrp * sizeof(l_gid_t));
+ if (error)
+ return (error);
+ newcred = crget();
+ p = td->td_proc;
+ PROC_LOCK(p);
+ oldcred = p->p_ucred;
/*
* cr_groups[0] holds egid. Setting the whole set from
@@ -980,19 +990,14 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
* Keep cr_groups[0] unchanged to prevent that.
*/
- if ((error = suser_cred(oldcred, PRISON_ROOT)) != 0)
+ if ((error = suser_cred(oldcred, PRISON_ROOT)) != 0) {
+ PROC_UNLOCK(p);
+ crfree(newcred);
return (error);
+ }
- if (ngrp >= NGROUPS)
- return (EINVAL);
-
- newcred = crdup(oldcred);
+ crcopy(newcred, oldcred);
if (ngrp > 0) {
- error = copyin((caddr_t)args->grouplist, linux_gidset,
- ngrp * sizeof(l_gid_t));
- if (error)
- return (error);
-
newcred->cr_ngroups = ngrp + 1;
bsd_gidset = newcred->cr_groups;
@@ -1005,8 +1010,9 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
else
newcred->cr_ngroups = 1;
- setsugid(td->td_proc);
- td->td_proc->p_ucred = newcred;
+ setsugid(p);
+ p->p_ucred = newcred;
+ PROC_UNLOCK(p);
crfree(oldcred);
return (0);
}
OpenPOWER on IntegriCloud