summaryrefslogtreecommitdiffstats
path: root/sys/compat/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linux')
-rw-r--r--sys/compat/linux/linux_misc.c24
-rw-r--r--sys/compat/linux/linux_uid16.c18
2 files changed, 27 insertions, 15 deletions
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 9595fed..267da07 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1132,7 +1132,7 @@ int
linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
{
struct ucred *newcred, *oldcred;
- l_gid_t linux_gidset[NGROUPS];
+ l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@@ -1140,13 +1140,14 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
ngrp = args->gidsetsize;
if (ngrp < 0 || ngrp >= NGROUPS)
return (EINVAL);
+ linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
if (error)
- return (error);
+ goto out;
newcred = crget();
p = td->td_proc;
PROC_LOCK(p);
- oldcred = p->p_ucred;
+ oldcred = crcopysafe(p, newcred);
/*
* cr_groups[0] holds egid. Setting the whole set from
@@ -1157,10 +1158,9 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
- return (error);
+ goto out;
}
- crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups = ngrp + 1;
@@ -1177,14 +1177,17 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
- return (0);
+ error = 0;
+out:
+ free(linux_gidset, M_TEMP);
+ return (error);
}
int
linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
{
struct ucred *cred;
- l_gid_t linux_gidset[NGROUPS];
+ l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
@@ -1207,13 +1210,16 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
return (EINVAL);
ngrp = 0;
+ linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
+ M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
- if ((error = copyout(linux_gidset, args->grouplist,
- ngrp * sizeof(l_gid_t))))
+ error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
+ free(linux_gidset, M_TEMP);
+ if (error)
return (error);
td->td_retval[0] = ngrp;
diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c
index 2685eaa..b49bf78 100644
--- a/sys/compat/linux/linux_uid16.c
+++ b/sys/compat/linux/linux_uid16.c
@@ -98,7 +98,7 @@ int
linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
{
struct ucred *newcred, *oldcred;
- l_gid16_t linux_gidset[NGROUPS];
+ l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@@ -111,13 +111,14 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
ngrp = args->gidsetsize;
if (ngrp < 0 || ngrp >= NGROUPS)
return (EINVAL);
+ linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error = copyin(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;
+ oldcred = crcopysafe(p, newcred);
/*
* cr_groups[0] holds egid. Setting the whole set from
@@ -128,10 +129,9 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
- return (error);
+ goto out;
}
- crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups = ngrp + 1;
@@ -149,14 +149,17 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
- return (0);
+ error = 0;
+out:
+ free(linux_gidset, M_TEMP);
+ return (error);
}
int
linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
{
struct ucred *cred;
- l_gid16_t linux_gidset[NGROUPS];
+ l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
@@ -184,12 +187,15 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
return (EINVAL);
ngrp = 0;
+ linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
+ M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
+ free(linux_gidset, M_TEMP);
if (error)
return (error);
OpenPOWER on IntegriCloud