aboutsummaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorKees Cook <kees.cook@canonical.com>2010-06-29 11:07:44 -0700
committerJohn Rigby <john.rigby@linaro.org>2011-09-23 08:50:18 -0600
commitd0629e4c68008c04b52f99b27e4078f952193267 (patch)
treeb28aefdcb05522a093f69b91ddd40223eb3e3e9a /security
parentbdc5f8863afc28bf148ecdb1a8c60d2444888148 (diff)
UBUNTU: ubuntu: Yama - 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: Tim Gardner <tim.gardner@canonical.com>
Diffstat (limited to 'security')
-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 81e712cb472..0401d32bd19 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);
@@ -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);
}
@@ -397,6 +415,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);
@@ -518,6 +541,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);
}
@@ -714,6 +742,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);
}
@@ -829,6 +862,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 d2bcc0bd78d..9389282d36a 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;
@@ -236,7 +236,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;
@@ -284,7 +284,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;
@@ -343,7 +343,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;
@@ -424,19 +424,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;
}