Rework logic of syscalls that modify process credentials as described in

rev 1.152 of sys/kern/kern_prot.c.
This commit is contained in:
jhb 2002-04-13 23:11:23 +00:00
parent f9984f5fb1
commit 6f496a2e6a
3 changed files with 55 additions and 29 deletions

View File

@ -1060,13 +1060,18 @@ osf1_setuid(td, uap)
p = td->td_proc;
uid = SCARG(uap, uid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
if ((error = suser_cred(p->p_ucred, PRISON_ROOT)) != 0 &&
uid != oldcred->cr_ruid && uid != oldcred->cr_svuid)
uid != oldcred->cr_ruid && uid != oldcred->cr_svuid) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
}
newcred = crdup(oldcred);
crcopy(newcred, oldcred);
if (error == 0) {
if (uid != oldcred->cr_ruid) {
change_ruid(newcred, uid);
@ -1082,6 +1087,7 @@ osf1_setuid(td, uap)
setsugid(p);
}
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
return (0);
}
@ -1106,13 +1112,18 @@ osf1_setgid(td, uap)
p = td->td_proc;
gid = SCARG(uap, gid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
if (((error = suser_cred(p->p_ucred, PRISON_ROOT)) != 0 ) &&
gid != oldcred->cr_rgid && gid != oldcred->cr_svgid)
gid != oldcred->cr_rgid && gid != oldcred->cr_svgid) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
}
newcred = crdup(oldcred);
crcopy(newcred, oldcred);
if (error == 0) {
if (gid != oldcred->cr_rgid) {
change_rgid(newcred, gid);
@ -1128,6 +1139,7 @@ osf1_setgid(td, uap)
setsugid(p);
}
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
return (0);
}

View File

@ -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);
}

View File

@ -30,6 +30,8 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sysproto.h>
@ -93,6 +95,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
l_gid16_t linux_gidset[NGROUPS];
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
#ifdef DEBUG
if (ldebug(setgroups16))
@ -100,7 +103,16 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
#endif
ngrp = args->gidsetsize;
oldcred = td->td_proc->p_ucred;
if (ngrp >= NGROUPS)
return (EINVAL);
error = copyin((caddr_t)args->gidset, linux_gidset,
ngrp * sizeof(l_gid16_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
@ -108,19 +120,14 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_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->gidset, linux_gidset,
ngrp * sizeof(l_gid16_t));
if (error)
return (error);
newcred->cr_ngroups = ngrp + 1;
bsd_gidset = newcred->cr_groups;
@ -134,7 +141,8 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
newcred->cr_ngroups = 1;
setsugid(td->td_proc);
td->td_proc->p_ucred = newcred;
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
return (0);
}