diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 3 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 45 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 5 |
3 files changed, 26 insertions, 27 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 45c41490d52..fc774436a26 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1986,6 +1986,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, inode_security_set_sid(inode, newsid); + if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) + return -EOPNOTSUPP; + if (name) { namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); if (!namep) diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index fdc38238972..0e1352a555c 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = { .write = sel_write_load, }; - -static ssize_t sel_write_context(struct file * file, const char __user * buf, - size_t count, loff_t *ppos) - +static ssize_t sel_write_context(struct file * file, char *buf, size_t size) { - char *page; - u32 sid; + char *canon; + u32 sid, len; ssize_t length; length = task_has_security(current, SECURITY__CHECK_CONTEXT); if (length) return length; - if (count >= PAGE_SIZE) - return -ENOMEM; - if (*ppos != 0) { - /* No partial writes. */ - return -EINVAL; - } - page = (char*)get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - length = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + length = security_context_to_sid(buf, size, &sid); + if (length < 0) + return length; - length = security_context_to_sid(page, count, &sid); + length = security_sid_to_context(sid, &canon, &len); if (length < 0) + return length; + + if (len > SIMPLE_TRANSACTION_LIMIT) { + printk(KERN_ERR "%s: context size (%u) exceeds payload " + "max\n", __FUNCTION__, len); + length = -ERANGE; goto out; + } - length = count; + memcpy(buf, canon, len); + length = len; out: - free_page((unsigned long) page); + kfree(canon); return length; } -static struct file_operations sel_context_ops = { - .write = sel_write_context, -}; - static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { @@ -375,6 +367,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { [SEL_RELABEL] = sel_write_relabel, [SEL_USER] = sel_write_user, [SEL_MEMBER] = sel_write_member, + [SEL_CONTEXT] = sel_write_context, }; static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) @@ -1220,7 +1213,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) static struct tree_descr selinux_files[] = { [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, - [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO}, + [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO}, [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index aaefac2921f..640d0bfdbc6 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -262,8 +262,11 @@ int mls_context_to_sid(char oldc, struct cat_datum *catdatum, *rngdatum; int l, rc = -EINVAL; - if (!selinux_mls_enabled) + if (!selinux_mls_enabled) { + if (def_sid != SECSID_NULL && oldc) + *scontext += strlen(*scontext); return 0; + } /* * No MLS component to the security context, try and map to |