diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 20:27:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-21 20:27:36 -0700 |
commit | cb60e3e65c1b96a4d6444a7a13dc7dd48bc15a2b (patch) | |
tree | 4322be35db678f6299348a76ad60a2023954af7d /security/yama/yama_lsm.c | |
parent | 99262a3dafa3290866512ddfb32609198f8973e9 (diff) | |
parent | ff2bb047c4bce9742e94911eeb44b4d6ff4734ab (diff) | |
download | lwn-cb60e3e65c1b96a4d6444a7a13dc7dd48bc15a2b.tar.gz lwn-cb60e3e65c1b96a4d6444a7a13dc7dd48bc15a2b.zip |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris:
"New notable features:
- The seccomp work from Will Drewry
- PR_{GET,SET}_NO_NEW_PRIVS from Andy Lutomirski
- Longer security labels for Smack from Casey Schaufler
- Additional ptrace restriction modes for Yama by Kees Cook"
Fix up trivial context conflicts in arch/x86/Kconfig and include/linux/filter.h
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (65 commits)
apparmor: fix long path failure due to disconnected path
apparmor: fix profile lookup for unconfined
ima: fix filename hint to reflect script interpreter name
KEYS: Don't check for NULL key pointer in key_validate()
Smack: allow for significantly longer Smack labels v4
gfp flags for security_inode_alloc()?
Smack: recursive tramsmute
Yama: replace capable() with ns_capable()
TOMOYO: Accept manager programs which do not start with / .
KEYS: Add invalidation support
KEYS: Do LRU discard in full keyrings
KEYS: Permit in-place link replacement in keyring list
KEYS: Perform RCU synchronisation on keys prior to key destruction
KEYS: Announce key type (un)registration
KEYS: Reorganise keys Makefile
KEYS: Move the key config into security/keys/Kconfig
KEYS: Use the compat keyctl() syscall wrapper on Sparc64 for Sparc32 compat
Yama: remove an unused variable
samples/seccomp: fix dependencies on arch macros
Yama: add additional ptrace scopes
...
Diffstat (limited to 'security/yama/yama_lsm.c')
-rw-r--r-- | security/yama/yama_lsm.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 573723843a04..83554ee8a587 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -18,7 +18,12 @@ #include <linux/prctl.h> #include <linux/ratelimit.h> -static int ptrace_scope = 1; +#define YAMA_SCOPE_DISABLED 0 +#define YAMA_SCOPE_RELATIONAL 1 +#define YAMA_SCOPE_CAPABILITY 2 +#define YAMA_SCOPE_NO_ATTACH 3 + +static int ptrace_scope = YAMA_SCOPE_RELATIONAL; /* describe a ptrace relationship for potential exception */ struct ptrace_relation { @@ -251,17 +256,32 @@ static int yama_ptrace_access_check(struct task_struct *child, return rc; /* require ptrace target be a child of ptracer on attach */ - if (mode == PTRACE_MODE_ATTACH && - ptrace_scope && - !task_is_descendant(current, child) && - !ptracer_exception_found(current, child) && - !capable(CAP_SYS_PTRACE)) - rc = -EPERM; + if (mode == PTRACE_MODE_ATTACH) { + switch (ptrace_scope) { + case YAMA_SCOPE_DISABLED: + /* No additional restrictions. */ + break; + case YAMA_SCOPE_RELATIONAL: + if (!task_is_descendant(current, child) && + !ptracer_exception_found(current, child) && + !ns_capable(task_user_ns(child), CAP_SYS_PTRACE)) + rc = -EPERM; + break; + case YAMA_SCOPE_CAPABILITY: + if (!ns_capable(task_user_ns(child), CAP_SYS_PTRACE)) + rc = -EPERM; + break; + case YAMA_SCOPE_NO_ATTACH: + default: + rc = -EPERM; + break; + } + } if (rc) { char name[sizeof(current->comm)]; - printk_ratelimited(KERN_NOTICE "ptrace of non-child" - " pid %d was attempted by: %s (pid %d)\n", + printk_ratelimited(KERN_NOTICE + "ptrace of pid %d was attempted by: %s (pid %d)\n", child->pid, get_task_comm(name, current), current->pid); @@ -279,8 +299,27 @@ static struct security_operations yama_ops = { }; #ifdef CONFIG_SYSCTL +static int yama_dointvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int rc; + + if (write && !capable(CAP_SYS_PTRACE)) + return -EPERM; + + rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (rc) + return rc; + + /* Lock the max value if it ever gets set. */ + if (write && *(int *)table->data == *(int *)table->extra2) + table->extra1 = table->extra2; + + return rc; +} + static int zero; -static int one = 1; +static int max_scope = YAMA_SCOPE_NO_ATTACH; struct ctl_path yama_sysctl_path[] = { { .procname = "kernel", }, @@ -294,9 +333,9 @@ static struct ctl_table yama_sysctl_table[] = { .data = &ptrace_scope, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax, + .proc_handler = yama_dointvec_minmax, .extra1 = &zero, - .extra2 = &one, + .extra2 = &max_scope, }, { } }; |