aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 bfc5218d584..2cf67086414 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,
112int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, 112int 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
115int security_transition_sid_user(u32 ssid, u32 tsid, 115int 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
118int security_member_sid(u32 ssid, u32 tsid, 118int 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 ea39cb742ae..973f5a4a6fc 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -753,11 +753,13 @@ out:
753static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 753static 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;
805out: 816out:
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 03f7a4748ee..39d732145ab 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1360,14 +1360,14 @@ out:
1360 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext, 1361static 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
1545int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) 1545int 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/**