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

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
...@@ -112,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid, ...@@ -112,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,
int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid); const struct qstr *qstr, u32 *out_sid);
int security_transition_sid_user(u32 ssid, u32 tsid, int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
u16 tclass, u32 *out_sid); const char *objname, u32 *out_sid);
int security_member_sid(u32 ssid, u32 tsid, int security_member_sid(u32 ssid, u32 tsid,
u16 tclass, u32 *out_sid); u16 tclass, u32 *out_sid);
......
...@@ -753,11 +753,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) ...@@ -753,11 +753,13 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
static ssize_t sel_write_create(struct file *file, char *buf, size_t size) static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
{ {
char *scon = NULL, *tcon = NULL; char *scon = NULL, *tcon = NULL;
char *namebuf = NULL, *objname = NULL;
u32 ssid, tsid, newsid; u32 ssid, tsid, newsid;
u16 tclass; u16 tclass;
ssize_t length; ssize_t length;
char *newcon = NULL; char *newcon = NULL;
u32 len; u32 len;
int nargs;
length = task_has_security(current, SECURITY__COMPUTE_CREATE); length = task_has_security(current, SECURITY__COMPUTE_CREATE);
if (length) if (length)
...@@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if (!tcon) if (!tcon)
goto out; goto out;
length = -ENOMEM;
namebuf = kzalloc(size + 1, GFP_KERNEL);
if (!namebuf)
goto out;
length = -EINVAL; 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; goto out;
if (nargs == 4)
objname = namebuf;
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
if (length) if (length)
...@@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
if (length) if (length)
goto out; goto out;
length = security_transition_sid_user(ssid, tsid, tclass, &newsid); length = security_transition_sid_user(ssid, tsid, tclass,
objname, &newsid);
if (length) if (length)
goto out; goto out;
...@@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) ...@@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
length = len; length = len;
out: out:
kfree(newcon); kfree(newcon);
kfree(namebuf);
kfree(tcon); kfree(tcon);
kfree(scon); kfree(scon);
return length; return length;
......
...@@ -1360,14 +1360,14 @@ static int compute_sid_handle_invalid_context( ...@@ -1360,14 +1360,14 @@ static int compute_sid_handle_invalid_context(
static void filename_compute_type(struct policydb *p, struct context *newcontext, static void filename_compute_type(struct policydb *p, struct context *newcontext,
u32 scon, u32 tcon, u16 tclass, u32 scon, u32 tcon, u16 tclass,
const struct qstr *qstr) const char *objname)
{ {
struct filename_trans *ft; struct filename_trans *ft;
for (ft = p->filename_trans; ft; ft = ft->next) { for (ft = p->filename_trans; ft; ft = ft->next) {
if (ft->stype == scon && if (ft->stype == scon &&
ft->ttype == tcon && ft->ttype == tcon &&
ft->tclass == tclass && ft->tclass == tclass &&
!strcmp(ft->name, qstr->name)) { !strcmp(ft->name, objname)) {
newcontext->type = ft->otype; newcontext->type = ft->otype;
return; return;
} }
...@@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid, ...@@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid,
u32 tsid, u32 tsid,
u16 orig_tclass, u16 orig_tclass,
u32 specified, u32 specified,
const struct qstr *qstr, const char *objname,
u32 *out_sid, u32 *out_sid,
bool kern) bool kern)
{ {
...@@ -1479,9 +1479,9 @@ static int security_compute_sid(u32 ssid, ...@@ -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 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, filename_compute_type(&policydb, &newcontext, scontext->type,
tcontext->type, tclass, qstr); tcontext->type, tclass, objname);
/* Check for class-specific changes. */ /* Check for class-specific changes. */
if (specified & AVTAB_TRANSITION) { if (specified & AVTAB_TRANSITION) {
...@@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, ...@@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
const struct qstr *qstr, u32 *out_sid) const struct qstr *qstr, u32 *out_sid)
{ {
return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 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, return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
NULL, out_sid, false); objname, out_sid, false);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment