diff options
-rw-r--r-- | security/yama/yama_lsm.c | 16 |
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 | */ |
314 | static int ptracer_exception_found(struct task_struct *tracer, | 314 | static 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 | |||
350 | unlock: | ||
337 | rcu_read_unlock(); | 351 | rcu_read_unlock(); |
338 | 352 | ||
339 | return rc; | 353 | return rc; |