Yama: add PR_SET_PTRACER_ANY

For a process to entirely disable Yama ptrace restrictions, it can use
the special PR_SET_PTRACER_ANY pid to indicate that any otherwise allowed
process may ptrace it. This is stronger than calling PR_SET_PTRACER with
pid "1" because it includes processes in external pid namespaces. This is
currently needed by the Chrome renderer, since its crash handler (Breakpad)
runs external to the renderer's pid namespace.

Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index dd4d360..5737238 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -84,7 +84,7 @@
 	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 @@
 		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 @@
 	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 @@
 	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);