X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=security%2Fselinux%2Fselinuxfs.c;h=e59da6398d44508ca902c7dad417ddb0cdba888a;hb=123656d4cc8c946f578ebd18c2050f5251720428;hp=fdc3823897207284fafe407546b40cdc7edd7899;hpb=849a8924a6740ecbf9711e015beca69425f0c429;p=powerpc.git diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index fdc3823897..e59da6398d 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) @@ -383,7 +376,7 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b char *data; ssize_t rv; - if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino]) + if (ino >= ARRAY_SIZE(write_op) || !write_op[ino]) return -EINVAL; data = simple_transaction_get(file, buf, size); @@ -1168,7 +1161,7 @@ static int sel_make_avc_files(struct dentry *dir) #endif }; - for (i = 0; i < sizeof (files) / sizeof (files[0]); i++) { + for (i = 0; i < ARRAY_SIZE(files); i++) { struct inode *inode; struct dentry *dentry; @@ -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},