aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;