summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2016-12-02 18:49:43 -0500
committerJames Morris <james.l.morris@oracle.com>2016-12-04 19:48:01 -0500
commit50523a29d900d5a403e0352d3d7aeda6a33df25c (patch)
tree4c279a19e9a0f4521212bf444a939bb83c8d1915 /security
parent9430066a15d6f55a3d008a6f99bb462480870207 (diff)
Yama: allow access for the current ptrace parent
Under ptrace_scope=1, it's possible to have a tracee that is already ptrace-attached, but is no longer a direct descendant. For instance, a forking daemon will be re-parented to init, losing its ancestry to the tracer that launched it. The tracer can continue using ptrace in that state, but it will be denied other accesses that check PTRACE_MODE_ATTACH, like process_vm_rw and various procfs files. There's no reason to prevent such access for a tracer that already has ptrace control anyway. This patch adds a case to ptracer_exception_found to allow access for any task in the same thread group as the current ptrace parent. Signed-off-by: Josh Stone <jistone@redhat.com> Cc: Kees Cook <keescook@chromium.org> Cc: James Morris <james.l.morris@oracle.com> Cc: "Serge E. Hallyn" <serge@hallyn.com> Cc: linux-security-module@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security')
-rw-r--r--security/yama/yama_lsm.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 0309f2111c70..968e5e0a3f81 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -309,7 +309,7 @@ static int task_is_descendant(struct task_struct *parent,
309 * @tracer: the task_struct of the process attempting ptrace 309 * @tracer: the task_struct of the process attempting ptrace
310 * @tracee: the task_struct of the process to be ptraced 310 * @tracee: the task_struct of the process to be ptraced
311 * 311 *
312 * Returns 1 if tracer has is ptracer exception ancestor for tracee. 312 * Returns 1 if tracer has a ptracer exception ancestor for tracee.
313 */ 313 */
314static int ptracer_exception_found(struct task_struct *tracer, 314static int ptracer_exception_found(struct task_struct *tracer,
315 struct task_struct *tracee) 315 struct task_struct *tracee)
@@ -320,6 +320,18 @@ static int ptracer_exception_found(struct task_struct *tracer,
320 bool found = false; 320 bool found = false;
321 321
322 rcu_read_lock(); 322 rcu_read_lock();
323
324 /*
325 * If there's already an active tracing relationship, then make an
326 * exception for the sake of other accesses, like process_vm_rw().
327 */
328 parent = ptrace_parent(tracee);
329 if (parent != NULL && same_thread_group(parent, tracer)) {
330 rc = 1;
331 goto unlock;
332 }
333
334 /* Look for a PR_SET_PTRACER relationship. */
323 if (!thread_group_leader(tracee)) 335 if (!thread_group_leader(tracee))
324 tracee = rcu_dereference(tracee->group_leader); 336 tracee = rcu_dereference(tracee->group_leader);
325 list_for_each_entry_rcu(relation, &ptracer_relations, node) { 337 list_for_each_entry_rcu(relation, &ptracer_relations, node) {
@@ -334,6 +346,8 @@ static int ptracer_exception_found(struct task_struct *tracer,
334 346
335 if (found && (parent == NULL || task_is_descendant(parent, tracer))) 347 if (found && (parent == NULL || task_is_descendant(parent, tracer)))
336 rc = 1; 348 rc = 1;
349
350unlock:
337 rcu_read_unlock(); 351 rcu_read_unlock();
338 352
339 return rc; 353 return rc;