/* export the group_info to a user-space array */ staticint groups_to_user(gid_t __user *grouplist, conststruct group_info *group_info)
{ struct user_namespace *user_ns = current_user_ns(); int i; unsignedint count = group_info->ngroups;
for (i = 0; i < count; i++) {
gid_t gid;
gid = from_kgid_munged(user_ns, group_info->gid[i]); if (put_user(gid, grouplist+i)) return -EFAULT;
} return 0;
}
/* fill a group_info from a user-space array - it must be allocated already */ staticint groups_from_user(struct group_info *group_info,
gid_t __user *grouplist)
{ struct user_namespace *user_ns = current_user_ns(); int i; unsignedint count = group_info->ngroups;
for (i = 0; i < count; i++) {
gid_t gid;
kgid_t kgid; if (get_user(gid, grouplist+i)) return -EFAULT;
kgid = make_kgid(user_ns, gid); if (!gid_valid(kgid)) return -EINVAL;
group_info->gid[i] = kgid;
} return 0;
}
staticint gid_cmp(constvoid *_a, constvoid *_b)
{
kgid_t a = *(kgid_t *)_a;
kgid_t b = *(kgid_t *)_b;
/* a simple bsearch */ int groups_search(conststruct group_info *group_info, kgid_t grp)
{ unsignedint left, right;
if (!group_info) return 0;
left = 0;
right = group_info->ngroups; while (left < right) { unsignedint mid = (left+right)/2; if (gid_gt(grp, group_info->gid[mid]))
left = mid + 1; elseif (gid_lt(grp, group_info->gid[mid]))
right = mid; else return 1;
} return 0;
}
/** * set_groups - Change a group subscription in a set of credentials * @new: The newly prepared set of credentials to alter * @group_info: The group list to install
*/ void set_groups(struct cred *new, struct group_info *group_info)
{
put_group_info(new->group_info);
get_group_info(group_info);
new->group_info = group_info;
}
EXPORT_SYMBOL(set_groups);
/** * set_current_groups - Change current's group subscription * @group_info: The group list to impose * * Validate a group subscription and, if valid, impose it upon current's task * security record.
*/ int set_current_groups(struct group_info *group_info)
{ struct cred *new; conststruct cred *old; int retval;
new = prepare_creds(); if (!new) return -ENOMEM;
old = current_cred();
set_groups(new, group_info);
retval = security_task_fix_setgroups(new, old); if (retval < 0) goto error;
/* no need to grab task_lock here; it cannot change */
i = cred->group_info->ngroups; if (gidsetsize) { if (i > gidsetsize) {
i = -EINVAL; goto out;
} if (groups_to_user(grouplist, cred->group_info)) {
i = -EFAULT; goto out;
}
}
out: return i;
}
/* * Check whether we're fsgid/egid or in the supplemental group..
*/ int in_group_p(kgid_t grp)
{ conststruct cred *cred = current_cred(); int retval = 1;
if (!gid_eq(grp, cred->fsgid))
retval = groups_search(cred->group_info, grp); return retval;
}
EXPORT_SYMBOL(in_group_p);
int in_egroup_p(kgid_t grp)
{ conststruct cred *cred = current_cred(); int retval = 1;
if (!gid_eq(grp, cred->egid))
retval = groups_search(cred->group_info, grp); return retval;
}
EXPORT_SYMBOL(in_egroup_p);
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.