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

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

selinux: add type_transition with name extension support for selinuxfs



The attached patch allows /selinux/create takes optional 4th argument
to support TYPE_TRANSITION with name extension for userspace object
managers.
If 4th argument is not supplied, it shall perform as existing kernel.
In fact, the regression test of SE-PostgreSQL works well on the patched
kernel.

Thanks,

Signed-off-by: default avatarKaiGai Kohei <kohei.kaigai@eu.nec.com>
[manually verify fuzz was not an issue, and it wasn't: eparis]
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent 6bde95ce
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -112,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
			    const struct qstr *qstr, u32 *out_sid);

int security_transition_sid_user(u32 ssid, u32 tsid,
				 u16 tclass, u32 *out_sid);
int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
				 const char *objname, u32 *out_sid);

int security_member_sid(u32 ssid, u32 tsid,
	u16 tclass, u32 *out_sid);
+14 −2
Original line number Diff line number Diff line
@@ -753,11 +753,13 @@ out:
static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{
	char *scon = NULL, *tcon = NULL;
	char *namebuf = NULL, *objname = NULL;
	u32 ssid, tsid, newsid;
	u16 tclass;
	ssize_t length;
	char *newcon = NULL;
	u32 len;
	int nargs;

	length = task_has_security(current, SECURITY__COMPUTE_CREATE);
	if (length)
@@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
	if (!tcon)
		goto out;

	length = -ENOMEM;
	namebuf = kzalloc(size + 1, GFP_KERNEL);
	if (!namebuf)
		goto out;

	length = -EINVAL;
	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
	nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
	if (nargs < 3 || nargs > 4)
		goto out;
	if (nargs == 4)
		objname = namebuf;

	length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
	if (length)
@@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
	if (length)
		goto out;

	length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
	length = security_transition_sid_user(ssid, tsid, tclass,
					      objname, &newsid);
	if (length)
		goto out;

@@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
	length = len;
out:
	kfree(newcon);
	kfree(namebuf);
	kfree(tcon);
	kfree(scon);
	return length;
+9 −8
Original line number Diff line number Diff line
@@ -1360,14 +1360,14 @@ out:

static void filename_compute_type(struct policydb *p, struct context *newcontext,
				  u32 scon, u32 tcon, u16 tclass,
				  const struct qstr *qstr)
				  const char *objname)
{
	struct filename_trans *ft;
	for (ft = p->filename_trans; ft; ft = ft->next) {
		if (ft->stype == scon &&
		    ft->ttype == tcon &&
		    ft->tclass == tclass &&
		    !strcmp(ft->name, qstr->name)) {
		    !strcmp(ft->name, objname)) {
			newcontext->type = ft->otype;
			return;
		}
@@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid,
				u32 tsid,
				u16 orig_tclass,
				u32 specified,
				const struct qstr *qstr,
				const char *objname,
				u32 *out_sid,
				bool kern)
{
@@ -1479,9 +1479,9 @@ static int security_compute_sid(u32 ssid,
	}

	/* if we have a qstr this is a file trans check so check those rules */
	if (qstr)
	if (objname)
		filename_compute_type(&policydb, &newcontext, scontext->type,
				      tcontext->type, tclass, qstr);
				      tcontext->type, tclass, objname);

	/* Check for class-specific changes. */
	if (specified & AVTAB_TRANSITION) {
@@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
			    const struct qstr *qstr, u32 *out_sid)
{
	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
				    qstr, out_sid, true);
				    qstr ? qstr->name : NULL, out_sid, true);
}

int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid)
int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
				 const char *objname, u32 *out_sid)
{
	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
				    NULL, out_sid, false);
				    objname, out_sid, false);
}

/**