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

Commit 0f7e4c33 authored by Kohei Kaigai's avatar Kohei Kaigai Committed by Eric Paris
Browse files

selinux: fix case of names with whitespace/multibytes on /selinux/create



I submit the patch again, according to patch submission convension.

This patch enables to accept percent-encoded object names as forth
argument of /selinux/create interface to avoid possible bugs when we
give an object name including whitespace or multibutes.

E.g) if and when a userspace object manager tries to create a new object
 named as "resolve.conf but fake", it shall give this name as the forth
 argument of the /selinux/create. But sscanf() logic in kernel space
 fetches only the part earlier than the first whitespace.
 In this case, selinux may unexpectedly answer a default security context
 configured to "resolve.conf", but it is bug.

Although I could not test this patch on named TYPE_TRANSITION rules
actually, But debug printk() message seems to me the logic works
correctly.
I assume the libselinux provides an interface to apply this logic
transparently, so nothing shall not be changed from the viewpoint of
application.

Signed-off-by: default avatarKaiGai Kohei <kohei.kaigai@emea.nec.com>
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent ea77f7a2
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/audit.h>
#include <linux/uaccess.h>
#include <linux/kobject.h>
#include <linux/ctype.h>

/* selinuxfs pseudo filesystem for exporting the security policy API.
   Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -751,6 +752,14 @@ out:
	return length;
}

static inline int hexcode_to_int(int code) {
	if (code == '\0' || !isxdigit(code))
		return -1;
	if (isdigit(code))
		return code - '0';
	return tolower(code) - 'a' + 10;
}

static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{
	char *scon = NULL, *tcon = NULL;
@@ -785,8 +794,34 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
	nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
	if (nargs < 3 || nargs > 4)
		goto out;
	if (nargs == 4)
	if (nargs == 4) {
		/*
		 * If and when the name of new object to be queried contains
		 * either whitespace or multibyte characters, they shall be
		 * encoded based on the percentage-encoding rule.
		 * If not encoded, the sscanf logic picks up only left-half
		 * of the supplied name; splitted by a whitespace unexpectedly.
		 */
		char   *r, *w;
		int     c1, c2;

		r = w = namebuf;
		do {
			c1 = *r++;
			if (c1 == '+')
				c1 = ' ';
			else if (c1 == '%') {
				if ((c1 = hexcode_to_int(*r++)) < 0)
					goto out;
				if ((c2 = hexcode_to_int(*r++)) < 0)
					goto out;
				c1 = (c1 << 4) | c2;
			}
			*w++ = c1;
		} while (c1 != '\0');

		objname = namebuf;
	}

	length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
	if (length)