aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <kees.cook@canonical.com>2010-06-29 11:07:44 -0700
committerTim Gardner <tim.gardner@canonical.com>2010-07-06 08:00:48 -0600
commit7771e5231229c5060fb9a9133a2f381c03399d97 (patch)
tree7c0a105f3129786f42ae954f281105d4de3f310f
parent1b1e9f8a9d1b96689b804e9a8adba83576c9859b (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.c39
-rw-r--r--security/yama/yama_lsm.c22
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;
}