aboutsummaryrefslogtreecommitdiff
path: root/security/selinux
diff options
context:
space:
mode:
authorKohei Kaigai <Kohei.Kaigai@eu.nec.com>2011-04-01 15:39:26 +0100
committerEric Paris <eparis@redhat.com>2011-04-01 17:13:23 -0400
commitf50a3ec961f90e38c0311411179d5dfee1412192 (patch)
tree600b7909964cd116af1252ecabb5b1415c01d7a0 /security/selinux
parent6bde95ce33e1c2ac9b5cb3d814722105131090ec (diff)
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>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/include/security.h4
-rw-r--r--security/selinux/selinuxfs.c16
-rw-r--r--security/selinux/ss/services.c17
3 files changed, 25 insertions, 12 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index bfc5218d5840..2cf670864147 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -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);
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index ea39cb742ae5..973f5a4a6fce 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -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;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 03f7a4748ee8..39d732145abe 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -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);
}
/**