summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-08-10 04:01:26 +0200
committerJames Morris <james.l.morris@oracle.com>2012-08-10 11:58:07 +0200
commit9d8dad742ad1c74d7e7210ee05d0b44961d5ea16 (patch)
treeb1e738bf17987552cdace2695d8b77328dc29bcf /security
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net (diff)
downloadlinux-9d8dad742ad1c74d7e7210ee05d0b44961d5ea16.tar.xz
linux-9d8dad742ad1c74d7e7210ee05d0b44961d5ea16.zip
Yama: higher restrictions should block PTRACE_TRACEME
The higher ptrace restriction levels should be blocking even PTRACE_TRACEME requests. The comments in the LSM documentation are misleading about when the checks happen (the parent does not go through security_ptrace_access_check() on a PTRACE_TRACEME call). Signed-off-by: Kees Cook <keescook@chromium.org> Cc: stable@vger.kernel.org # 3.5.x and later Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security')
-rw-r--r--security/yama/yama_lsm.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 83554ee8a587..d51b7c76c37d 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -290,10 +290,51 @@ static int yama_ptrace_access_check(struct task_struct *child,
return rc;
}
+/**
+ * yama_ptrace_traceme - validate PTRACE_TRACEME calls
+ * @parent: task that will become the ptracer of the current task
+ *
+ * Returns 0 if following the ptrace is allowed, -ve on error.
+ */
+static int yama_ptrace_traceme(struct task_struct *parent)
+{
+ int rc;
+
+ /* If standard caps disallows it, so does Yama. We should
+ * only tighten restrictions further.
+ */
+ rc = cap_ptrace_traceme(parent);
+ if (rc)
+ return rc;
+
+ /* Only disallow PTRACE_TRACEME on more aggressive settings. */
+ switch (ptrace_scope) {
+ case YAMA_SCOPE_CAPABILITY:
+ if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE))
+ rc = -EPERM;
+ break;
+ case YAMA_SCOPE_NO_ATTACH:
+ rc = -EPERM;
+ break;
+ }
+
+ if (rc) {
+ char name[sizeof(current->comm)];
+ printk_ratelimited(KERN_NOTICE
+ "ptraceme of pid %d was attempted by: %s (pid %d)\n",
+ current->pid,
+ get_task_comm(name, parent),
+ parent->pid);
+ }
+
+ return rc;
+}
+
static struct security_operations yama_ops = {
.name = "yama",
.ptrace_access_check = yama_ptrace_access_check,
+ .ptrace_traceme = yama_ptrace_traceme,
.task_prctl = yama_task_prctl,
.task_free = yama_task_free,
};