History

selinux: reject a permission value exceeding the class permission count

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.

Bryam Vargas committed 3 months ago

Commit d14b5d01 parent f5098b61 file · +3 −0Browse files

Showing the changes to security (1 of 1 file). Show all

Unified · Split

security/selinux/ss/policydb.c+3−0
@@ -1175,6 +1175,9 @@ static int perm_read(struct policydb *p, struct symtab *s, struct policy_file *f · 1174 unmodified lines
1175 rc = -EINVAL;1175 rc = -EINVAL;
1176 if (perdatum->value < 1 || perdatum->value > SEL_VEC_MAX)1176 if (perdatum->value < 1 || perdatum->value > SEL_VEC_MAX)
1177 goto bad;1177 goto bad;
1178 /* indexes an nprim-sized array in security_get_permissions() */
1179 if (perdatum->value > s->nprim)
1180 goto bad;
1178 1181
1179 rc = str_read(&key, GFP_KERNEL, fp, len);1182 rc = str_read(&key, GFP_KERNEL, fp, len);
1180 if (rc)1183 if (rc)