aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2012-04-16 14:56:45 -0400
committerJames Morris <james.l.morris@oracle.com>2012-04-18 23:39:56 -0400
commit389da25f93eea8ff64181ae7e3e87da68acaef2e (patch)
tree09277860746b3372cbb49ea82868709cbae99ec3
parent8156b451f37898d3c3652b4e988a4d62ae16eaac (diff)
Yama: add additional ptrace scopes
This expands the available Yama ptrace restrictions to include two more modes. Mode 2 requires CAP_SYS_PTRACE for PTRACE_ATTACH, and mode 3 completely disables PTRACE_ATTACH (and locks the sysctl). Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: James Morris <james.l.morris@oracle.com>
-rw-r--r--Documentation/security/Yama.txt10
-rw-r--r--security/yama/yama_lsm.c62
2 files changed, 60 insertions, 12 deletions
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt
index a9511f179069..e369de2d48cd 100644
--- a/Documentation/security/Yama.txt
+++ b/Documentation/security/Yama.txt
@@ -34,7 +34,7 @@ parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still
34work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID" 34work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID"
35still work as root). 35still work as root).
36 36
37For software that has defined application-specific relationships 37In mode 1, software that has defined application-specific relationships
38between a debugging process and its inferior (crash handlers, etc), 38between a debugging process and its inferior (crash handlers, etc),
39prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which 39prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which
40other process (and its descendents) are allowed to call PTRACE_ATTACH 40other process (and its descendents) are allowed to call PTRACE_ATTACH
@@ -46,6 +46,8 @@ 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.
50
49The sysctl settings are: 51The sysctl settings are:
50 52
510 - classic ptrace permissions: a process can PTRACE_ATTACH to any other 530 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
@@ -60,6 +62,12 @@ The sysctl settings are:
60 inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare 62 inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
61 an allowed debugger PID to call PTRACE_ATTACH on the inferior. 63 an allowed debugger PID to call PTRACE_ATTACH on the inferior.
62 64
652 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace
66 with PTRACE_ATTACH.
67
683 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set,
69 this sysctl cannot be changed to a lower value.
70
63The original children-only logic was based on the restrictions in grsecurity. 71The original children-only logic was based on the restrictions in grsecurity.
64 72
65============================================================== 73==============================================================
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 573723843a04..afb04cbb6971 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -18,7 +18,12 @@
18#include <linux/prctl.h> 18#include <linux/prctl.h>
19#include <linux/ratelimit.h> 19#include <linux/ratelimit.h>
20 20
21static int ptrace_scope = 1; 21#define YAMA_SCOPE_DISABLED 0
22#define YAMA_SCOPE_RELATIONAL 1
23#define YAMA_SCOPE_CAPABILITY 2
24#define YAMA_SCOPE_NO_ATTACH 3
25
26static int ptrace_scope = YAMA_SCOPE_RELATIONAL;
22 27
23/* describe a ptrace relationship for potential exception */ 28/* describe a ptrace relationship for potential exception */
24struct ptrace_relation { 29struct ptrace_relation {
@@ -251,17 +256,32 @@ static int yama_ptrace_access_check(struct task_struct *child,
251 return rc; 256 return rc;
252 257
253 /* require ptrace target be a child of ptracer on attach */ 258 /* require ptrace target be a child of ptracer on attach */
254 if (mode == PTRACE_MODE_ATTACH && 259 if (mode == PTRACE_MODE_ATTACH) {
255 ptrace_scope && 260 switch (ptrace_scope) {
256 !task_is_descendant(current, child) && 261 case YAMA_SCOPE_DISABLED:
257 !ptracer_exception_found(current, child) && 262 /* No additional restrictions. */
258 !capable(CAP_SYS_PTRACE)) 263 break;
259 rc = -EPERM; 264 case YAMA_SCOPE_RELATIONAL:
265 if (!task_is_descendant(current, child) &&
266 !ptracer_exception_found(current, child) &&
267 !capable(CAP_SYS_PTRACE))
268 rc = -EPERM;
269 break;
270 case YAMA_SCOPE_CAPABILITY:
271 if (!capable(CAP_SYS_PTRACE))
272 rc = -EPERM;
273 break;
274 case YAMA_SCOPE_NO_ATTACH:
275 default:
276 rc = -EPERM;
277 break;
278 }
279 }
260 280
261 if (rc) { 281 if (rc) {
262 char name[sizeof(current->comm)]; 282 char name[sizeof(current->comm)];
263 printk_ratelimited(KERN_NOTICE "ptrace of non-child" 283 printk_ratelimited(KERN_NOTICE
264 " pid %d was attempted by: %s (pid %d)\n", 284 "ptrace of pid %d was attempted by: %s (pid %d)\n",
265 child->pid, 285 child->pid,
266 get_task_comm(name, current), 286 get_task_comm(name, current),
267 current->pid); 287 current->pid);
@@ -279,8 +299,28 @@ static struct security_operations yama_ops = {
279}; 299};
280 300
281#ifdef CONFIG_SYSCTL 301#ifdef CONFIG_SYSCTL
302static int yama_dointvec_minmax(struct ctl_table *table, int write,
303 void __user *buffer, size_t *lenp, loff_t *ppos)
304{
305 int rc;
306
307 if (write && !capable(CAP_SYS_PTRACE))
308 return -EPERM;
309
310 rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
311 if (rc)
312 return rc;
313
314 /* Lock the max value if it ever gets set. */
315 if (write && *(int *)table->data == *(int *)table->extra2)
316 table->extra1 = table->extra2;
317
318 return rc;
319}
320
282static int zero; 321static int zero;
283static int one = 1; 322static int one = 1;
323static int max_scope = YAMA_SCOPE_NO_ATTACH;
284 324
285struct ctl_path yama_sysctl_path[] = { 325struct ctl_path yama_sysctl_path[] = {
286 { .procname = "kernel", }, 326 { .procname = "kernel", },
@@ -294,9 +334,9 @@ static struct ctl_table yama_sysctl_table[] = {
294 .data = &ptrace_scope, 334 .data = &ptrace_scope,
295 .maxlen = sizeof(int), 335 .maxlen = sizeof(int),
296 .mode = 0644, 336 .mode = 0644,
297 .proc_handler = proc_dointvec_minmax, 337 .proc_handler = yama_dointvec_minmax,
298 .extra1 = &zero, 338 .extra1 = &zero,
299 .extra2 = &one, 339 .extra2 = &max_scope,
300 }, 340 },
301 { } 341 { }
302}; 342};