diff options
Diffstat (limited to 'security/commoncap.c')
-rw-r--r-- | security/commoncap.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/security/commoncap.c b/security/commoncap.c index 43a205bc7d7c..f20e984ccfb4 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -127,18 +127,30 @@ int cap_settime(const struct timespec *ts, const struct timezone *tz) | |||
127 | * @child: The process to be accessed | 127 | * @child: The process to be accessed |
128 | * @mode: The mode of attachment. | 128 | * @mode: The mode of attachment. |
129 | * | 129 | * |
130 | * If we are in the same or an ancestor user_ns and have all the target | ||
131 | * task's capabilities, then ptrace access is allowed. | ||
132 | * If we have the ptrace capability to the target user_ns, then ptrace | ||
133 | * access is allowed. | ||
134 | * Else denied. | ||
135 | * | ||
130 | * Determine whether a process may access another, returning 0 if permission | 136 | * Determine whether a process may access another, returning 0 if permission |
131 | * granted, -ve if denied. | 137 | * granted, -ve if denied. |
132 | */ | 138 | */ |
133 | int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) | 139 | int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) |
134 | { | 140 | { |
135 | int ret = 0; | 141 | int ret = 0; |
142 | const struct cred *cred, *child_cred; | ||
136 | 143 | ||
137 | rcu_read_lock(); | 144 | rcu_read_lock(); |
138 | if (!cap_issubset(__task_cred(child)->cap_permitted, | 145 | cred = current_cred(); |
139 | current_cred()->cap_permitted) && | 146 | child_cred = __task_cred(child); |
140 | !capable(CAP_SYS_PTRACE)) | 147 | if (cred->user->user_ns == child_cred->user->user_ns && |
141 | ret = -EPERM; | 148 | cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) |
149 | goto out; | ||
150 | if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE)) | ||
151 | goto out; | ||
152 | ret = -EPERM; | ||
153 | out: | ||
142 | rcu_read_unlock(); | 154 | rcu_read_unlock(); |
143 | return ret; | 155 | return ret; |
144 | } | 156 | } |
@@ -147,18 +159,30 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) | |||
147 | * cap_ptrace_traceme - Determine whether another process may trace the current | 159 | * cap_ptrace_traceme - Determine whether another process may trace the current |
148 | * @parent: The task proposed to be the tracer | 160 | * @parent: The task proposed to be the tracer |
149 | * | 161 | * |
162 | * If parent is in the same or an ancestor user_ns and has all current's | ||
163 | * capabilities, then ptrace access is allowed. | ||
164 | * If parent has the ptrace capability to current's user_ns, then ptrace | ||
165 | * access is allowed. | ||
166 | * Else denied. | ||
167 | * | ||
150 | * Determine whether the nominated task is permitted to trace the current | 168 | * Determine whether the nominated task is permitted to trace the current |
151 | * process, returning 0 if permission is granted, -ve if denied. | 169 | * process, returning 0 if permission is granted, -ve if denied. |
152 | */ | 170 | */ |
153 | int cap_ptrace_traceme(struct task_struct *parent) | 171 | int cap_ptrace_traceme(struct task_struct *parent) |
154 | { | 172 | { |
155 | int ret = 0; | 173 | int ret = 0; |
174 | const struct cred *cred, *child_cred; | ||
156 | 175 | ||
157 | rcu_read_lock(); | 176 | rcu_read_lock(); |
158 | if (!cap_issubset(current_cred()->cap_permitted, | 177 | cred = __task_cred(parent); |
159 | __task_cred(parent)->cap_permitted) && | 178 | child_cred = current_cred(); |
160 | !has_capability(parent, CAP_SYS_PTRACE)) | 179 | if (cred->user->user_ns == child_cred->user->user_ns && |
161 | ret = -EPERM; | 180 | cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) |
181 | goto out; | ||
182 | if (has_ns_capability(parent, child_cred->user->user_ns, CAP_SYS_PTRACE)) | ||
183 | goto out; | ||
184 | ret = -EPERM; | ||
185 | out: | ||
162 | rcu_read_unlock(); | 186 | rcu_read_unlock(); |
163 | return ret; | 187 | return ret; |
164 | } | 188 | } |