diff options
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) | |||
76 | int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, | 76 | int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, |
77 | int cap, int audit) | 77 | int cap, int audit) |
78 | { | 78 | { |
79 | for (;;) { | 79 | struct user_namespace *ns = targ_ns; |
80 | /* The owner of the user namespace has all caps. */ | ||
81 | if (targ_ns != &init_user_ns && uid_eq(targ_ns->owner, cred->euid)) | ||
82 | return 0; | ||
83 | 80 | ||
81 | /* See if cred has the capability in the target user namespace | ||
82 | * by examining the target user namespace and all of the target | ||
83 | * user namespace's parents. | ||
84 | */ | ||
85 | for (;;) { | ||
84 | /* Do we have the necessary capabilities? */ | 86 | /* Do we have the necessary capabilities? */ |
85 | if (targ_ns == cred->user_ns) | 87 | if (ns == cred->user_ns) |
86 | return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; | 88 | return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; |
87 | 89 | ||
88 | /* Have we tried all of the parent namespaces? */ | 90 | /* Have we tried all of the parent namespaces? */ |
89 | if (targ_ns == &init_user_ns) | 91 | if (ns == &init_user_ns) |
90 | return -EPERM; | 92 | return -EPERM; |
91 | 93 | ||
94 | /* | ||
95 | * The owner of the user namespace in the parent of the | ||
96 | * user namespace has all caps. | ||
97 | */ | ||
98 | if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid)) | ||
99 | return 0; | ||
100 | |||
92 | /* | 101 | /* |
93 | *If you have a capability in a parent user ns, then you have | 102 | * If you have a capability in a parent user ns, then you have |
94 | * it over all children user namespaces as well. | 103 | * it over all children user namespaces as well. |
95 | */ | 104 | */ |
96 | targ_ns = targ_ns->parent; | 105 | ns = ns->parent; |
97 | } | 106 | } |
98 | 107 | ||
99 | /* We never get here */ | 108 | /* We never get here */ |