aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2002-04-13 23:11:23 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2002-04-13 23:11:23 +0000
commit094a945562c40f4563be3ec926528b461005c88c (patch)
tree79c28d44d62f6762001bb8e1f175e812ae8c217a /sys
parent590ae816c2e1da8e09f305927304acdce9fbd606 (diff)
downloadsrc-094a945562c40f4563be3ec926528b461005c88c.tar.gz
src-094a945562c40f4563be3ec926528b461005c88c.zip
Rework logic of syscalls that modify process credentials as described in
rev 1.152 of sys/kern/kern_prot.c.
Notes
Notes: svn path=/head/; revision=94621
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/osf1/osf1_misc.c20
-rw-r--r--sys/compat/linux/linux_misc.c32
-rw-r--r--sys/compat/linux/linux_uid16.c32
3 files changed, 55 insertions, 29 deletions
diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c
index e75bdf999d3b..8a898915143b 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 e3d1cdbdc6ff..2bb7b399031f 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 b29368c7f508..ee39025354f5 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);
}