Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce9982d0 authored by Stephen Smalley's avatar Stephen Smalley Committed by Linus Torvalds
Browse files

[PATCH] selinux: extend selinuxfs context interface



This patch extends the selinuxfs context interface to allow return the
canonical form of the context to userspace.

Signed-off-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 25a74f3b
Loading
Loading
Loading
Loading
+19 −26
Original line number Original line Diff line number Diff line
@@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = {
	.write		= sel_write_load,
	.write		= sel_write_load,
};
};



static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
static ssize_t sel_write_context(struct file * file, const char __user * buf,
				 size_t count, loff_t *ppos)

{
{
	char *page;
	char *canon;
	u32 sid;
	u32 sid, len;
	ssize_t length;
	ssize_t length;


	length = task_has_security(current, SECURITY__CHECK_CONTEXT);
	length = task_has_security(current, SECURITY__CHECK_CONTEXT);
	if (length)
	if (length)
		return length;
		return length;


	if (count >= PAGE_SIZE)
	length = security_context_to_sid(buf, size, &sid);
		return -ENOMEM;
	if (length < 0)
	if (*ppos != 0) {
		return length;
		/* 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(page, count, &sid);
	length = security_sid_to_context(sid, &canon, &len);
	if (length < 0)
	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;
		goto out;
	}


	length = count;
	memcpy(buf, canon, len);
	length = len;
out:
out:
	free_page((unsigned long) page);
	kfree(canon);
	return length;
	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,
static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
				     size_t count, loff_t *ppos)
				     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_RELABEL] = sel_write_relabel,
	[SEL_USER] = sel_write_user,
	[SEL_USER] = sel_write_user,
	[SEL_MEMBER] = sel_write_member,
	[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)
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[] = {
	static struct tree_descr selinux_files[] = {
		[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
		[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
		[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|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_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO},
		[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
		[SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO},
		[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},
		[SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO},