aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKees Cook <kees.cook@canonical.com>2010-06-29 11:07:44 -0700
committerJohn Rigby <john.rigby@linaro.org>2012-06-25 15:02:21 -0600
commitff742a4061a69e24923a5135e3936579d9039cbf (patch)
tree7c90c91ae32c763f29785130296426fada8c1ac8
parent8b06d918391bca5b513f9d8177ab79a18f326d0b (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. This is not intended for upstream. This is, however, what Ubuntu and ChromeOS are doing. Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
-rw-r--r--include/linux/security.h42
-rw-r--r--security/security.c17
-rw-r--r--security/yama/yama_lsm.c26
3 files changed, 64 insertions, 21 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index 4e5a73cdbbe..6ae2a7f42ca 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -3023,5 +3023,47 @@ static inline void free_secdata(void *secdata)
{ }
#endif /* CONFIG_SECURITY */
+#ifdef 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);
+#else
+static inline int yama_ptrace_access_check(struct task_struct *child,
+ unsigned int mode)
+{
+ return 0;
+}
+
+static inline int yama_path_link(struct dentry *old_dentry,
+ struct path *new_dir,
+ struct dentry *new_dentry)
+{
+ return 0;
+}
+
+static inline int yama_inode_follow_link(struct dentry *dentry,
+ struct nameidata *nameidata)
+{
+ return 0;
+}
+
+static inline void yama_task_free(struct task_struct *task)
+{
+}
+
+static inline int yama_task_prctl(int option, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5)
+{
+ return -ENOSYS;
+}
+#endif /* CONFIG_SECURITY_YAMA */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/security/security.c b/security/security.c
index c7afd35aa2b..7fb3683fdad 100644
--- a/security/security.c
+++ b/security/security.c
@@ -135,6 +135,10 @@ int __init register_security(struct security_operations *ops)
int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
+ int rc;
+ rc = yama_ptrace_access_check(child, mode);
+ if (rc)
+ return rc;
return security_ops->ptrace_access_check(child, mode);
}
@@ -405,8 +409,12 @@ EXPORT_SYMBOL(security_path_symlink);
int security_path_link(struct dentry *old_dentry, struct path *new_dir,
struct dentry *new_dentry)
{
+ int rc;
if (unlikely(IS_PRIVATE(old_dentry->d_inode)))
return 0;
+ rc = yama_path_link(old_dentry, new_dir, new_dentry);
+ if (rc)
+ return rc;
return security_ops->path_link(old_dentry, new_dir, new_dentry);
}
EXPORT_SYMBOL(security_path_link);
@@ -525,8 +533,12 @@ EXPORT_SYMBOL(security_inode_readlink);
int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
{
+ int rc;
if (unlikely(IS_PRIVATE(dentry->d_inode)))
return 0;
+ rc = yama_inode_follow_link(dentry, nd);
+ if (rc)
+ return rc;
return security_ops->inode_follow_link(dentry, nd);
}
@@ -770,6 +782,7 @@ int security_task_create(unsigned long clone_flags)
void security_task_free(struct task_struct *task)
{
+ yama_task_free(task);
security_ops->task_free(task);
}
@@ -885,6 +898,10 @@ 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)
{
+ int rc;
+ rc = yama_task_prctl(option, arg2, arg3, arg4, arg5);
+ if (rc != -ENOSYS)
+ return rc;
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 50c72221d13..8694b0e3f8e 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -105,7 +105,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);
}
@@ -121,7 +121,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;
@@ -248,7 +248,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;
@@ -311,7 +311,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;
@@ -381,7 +381,7 @@ static int yama_generic_permission(struct inode *inode, int mask)
*
* 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;
@@ -408,16 +408,6 @@ static int yama_path_link(struct dentry *old_dentry, struct path *new_dir,
return rc;
}
-static struct security_operations yama_ops = {
- .name = "yama",
-
- .ptrace_access_check = yama_ptrace_access_check,
- .inode_follow_link = yama_inode_follow_link,
- .path_link = yama_path_link,
- .task_prctl = yama_task_prctl,
- .task_free = yama_task_free,
-};
-
#ifdef CONFIG_SYSCTL
static int yama_dointvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -481,14 +471,8 @@ 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");