]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selinux: check for simple types
authorChristian Göttsche <cgzones@googlemail.com>
Sun, 11 May 2025 17:30:12 +0000 (19:30 +0200)
committerPaul Moore <paul@paul-moore.com>
Wed, 6 May 2026 23:43:22 +0000 (19:43 -0400)
Validate that the target of AVTAB_TYPE rules and file transitions are
simple types and not attributes.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: merge fuzz, dropped parts due to dependencies]
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/ss/avtab.c
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h

index b708e2c9acdda80b7b674dfef2718df506905920..0f94edd01f696e39fc8856ced57722bb61a0a678 100644 (file)
@@ -393,6 +393,13 @@ int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *po
                                }
                                key.specified = spec_order[i] | enabled;
                                datum.u.data = le32_to_cpu(buf32[items++]);
+
+                               if ((key.specified & AVTAB_TYPE) &&
+                                   !policydb_simpletype_isvalid(pol, datum.u.data)) {
+                                       pr_err("SELinux: avtab: invalid type\n");
+                                       return -EINVAL;
+                               }
+
                                rc = insertf(a, &key, &datum, p);
                                if (rc)
                                        return rc;
@@ -484,7 +491,7 @@ int avtab_read_item(struct avtab *a, struct policy_file *fp, struct policydb *po
                datum.u.data = le32_to_cpu(*buf32);
        }
        if ((key.specified & AVTAB_TYPE) &&
-           !policydb_type_isvalid(pol, datum.u.data)) {
+           !policydb_simpletype_isvalid(pol, datum.u.data)) {
                pr_err("SELinux: avtab: invalid type\n");
                return -EINVAL;
        }
index 5c7fec936d2992970a241da0db02c4adb3eb391c..ead504a639e363d6ba123b615c27ecc11da610d9 100644 (file)
@@ -964,6 +964,23 @@ bool policydb_type_isvalid(const struct policydb *p, u32 type)
        return true;
 }
 
+bool policydb_simpletype_isvalid(const struct policydb *p, u32 type)
+{
+       const struct type_datum *datum;
+
+       if (!type || type > p->p_types.nprim)
+               return false;
+
+       datum = p->type_val_to_struct[type - 1];
+       if (!datum)
+               return false;
+
+       if (datum->attribute)
+               return false;
+
+       return true;
+}
+
 /*
  * Return true if the fields in the security context
  * structure `c' are valid.  Return 0 otherwise.
@@ -2078,6 +2095,8 @@ static int filename_trans_read_helper_compat(struct policydb *p, struct policy_f
        key.name = name;
 
        otype = le32_to_cpu(buf[3]);
+       if (!policydb_simpletype_isvalid(p, otype))
+               goto out;
 
        last = NULL;
        datum = policydb_filenametr_search(p, &key);
@@ -2200,7 +2219,7 @@ static int filename_trans_read_helper(struct policydb *p, struct policy_file *fp
                datum->otype = le32_to_cpu(buf[0]);
 
                rc = -EINVAL;
-               if (!policydb_type_isvalid(p, datum->otype))
+               if (!policydb_simpletype_isvalid(p, datum->otype))
                        goto out;
 
                dst = &datum->next;
index b1a64c23e1dcd7bde89faa31094be2bf0542e098..974180b2e3a35fe8de92542a6e5d53449660799a 100644 (file)
@@ -326,6 +326,7 @@ extern bool policydb_context_isvalid(const struct policydb *p,
                                     const struct context *c);
 extern bool policydb_class_isvalid(const struct policydb *p, u16 class);
 extern bool policydb_type_isvalid(const struct policydb *p, u32 type);
+extern bool policydb_simpletype_isvalid(const struct policydb *p, u32 type);
 extern bool policydb_role_isvalid(const struct policydb *p, u32 role);
 extern bool policydb_user_isvalid(const struct policydb *p, u32 user);
 extern int policydb_read(struct policydb *p, struct policy_file *fp);