diff options
author | Kohei Kaigai <Kohei.Kaigai@eu.nec.com> | 2011-04-01 10:39:26 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2011-04-01 17:13:23 -0400 |
commit | f50a3ec961f90e38c0311411179d5dfee1412192 (patch) | |
tree | 600b7909964cd116af1252ecabb5b1415c01d7a0 /security | |
parent | 6bde95ce33e1c2ac9b5cb3d814722105131090ec (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')
-rw-r--r-- | security/selinux/include/security.h | 4 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 16 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 17 |
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, | |||
112 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, | 112 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, |
113 | const struct qstr *qstr, u32 *out_sid); | 113 | const struct qstr *qstr, u32 *out_sid); |
114 | 114 | ||
115 | int security_transition_sid_user(u32 ssid, u32 tsid, | 115 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, |
116 | u16 tclass, u32 *out_sid); | 116 | const char *objname, u32 *out_sid); |
117 | 117 | ||
118 | int security_member_sid(u32 ssid, u32 tsid, | 118 | int security_member_sid(u32 ssid, u32 tsid, |
119 | u16 tclass, u32 *out_sid); | 119 | 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: | |||
753 | static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | 753 | static ssize_t sel_write_create(struct file *file, char *buf, size_t size) |
754 | { | 754 | { |
755 | char *scon = NULL, *tcon = NULL; | 755 | char *scon = NULL, *tcon = NULL; |
756 | char *namebuf = NULL, *objname = NULL; | ||
756 | u32 ssid, tsid, newsid; | 757 | u32 ssid, tsid, newsid; |
757 | u16 tclass; | 758 | u16 tclass; |
758 | ssize_t length; | 759 | ssize_t length; |
759 | char *newcon = NULL; | 760 | char *newcon = NULL; |
760 | u32 len; | 761 | u32 len; |
762 | int nargs; | ||
761 | 763 | ||
762 | length = task_has_security(current, SECURITY__COMPUTE_CREATE); | 764 | length = task_has_security(current, SECURITY__COMPUTE_CREATE); |
763 | if (length) | 765 | if (length) |
@@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
773 | if (!tcon) | 775 | if (!tcon) |
774 | goto out; | 776 | goto out; |
775 | 777 | ||
778 | length = -ENOMEM; | ||
779 | namebuf = kzalloc(size + 1, GFP_KERNEL); | ||
780 | if (!namebuf) | ||
781 | goto out; | ||
782 | |||
776 | length = -EINVAL; | 783 | length = -EINVAL; |
777 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 784 | nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf); |
785 | if (nargs < 3 || nargs > 4) | ||
778 | goto out; | 786 | goto out; |
787 | if (nargs == 4) | ||
788 | objname = namebuf; | ||
779 | 789 | ||
780 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 790 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); |
781 | if (length) | 791 | if (length) |
@@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
785 | if (length) | 795 | if (length) |
786 | goto out; | 796 | goto out; |
787 | 797 | ||
788 | length = security_transition_sid_user(ssid, tsid, tclass, &newsid); | 798 | length = security_transition_sid_user(ssid, tsid, tclass, |
799 | objname, &newsid); | ||
789 | if (length) | 800 | if (length) |
790 | goto out; | 801 | goto out; |
791 | 802 | ||
@@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
804 | length = len; | 815 | length = len; |
805 | out: | 816 | out: |
806 | kfree(newcon); | 817 | kfree(newcon); |
818 | kfree(namebuf); | ||
807 | kfree(tcon); | 819 | kfree(tcon); |
808 | kfree(scon); | 820 | kfree(scon); |
809 | return length; | 821 | 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: | |||
1360 | 1360 | ||
1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | 1361 | static void filename_compute_type(struct policydb *p, struct context *newcontext, |
1362 | u32 scon, u32 tcon, u16 tclass, | 1362 | u32 scon, u32 tcon, u16 tclass, |
1363 | const struct qstr *qstr) | 1363 | const char *objname) |
1364 | { | 1364 | { |
1365 | struct filename_trans *ft; | 1365 | struct filename_trans *ft; |
1366 | for (ft = p->filename_trans; ft; ft = ft->next) { | 1366 | for (ft = p->filename_trans; ft; ft = ft->next) { |
1367 | if (ft->stype == scon && | 1367 | if (ft->stype == scon && |
1368 | ft->ttype == tcon && | 1368 | ft->ttype == tcon && |
1369 | ft->tclass == tclass && | 1369 | ft->tclass == tclass && |
1370 | !strcmp(ft->name, qstr->name)) { | 1370 | !strcmp(ft->name, objname)) { |
1371 | newcontext->type = ft->otype; | 1371 | newcontext->type = ft->otype; |
1372 | return; | 1372 | return; |
1373 | } | 1373 | } |
@@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid, | |||
1378 | u32 tsid, | 1378 | u32 tsid, |
1379 | u16 orig_tclass, | 1379 | u16 orig_tclass, |
1380 | u32 specified, | 1380 | u32 specified, |
1381 | const struct qstr *qstr, | 1381 | const char *objname, |
1382 | u32 *out_sid, | 1382 | u32 *out_sid, |
1383 | bool kern) | 1383 | bool kern) |
1384 | { | 1384 | { |
@@ -1479,9 +1479,9 @@ static int security_compute_sid(u32 ssid, | |||
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | /* if we have a qstr this is a file trans check so check those rules */ | 1481 | /* if we have a qstr this is a file trans check so check those rules */ |
1482 | if (qstr) | 1482 | if (objname) |
1483 | filename_compute_type(&policydb, &newcontext, scontext->type, | 1483 | filename_compute_type(&policydb, &newcontext, scontext->type, |
1484 | tcontext->type, tclass, qstr); | 1484 | tcontext->type, tclass, objname); |
1485 | 1485 | ||
1486 | /* Check for class-specific changes. */ | 1486 | /* Check for class-specific changes. */ |
1487 | if (specified & AVTAB_TRANSITION) { | 1487 | if (specified & AVTAB_TRANSITION) { |
@@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, | |||
1539 | const struct qstr *qstr, u32 *out_sid) | 1539 | const struct qstr *qstr, u32 *out_sid) |
1540 | { | 1540 | { |
1541 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1541 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1542 | qstr, out_sid, true); | 1542 | qstr ? qstr->name : NULL, out_sid, true); |
1543 | } | 1543 | } |
1544 | 1544 | ||
1545 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) | 1545 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, |
1546 | const char *objname, u32 *out_sid) | ||
1546 | { | 1547 | { |
1547 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1548 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, |
1548 | NULL, out_sid, false); | 1549 | objname, out_sid, false); |
1549 | } | 1550 | } |
1550 | 1551 | ||
1551 | /** | 1552 | /** |