]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selinux: check type attr map overflows
authorChristian Göttsche <cgzones@googlemail.com>
Sun, 11 May 2025 17:30:07 +0000 (19:30 +0200)
committerPaul Moore <paul@paul-moore.com>
Wed, 6 May 2026 23:43:19 +0000 (19:43 -0400)
Validate that no types with an invalid too high ID are present in the
attribute map.  Gaps are still not checked.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: changed name to ebitmap_get_highest_set_bit()]
Signed-off-by: Paul Moore <paul@paul-moore.com>
security/selinux/ss/ebitmap.c
security/selinux/ss/ebitmap.h
security/selinux/ss/policydb.c

index 43bc19e2196098b3fb8ab4d9d9db0667fbf6ee97..ea894361fed644e75a2cc9aa50a374fde0e674bf 100644 (file)
@@ -257,6 +257,33 @@ int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
        return 1;
 }
 
+u32 ebitmap_get_highest_set_bit(const struct ebitmap *e)
+{
+       const struct ebitmap_node *n;
+       unsigned long unit;
+       u32 pos = 0;
+
+       n = e->node;
+       if (!n)
+               return 0;
+
+       while (n->next)
+               n = n->next;
+
+       for (unsigned int i = EBITMAP_UNIT_NUMS; i > 0; i--) {
+               unit = n->maps[i - 1];
+               if (unit == 0)
+                       continue;
+
+               pos = (i - 1) * EBITMAP_UNIT_SIZE;
+               while (unit >>= 1)
+                       pos++;
+               break;
+       }
+
+       return n->startbit + pos;
+}
+
 int ebitmap_get_bit(const struct ebitmap *e, u32 bit)
 {
        const struct ebitmap_node *n;
index c9569998f287d32418cd091e5bcc4e0b5a11fd88..ae05cc8e46721ed5033209c10ee000fe52e34bcb 100644 (file)
@@ -126,6 +126,7 @@ int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1,
                const struct ebitmap *e2);
 int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
                     u32 last_e2bit);
+u32 ebitmap_get_highest_set_bit(const struct ebitmap *e);
 int ebitmap_get_bit(const struct ebitmap *e, u32 bit);
 int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value);
 void ebitmap_destroy(struct ebitmap *e);
index 39065418bed915ceaae066ffc5316bad33e7eb9c..6bb66eda9fc01546eb4589c39f126bba6fba2943 100644 (file)
@@ -2900,6 +2900,11 @@ int policydb_read(struct policydb *p, struct policy_file *fp)
                        if (rc)
                                goto bad;
                }
+
+               rc = -EINVAL;
+               if (ebitmap_get_highest_set_bit(e) >= p->p_types.nprim)
+                       goto bad;
+
                /* add the type itself as the degenerate case */
                rc = ebitmap_set_bit(e, i, 1);
                if (rc)