Merge branch 'x86/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[pandora-kernel.git] / security / selinux / ss / services.c
index 543fd0f..8e42da1 100644 (file)
@@ -407,9 +407,19 @@ static int context_struct_compute_av(struct context *scontext,
        return 0;
 
 inval_class:
-       printk(KERN_ERR "SELinux: %s:  unrecognized class %d\n", __func__,
-               tclass);
-       return -EINVAL;
+       if (!tclass || tclass > kdefs->cts_len ||
+           !kdefs->class_to_string[tclass]) {
+               if (printk_ratelimit())
+                       printk(KERN_ERR "SELinux: %s:  unrecognized class %d\n",
+                              __func__, tclass);
+               return -EINVAL;
+       }
+
+       /*
+        * Known to the kernel, but not to the policy.
+        * Handle as a denial (allowed is 0).
+        */
+       return 0;
 }
 
 /*
@@ -1161,6 +1171,7 @@ static int validate_classes(struct policydb *p)
        const struct selinux_class_perm *kdefs = &selinux_class_perm;
        const char *def_class, *def_perm, *pol_class;
        struct symtab *perms;
+       bool print_unknown_handle = 0;
 
        if (p->allow_unknown) {
                u32 num_classes = kdefs->cts_len;
@@ -1181,6 +1192,7 @@ static int validate_classes(struct policydb *p)
                                return -EINVAL;
                        if (p->allow_unknown)
                                p->undefined_perms[i-1] = ~0U;
+                       print_unknown_handle = 1;
                        continue;
                }
                pol_class = p->p_class_val_to_name[i-1];
@@ -1210,6 +1222,7 @@ static int validate_classes(struct policydb *p)
                                return -EINVAL;
                        if (p->allow_unknown)
                                p->undefined_perms[class_val-1] |= perm_val;
+                       print_unknown_handle = 1;
                        continue;
                }
                perdatum = hashtab_search(perms->table, def_perm);
@@ -1257,6 +1270,7 @@ static int validate_classes(struct policydb *p)
                                        return -EINVAL;
                                if (p->allow_unknown)
                                        p->undefined_perms[class_val-1] |= (1 << j);
+                               print_unknown_handle = 1;
                                continue;
                        }
                        perdatum = hashtab_search(perms->table, def_perm);
@@ -1274,6 +1288,9 @@ static int validate_classes(struct policydb *p)
                        }
                }
        }
+       if (print_unknown_handle)
+               printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
+                       (security_get_allow_unknown() ? "allowed" : "denied"));
        return 0;
 }
 
@@ -1917,7 +1934,8 @@ out:
 int security_fs_use(
        const char *fstype,
        unsigned int *behavior,
-       u32 *sid)
+       u32 *sid,
+       bool can_xattr)
 {
        int rc = 0;
        struct ocontext *c;
@@ -1931,6 +1949,7 @@ int security_fs_use(
                c = c->next;
        }
 
+       /* look for labeling behavior defined in policy */
        if (c) {
                *behavior = c->v.behavior;
                if (!c->sid[0]) {
@@ -1941,14 +1960,23 @@ int security_fs_use(
                                goto out;
                }
                *sid = c->sid[0];
+               goto out;
+       }
+
+       /* labeling behavior not in policy, use xattrs if possible */
+       if (can_xattr) {
+               *behavior = SECURITY_FS_USE_XATTR;
+               *sid = SECINITSID_FS;
+               goto out;
+       }
+
+       /* no behavior in policy and can't use xattrs, try GENFS */
+       rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
+       if (rc) {
+               *behavior = SECURITY_FS_USE_NONE;
+               rc = 0;
        } else {
-               rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
-               if (rc) {
-                       *behavior = SECURITY_FS_USE_NONE;
-                       rc = 0;
-               } else {
-                       *behavior = SECURITY_FS_USE_GENFS;
-               }
+               *behavior = SECURITY_FS_USE_GENFS;
        }
 
 out: