selinux: change the handling of unknown classes

If allow_unknown==deny, SELinux treats an undefined kernel security
class as an error condition rather than as a typical permission denial
and thus does not allow permissions on undefined classes even when in
permissive mode.  Change the SELinux logic so that this case is handled
as a typical permission denial, subject to the usual permissive mode and
permissive domain handling.

Also drop the 'requested' argument from security_compute_av() and
helpers as it is a legacy of the original security server interface and
is unused.

Changes:
- Handle permissive domains consistently by moving up the test for a
permissive domain.
- Make security_compute_av_user() consistent with security_compute_av();
the only difference now is that security_compute_av() performs mapping
between the kernel-private class and permission indices and the policy
values.  In the userspace case, this mapping is handled by libselinux.
- Moved avd_init inside the policy lock.

Based in part on a patch by Paul Moore <paul.moore@hp.com>.

Reported-by: Andrew Worsley <amworsley@gmail.com>
Signed-off-by:  Stephen D. Smalley <sds@tycho.nsa.gov>
Reviewed-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index fab36fd..b7bb0f5 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -494,7 +494,6 @@
 	char *scon, *tcon;
 	u32 ssid, tsid;
 	u16 tclass;
-	u32 req;
 	struct av_decision avd;
 	ssize_t length;
 
@@ -512,7 +511,7 @@
 		goto out;
 
 	length = -EINVAL;
-	if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4)
+	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
 		goto out2;
 
 	length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
@@ -522,9 +521,7 @@
 	if (length < 0)
 		goto out2;
 
-	length = security_compute_av_user(ssid, tsid, tclass, req, &avd);
-	if (length < 0)
-		goto out2;
+	security_compute_av_user(ssid, tsid, tclass, &avd);
 
 	length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
 			  "%x %x %x %x %u %x",