diff options
author | jhb <jhb@FreeBSD.org> | 2002-04-13 23:11:23 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2002-04-13 23:11:23 +0000 |
commit | 2c33307035d86657e961fdf238490fc7633b59be (patch) | |
tree | 79c28d44d62f6762001bb8e1f175e812ae8c217a /sys | |
parent | 511ba1872bd9314e659a8de9a82e78964aace874 (diff) | |
download | FreeBSD-src-2c33307035d86657e961fdf238490fc7633b59be.zip FreeBSD-src-2c33307035d86657e961fdf238490fc7633b59be.tar.gz |
Rework logic of syscalls that modify process credentials as described in
rev 1.152 of sys/kern/kern_prot.c.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/osf1/osf1_misc.c | 20 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 32 | ||||
-rw-r--r-- | sys/compat/linux/linux_uid16.c | 32 |
3 files changed, 55 insertions, 29 deletions
diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c index e75bdf9..8a89891 100644 --- a/sys/alpha/osf1/osf1_misc.c +++ b/sys/alpha/osf1/osf1_misc.c @@ -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); } 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); } diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index b29368c..ee39025 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -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); } |