summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-02-15 01:48:09 +0100
committerJames Morris <jmorris@namei.org>2012-02-16 00:25:18 +0100
commitbf06189e4d14641c0148bea16e9dd24943862215 (patch)
tree5c62eb24339041baf65b8e42daac42c7a01efc0e /security
parentTPM: Zero buffer whole after copying to userspace (diff)
downloadlinux-bf06189e4d14641c0148bea16e9dd24943862215.tar.xz
linux-bf06189e4d14641c0148bea16e9dd24943862215.zip
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>
Diffstat (limited to 'security')
-rw-r--r--security/yama/yama_lsm.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index dd4d36067c50..573723843a04 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -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);