diff options
-rw-r--r-- | include/linux/security.h | 42 | ||||
-rw-r--r-- | security/security.c | 17 | ||||
-rw-r--r-- | security/yama/yama_lsm.c | 26 |
3 files changed, 64 insertions, 21 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index 673afbb8238..4efe351a3dc 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -3021,5 +3021,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 60b996a5f5d..2368d0c0901 100644 --- a/security/security.c +++ b/security/security.c @@ -132,6 +132,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); } @@ -402,8 +406,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); @@ -522,8 +530,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); } @@ -729,6 +741,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); } @@ -844,6 +857,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 4c6c2decb88..3d7b61e9077 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -100,7 +100,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); } @@ -116,7 +116,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; @@ -243,7 +243,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; @@ -291,7 +291,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; @@ -361,7 +361,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; @@ -388,16 +388,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 zero; static int one = 1; @@ -442,14 +432,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"); |