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>
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 03f7a47..39d7321 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1360,14 +1360,14 @@
 
 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 @@
 				u32 tsid,
 				u16 orig_tclass,
 				u32 specified,
-				const struct qstr *qstr,
+				const char *objname,
 				u32 *out_sid,
 				bool kern)
 {
@@ -1479,9 +1479,9 @@
 	}
 
 	/* 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 @@
 			    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);
 }
 
 /**