selinux: check for simple types

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>
This commit is contained in:
Christian Göttsche 2025-05-11 19:30:12 +02:00 committed by Paul Moore
parent 3e6420d8d3
commit 2f0af91353
3 changed files with 29 additions and 2 deletions

View 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;
}

View 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;

View 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);