diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 97b7e273809..24e1b1885de 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -22,7 +22,6 @@ * as published by the Free Software Foundation. */ -#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/ptrace.h> @@ -86,6 +85,7 @@ extern unsigned int policydb_loaded_version; extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); extern int selinux_compat_net; +extern struct security_operations *security_ops; #ifdef CONFIG_SECURITY_SELINUX_DEVELOP int selinux_enforcing = 0; @@ -2297,6 +2297,25 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); } +static int selinux_inode_setotherxattr(struct dentry *dentry, char *name) +{ + if (!strncmp(name, XATTR_SECURITY_PREFIX, + sizeof XATTR_SECURITY_PREFIX - 1)) { + if (!strcmp(name, XATTR_NAME_CAPS)) { + if (!capable(CAP_SETFCAP)) + return -EPERM; + } else if (!capable(CAP_SYS_ADMIN)) { + /* A different attribute in the security namespace. + Restrict to administrator. */ + return -EPERM; + } + } + + /* Not an attribute we recognize, so just check the + ordinary setattr permission. */ + return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); +} + static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) { struct task_security_struct *tsec = current->security; @@ -2307,19 +2326,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value u32 newsid; int rc = 0; - if (strcmp(name, XATTR_NAME_SELINUX)) { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof XATTR_SECURITY_PREFIX - 1) && - !capable(CAP_SYS_ADMIN)) { - /* A different attribute in the security namespace. - Restrict to administrator. */ - return -EPERM; - } - - /* Not an attribute we recognize, so just check the - ordinary setattr permission. */ - return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); - } + if (strcmp(name, XATTR_NAME_SELINUX)) + return selinux_inode_setotherxattr(dentry, name); sbsec = inode->i_sb->s_security; if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) @@ -2393,31 +2401,14 @@ static int selinux_inode_listxattr (struct dentry *dentry) static int selinux_inode_removexattr (struct dentry *dentry, char *name) { - if (strcmp(name, XATTR_NAME_SELINUX)) { - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof XATTR_SECURITY_PREFIX - 1) && - !capable(CAP_SYS_ADMIN)) { - /* A different attribute in the security namespace. - Restrict to administrator. */ - return -EPERM; - } - - /* Not an attribute we recognize, so just check the - ordinary setattr permission. Might want a separate - permission for removexattr. */ - return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); - } + if (strcmp(name, XATTR_NAME_SELINUX)) + return selinux_inode_setotherxattr(dentry, name); /* No one is allowed to remove a SELinux security label. You can change the label, but all data must be labeled. */ return -EACCES; } -static const char *selinux_inode_xattr_getsuffix(void) -{ - return XATTR_SELINUX_SUFFIX; -} - /* * Copy the in-core inode security context value to the user. If the * getxattr() prior to this succeeded, check to see if we need to @@ -2464,6 +2455,16 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t return len; } +static int selinux_inode_need_killpriv(struct dentry *dentry) +{ + return secondary_ops->inode_need_killpriv(dentry); +} + +static int selinux_inode_killpriv(struct dentry *dentry) +{ + return secondary_ops->inode_killpriv(dentry); +} + /* file security operations */ static int selinux_revalidate_file_permission(struct file *file, int mask) @@ -2882,6 +2883,12 @@ static int selinux_task_setnice(struct task_struct *p, int nice) static int selinux_task_setioprio(struct task_struct *p, int ioprio) { + int rc; + + rc = secondary_ops->task_setioprio(p, ioprio); + if (rc) + return rc; + return task_has_perm(current, p, PROCESS__SETSCHED); } @@ -2911,6 +2918,12 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) { + int rc; + + rc = secondary_ops->task_setscheduler(p, policy, lp); + if (rc) + return rc; + return task_has_perm(current, p, PROCESS__SETSCHED); } @@ -4536,19 +4549,6 @@ static int selinux_register_security (const char *name, struct security_operatio return 0; } -static int selinux_unregister_security (const char *name, struct security_operations *ops) -{ - if (ops != secondary_ops) { - printk(KERN_ERR "%s: trying to unregister a security module " - "that is not registered.\n", __FUNCTION__); - return -EINVAL; - } - - secondary_ops = original_ops; - - return 0; -} - static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) { if (inode) @@ -4826,10 +4826,11 @@ static struct security_operations selinux_ops = { .inode_getxattr = selinux_inode_getxattr, .inode_listxattr = selinux_inode_listxattr, .inode_removexattr = selinux_inode_removexattr, - .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix, .inode_getsecurity = selinux_inode_getsecurity, .inode_setsecurity = selinux_inode_setsecurity, .inode_listsecurity = selinux_inode_listsecurity, + .inode_need_killpriv = selinux_inode_need_killpriv, + .inode_killpriv = selinux_inode_killpriv, .file_permission = selinux_file_permission, .file_alloc_security = selinux_file_alloc_security, @@ -4894,7 +4895,6 @@ static struct security_operations selinux_ops = { .sem_semop = selinux_sem_semop, .register_security = selinux_register_security, - .unregister_security = selinux_unregister_security, .d_instantiate = selinux_d_instantiate, |