Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linux/linux_misc.c
Show First 20 Lines • Show All 1,213 Lines • ▼ Show 20 Lines | linux_nice(struct thread *td, struct linux_nice_args *args) | ||||
return (sys_setpriority(td, &bsd_args)); | return (sys_setpriority(td, &bsd_args)); | ||||
} | } | ||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | ||||
int | int | ||||
linux_setgroups(struct thread *td, struct linux_setgroups_args *args) | linux_setgroups(struct thread *td, struct linux_setgroups_args *args) | ||||
{ | { | ||||
struct ucred *newcred, *oldcred; | struct ucred *newcred, *oldcred; | ||||
struct credwrap *newcredwrap, *oldcredwrap; | |||||
l_gid_t *linux_gidset; | l_gid_t *linux_gidset; | ||||
gid_t *bsd_gidset; | gid_t *bsd_gidset; | ||||
int ngrp, error; | int ngrp, error; | ||||
struct proc *p; | struct proc *p; | ||||
ngrp = args->gidsetsize; | ngrp = args->gidsetsize; | ||||
if (ngrp < 0 || ngrp >= ngroups_max + 1) | if (ngrp < 0 || ngrp >= ngroups_max + 1) | ||||
return (EINVAL); | return (EINVAL); | ||||
linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); | linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); | ||||
error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); | error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
newcred = crget(); | newcred = crget(); | ||||
newcredwrap = crwget(newcred); | |||||
crextend(newcred, ngrp + 1); | crextend(newcred, ngrp + 1); | ||||
p = td->td_proc; | p = td->td_proc; | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
oldcred = p->p_ucred; | oldcred = p->p_ucred; | ||||
oldcredwrap = p->p_credwrap; | |||||
crcopy(newcred, oldcred); | crcopy(newcred, oldcred); | ||||
/* | /* | ||||
* cr_groups[0] holds egid. Setting the whole set from | * cr_groups[0] holds egid. Setting the whole set from | ||||
* the supplied set will cause egid to be changed too. | * the supplied set will cause egid to be changed too. | ||||
* Keep cr_groups[0] unchanged to prevent that. | * Keep cr_groups[0] unchanged to prevent that. | ||||
*/ | */ | ||||
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { | if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
crfree(newcred); | crfree(newcred); | ||||
crwfree(newcredwrap); | |||||
goto out; | goto out; | ||||
} | } | ||||
if (ngrp > 0) { | if (ngrp > 0) { | ||||
newcred->cr_ngroups = ngrp + 1; | newcred->cr_ngroups = ngrp + 1; | ||||
bsd_gidset = newcred->cr_groups; | bsd_gidset = newcred->cr_groups; | ||||
ngrp--; | ngrp--; | ||||
while (ngrp >= 0) { | while (ngrp >= 0) { | ||||
bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; | bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; | ||||
ngrp--; | ngrp--; | ||||
} | } | ||||
} else | } else | ||||
newcred->cr_ngroups = 1; | newcred->cr_ngroups = 1; | ||||
setsugid(p); | setsugid(p); | ||||
proc_set_cred(p, newcred); | proc_set_cred(p, newcred, newcredwrap); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
crfree(oldcred); | crfree(oldcred); | ||||
crwfree(oldcredwrap); | |||||
error = 0; | error = 0; | ||||
out: | out: | ||||
free(linux_gidset, M_LINUX); | free(linux_gidset, M_LINUX); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
linux_getgroups(struct thread *td, struct linux_getgroups_args *args) | linux_getgroups(struct thread *td, struct linux_getgroups_args *args) | ||||
▲ Show 20 Lines • Show All 1,015 Lines • Show Last 20 Lines |