diff options
author | James Morris <james.l.morris@oracle.com> | 2013-01-07 12:06:43 +1100 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2013-01-07 12:06:43 +1100 |
commit | cf9ce948f47640797bd19980e1d99c6d17d0bdc3 (patch) | |
tree | 97ce168cf32ac88b9aa93408b0b681747416a504 /security/commoncap.c | |
parent | e93072374112db9dc86635934ee761249be28370 (diff) | |
parent | d1c3ed669a2d452cacfb48c2d171a1f364dae2ed (diff) | |
download | lwn-cf9ce948f47640797bd19980e1d99c6d17d0bdc3.tar.gz lwn-cf9ce948f47640797bd19980e1d99c6d17d0bdc3.zip |
Merge tag 'v3.8-rc2' into next
Sync to Linus' tree.
Linux 3.8-rc2
Diffstat (limited to 'security/commoncap.c')
-rw-r--r-- | security/commoncap.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 6dbae4650abe..7ee08c756d6b 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -76,24 +76,33 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, int cap, int audit) { - for (;;) { - /* The owner of the user namespace has all caps. */ - if (targ_ns != &init_user_ns && uid_eq(targ_ns->owner, cred->euid)) - return 0; + struct user_namespace *ns = targ_ns; + /* See if cred has the capability in the target user namespace + * by examining the target user namespace and all of the target + * user namespace's parents. + */ + for (;;) { /* Do we have the necessary capabilities? */ - if (targ_ns == cred->user_ns) + if (ns == cred->user_ns) return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; /* Have we tried all of the parent namespaces? */ - if (targ_ns == &init_user_ns) + if (ns == &init_user_ns) return -EPERM; + /* + * The owner of the user namespace in the parent of the + * user namespace has all caps. + */ + if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid)) + return 0; + /* - *If you have a capability in a parent user ns, then you have + * If you have a capability in a parent user ns, then you have * it over all children user namespaces as well. */ - targ_ns = targ_ns->parent; + ns = ns->parent; } /* We never get here */ |