[PATCH v2 1/2] selinux: reject a permission value exceeding the class permission count

From: Bryam Vargas via B4 Relay

Date: Mon Jul 27 2026 - 21:31:40 EST


From: Bryam Vargas <hexlabsecurity@xxxxxxxxx>

perm_read() bounds a permission value by SEL_VEC_MAX but never by the
nprim of the owning class or common, which is taken verbatim from the
policy image. security_get_permissions() then writes perms[value - 1]
into an nprim-sized kcalloc() array, so a class declaring fewer
permissions than its largest permission value drives an out-of-bounds
heap write. The top-level symbol tables are validated this way; the
nested per-class permission table is not.

Reject a permission whose value exceeds nprim, which is already set when
perm_read() runs. Well-formed policies are unaffected.

Fixes: 55fcf09b3fe4 ("selinux: add support for querying object classes and permissions from the running policy")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Bryam Vargas <hexlabsecurity@xxxxxxxxx>
Acked-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx>
---
security/selinux/ss/policydb.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index ead504a639e3..6973b68d9782 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -1175,6 +1175,9 @@ static int perm_read(struct policydb *p, struct symtab *s, struct policy_file *f
rc = -EINVAL;
if (perdatum->value < 1 || perdatum->value > SEL_VEC_MAX)
goto bad;
+ /* the value indexes an nprim-sized array in security_get_permissions() */
+ if (perdatum->value > s->nprim)
+ goto bad;

rc = str_read(&key, GFP_KERNEL, fp, len);
if (rc)

--
2.55.0