aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-08-09 22:01:26 -0400
committerJames Morris <james.l.morris@oracle.com>2012-08-10 05:58:07 -0400
commit9d8dad742ad1c74d7e7210ee05d0b44961d5ea16 (patch)
treeb1e738bf17987552cdace2695d8b77328dc29bcf
parentf4ba394c1b02e7fc2179fda8d3941a5b3b65efb6 (diff)
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>
-rw-r--r--Documentation/security/Yama.txt14
-rw-r--r--include/linux/security.h2
-rw-r--r--security/yama/yama_lsm.c41
3 files changed, 48 insertions, 9 deletions
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt
index e369de2d48cd..dd908cf64ecf 100644
--- a/Documentation/security/Yama.txt
+++ b/Documentation/security/Yama.txt
@@ -46,14 +46,13 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
46so that any otherwise allowed process (even those in external pid namespaces) 46so that any otherwise allowed process (even those in external pid namespaces)
47may attach. 47may attach.
48 48
49These restrictions do not change how ptrace via PTRACE_TRACEME operates. 49The sysctl settings (writable only with CAP_SYS_PTRACE) are:
50
51The sysctl settings are:
52 50
530 - classic ptrace permissions: a process can PTRACE_ATTACH to any other 510 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
54 process running under the same uid, as long as it is dumpable (i.e. 52 process running under the same uid, as long as it is dumpable (i.e.
55 did not transition uids, start privileged, or have called 53 did not transition uids, start privileged, or have called
56 prctl(PR_SET_DUMPABLE...) already). 54 prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is
55 unchanged.
57 56
581 - restricted ptrace: a process must have a predefined relationship 571 - restricted ptrace: a process must have a predefined relationship
59 with the inferior it wants to call PTRACE_ATTACH on. By default, 58 with the inferior it wants to call PTRACE_ATTACH on. By default,
@@ -61,12 +60,13 @@ The sysctl settings are:
61 classic criteria is also met. To change the relationship, an 60 classic criteria is also met. To change the relationship, an
62 inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare 61 inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
63 an allowed debugger PID to call PTRACE_ATTACH on the inferior. 62 an allowed debugger PID to call PTRACE_ATTACH on the inferior.
63 Using PTRACE_TRACEME is unchanged.
64 64
652 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace 652 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace
66 with PTRACE_ATTACH. 66 with PTRACE_ATTACH, or through children calling PTRACE_TRACEME.
67 67
683 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set, 683 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via
69 this sysctl cannot be changed to a lower value. 69 PTRACE_TRACEME. Once set, this sysctl value cannot be changed.
70 70
71The original children-only logic was based on the restrictions in grsecurity. 71The original children-only logic was based on the restrictions in grsecurity.
72 72
diff --git a/include/linux/security.h b/include/linux/security.h
index 4e5a73cdbbef..3dea6a9d568f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1242,8 +1242,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1242 * Check that the @parent process has sufficient permission to trace the 1242 * Check that the @parent process has sufficient permission to trace the
1243 * current process before allowing the current process to present itself 1243 * current process before allowing the current process to present itself
1244 * to the @parent process for tracing. 1244 * to the @parent process for tracing.
1245 * The parent process will still have to undergo the ptrace_access_check
1246 * checks before it is allowed to trace this one.
1247 * @parent contains the task_struct structure for debugger process. 1245 * @parent contains the task_struct structure for debugger process.
1248 * Return 0 if permission is granted. 1246 * Return 0 if permission is granted.
1249 * @capget: 1247 * @capget:
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,
290 return rc; 290 return rc;
291} 291}
292 292
293/**
294 * yama_ptrace_traceme - validate PTRACE_TRACEME calls
295 * @parent: task that will become the ptracer of the current task
296 *
297 * Returns 0 if following the ptrace is allowed, -ve on error.
298 */
299static int yama_ptrace_traceme(struct task_struct *parent)
300{
301 int rc;
302
303 /* If standard caps disallows it, so does Yama. We should
304 * only tighten restrictions further.
305 */
306 rc = cap_ptrace_traceme(parent);
307 if (rc)
308 return rc;
309
310 /* Only disallow PTRACE_TRACEME on more aggressive settings. */
311 switch (ptrace_scope) {
312 case YAMA_SCOPE_CAPABILITY:
313 if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE))
314 rc = -EPERM;
315 break;
316 case YAMA_SCOPE_NO_ATTACH:
317 rc = -EPERM;
318 break;
319 }
320
321 if (rc) {
322 char name[sizeof(current->comm)];
323 printk_ratelimited(KERN_NOTICE
324 "ptraceme of pid %d was attempted by: %s (pid %d)\n",
325 current->pid,
326 get_task_comm(name, parent),
327 parent->pid);
328 }
329
330 return rc;
331}
332
293static struct security_operations yama_ops = { 333static struct security_operations yama_ops = {
294 .name = "yama", 334 .name = "yama",
295 335
296 .ptrace_access_check = yama_ptrace_access_check, 336 .ptrace_access_check = yama_ptrace_access_check,
337 .ptrace_traceme = yama_ptrace_traceme,
297 .task_prctl = yama_task_prctl, 338 .task_prctl = yama_task_prctl,
298 .task_free = yama_task_free, 339 .task_free = yama_task_free,
299}; 340};