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: KaiGai Kohei <kohei.kaigai@eu.nec.com> [manually verify fuzz was not an issue, and it wasn't: eparis] Signed-off-by: Eric Paris <eparis@redhat.com>
This commit is contained in:
@@ -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 @@ out:
|
|||||||
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,10 +775,18 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
|
|||||||
if (!tcon)
|
if (!tcon)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
length = -EINVAL;
|
length = -ENOMEM;
|
||||||
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
|
namebuf = kzalloc(size + 1, GFP_KERNEL);
|
||||||
|
if (!namebuf)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
length = -EINVAL;
|
||||||
|
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);
|
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
|
||||||
if (length)
|
if (length)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -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)
|
|||||||
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 @@ out:
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user