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:
parent
f9984f5fb1
commit
6f496a2e6a
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user