Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[firefly-linux-kernel-4.4.55.git] / security / yama / yama_lsm.c
index dd4d36067c50e4bd3f158b90b9935acd2ea02ef5..573723843a04fa3c3701826519652cea3b46029d 100644 (file)
@@ -84,7 +84,7 @@ static void yama_ptracer_del(struct task_struct *tracer,
        spin_lock_bh(&ptracer_relations_lock);
        list_for_each_entry_safe(relation, safe, &ptracer_relations, node)
                if (relation->tracee == tracee ||
-                   relation->tracer == tracer) {
+                   (tracer && relation->tracer == tracer)) {
                        list_del(&relation->node);
                        kfree(relation);
                }
@@ -138,6 +138,8 @@ static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                if (arg2 == 0) {
                        yama_ptracer_del(NULL, myself);
                        rc = 0;
+               } else if (arg2 == PR_SET_PTRACER_ANY) {
+                       rc = yama_ptracer_add(NULL, myself);
                } else {
                        struct task_struct *tracer;
 
@@ -208,6 +210,7 @@ static int ptracer_exception_found(struct task_struct *tracer,
        int rc = 0;
        struct ptrace_relation *relation;
        struct task_struct *parent = NULL;
+       bool found = false;
 
        spin_lock_bh(&ptracer_relations_lock);
        rcu_read_lock();
@@ -216,10 +219,11 @@ static int ptracer_exception_found(struct task_struct *tracer,
        list_for_each_entry(relation, &ptracer_relations, node)
                if (relation->tracee == tracee) {
                        parent = relation->tracer;
+                       found = true;
                        break;
                }
 
-       if (task_is_descendant(parent, tracer))
+       if (found && (parent == NULL || task_is_descendant(parent, tracer)))
                rc = 1;
        rcu_read_unlock();
        spin_unlock_bh(&ptracer_relations_lock);