diff options
author | Kees Cook <kees.cook@canonical.com> | 2010-06-29 11:07:44 -0700 |
---|---|---|
committer | Tim Gardner <tim.gardner@canonical.com> | 2010-07-06 08:00:48 -0600 |
commit | 7771e5231229c5060fb9a9133a2f381c03399d97 (patch) | |
tree | 7c0a105f3129786f42ae954f281105d4de3f310f | |
parent | 1b1e9f8a9d1b96689b804e9a8adba83576c9859b (diff) |
UBUNTU: SAUCE: security: unconditionally chain to Yama LSM
This patch forces the LSM to always chain through the Yama LSM
regardless of which LSM is selected as the primary LSM.
Signed-off-by: Kees Cook <kees.cook@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
-rw-r--r-- | security/security.c | 39 | ||||
-rw-r--r-- | security/yama/yama_lsm.c | 22 |
2 files changed, 50 insertions, 11 deletions
diff --git a/security/security.c b/security/security.c index 81b1152c32b..6346fc20fcb 100644 --- a/security/security.c +++ b/security/security.c @@ -22,6 +22,18 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = CONFIG_DEFAULT_SECURITY; +#if CONFIG_SECURITY_YAMA +extern int yama_ptrace_access_check(struct task_struct *child, + unsigned int mode); +extern int yama_path_link(struct dentry *old_dentry, struct path *new_dir, + struct dentry *new_dentry); +extern int yama_inode_follow_link(struct dentry *dentry, + struct nameidata *nameidata); +extern void yama_task_free(struct task_struct *task); +extern int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5); +#endif + /* things that live in capability.c */ extern void __init security_fixup_ops(struct security_operations *ops); @@ -137,6 +149,12 @@ int __init register_security(struct security_operations *ops) int security_ptrace_access_check(struct task_struct *child, unsigned int mode) { +#if CONFIG_SECURITY_YAMA + int rc; + rc = yama_ptrace_access_check(child, mode); + if (rc || security_ops->ptrace_access_check == yama_ptrace_access_check) + return rc; +#endif return security_ops->ptrace_access_check(child, mode); } @@ -408,6 +426,11 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, { if (unlikely(IS_PRIVATE(old_dentry->d_inode))) return 0; +#if CONFIG_SECURITY_YAMA + int rc = yama_path_link(old_dentry, new_dir, new_dentry); + if (rc || security_ops->path_link == yama_path_link) + return rc; +#endif return security_ops->path_link(old_dentry, new_dir, new_dentry); } EXPORT_SYMBOL(security_path_link); @@ -530,6 +553,11 @@ int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; +#if CONFIG_SECURITY_YAMA + int rc = yama_inode_follow_link(dentry, nd); + if (rc || security_ops->inode_follow_link == yama_inode_follow_link) + return rc; +#endif return security_ops->inode_follow_link(dentry, nd); } @@ -707,6 +735,11 @@ int security_task_create(unsigned long clone_flags) void security_task_free(struct task_struct *task) { +#if CONFIG_SECURITY_YAMA + yama_task_free(task); + if (security_ops->task_free == yama_task_free) + return; +#endif security_ops->task_free(task); } @@ -822,6 +855,12 @@ int security_task_wait(struct task_struct *p) int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { +#if CONFIG_SECURITY_YAMA + int rc; + rc = yama_task_prctl(option, arg2, arg3, arg4, arg5); + if (rc != -ENOSYS || security_ops->task_prctl == yama_task_prctl) + return rc; +#endif return security_ops->task_prctl(option, arg2, arg3, arg4, arg5); } diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index b667ab218fe..291a9e5dc21 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -98,7 +98,7 @@ static void yama_ptracer_del(struct task_struct *tracer, * yama_task_free - check for task_pid to remove from exception list * @task: task being removed */ -static void yama_task_free(struct task_struct *task) +void yama_task_free(struct task_struct *task) { yama_ptracer_del(task, task); } @@ -114,7 +114,7 @@ static void yama_task_free(struct task_struct *task) * Return 0 on success, -ve on error. -ENOSYS is returned when Yama * does not handle the given option. */ -static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, +int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { int rc; @@ -216,7 +216,7 @@ static int ptracer_exception_found(struct task_struct *tracer, * * Returns 0 if following the ptrace is allowed, -ve on error. */ -static int yama_ptrace_access_check(struct task_struct *child, +int yama_ptrace_access_check(struct task_struct *child, unsigned int mode) { int rc; @@ -264,7 +264,7 @@ static int yama_ptrace_access_check(struct task_struct *child, * * Returns 0 if following the symlink is allowed, -ve on error. */ -static int yama_inode_follow_link(struct dentry *dentry, +int yama_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) { int rc = 0; @@ -319,7 +319,7 @@ static int yama_inode_follow_link(struct dentry *dentry, * * Returns 0 if successful, -ve on error. */ -static int yama_path_link(struct dentry *old_dentry, struct path *new_dir, +int yama_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) { int rc = 0; @@ -400,19 +400,19 @@ static struct ctl_table yama_sysctl_table[] = { static __init int yama_init(void) { - if (!security_module_enable(&yama_ops)) - return 0; - printk(KERN_INFO "Yama: becoming mindful.\n"); - if (register_security(&yama_ops)) - panic("Yama: kernel registration failed.\n"); - #ifdef CONFIG_SYSCTL if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) panic("Yama: sysctl registration failed.\n"); #endif + if (!security_module_enable(&yama_ops)) + return 0; + + if (register_security(&yama_ops)) + panic("Yama: kernel registration failed.\n"); + return 0; } |