UBUNTU: SAUCE: security: unconditionally chain to Yama LSM
authorKees Cook <kees.cook@canonical.com>
Tue, 29 Jun 2010 18:07:44 +0000 (11:07 -0700)
committerLeann Ogasawara <leann.ogasawara@canonical.com>
Mon, 28 Mar 2011 13:48:55 +0000 (06:48 -0700)
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>

security/security.c
security/yama/yama_lsm.c

index d422c6b..7ed5b8b 100644 (file)
 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);
 
@@ -129,6 +141,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);
 }
 
@@ -387,6 +405,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);
 }
 
@@ -502,6 +525,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);
 }
 
@@ -697,6 +725,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);
 }
 
@@ -812,6 +845,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);
 }
 
index b667ab2..291a9e5 100644 (file)
@@ -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;
 }