[PATCH] libsepol: Check for zero when mapping identifier values
James Carter <[email protected]> Fri, 31 Jul 2026 13:51:23 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <[email protected]> |
When expanding a base along with its modules, the identifier values of declarations are mapped from their values in the module to their values in the kernel policy. A maliciously crafted policy could create a situation where there is no mapping. This would leave the new identifier value as zero. Identifier values must start at 1 because "value - 1" is used to reference zero-based arrays. Signed-off-by: James Carter <[email protected]> --- libsepol/src/expand.c | 76 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 1ef0fb39..8cb62d82 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -646,6 +646,10 @@ static int type_bounds_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return 0; bounds_val = state->typemap[type->bounds - 1]; + if (!bounds_val) { + ERR(state->handle, "No type mapping for %s", (char *)key); + return -1; + } dest = hashtab_search(state->out->p_types.table, (char *)key); if (!dest) { @@ -676,6 +680,10 @@ static int role_bounds_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return 0; bounds_val = state->rolemap[role->bounds - 1]; + if (!bounds_val) { + ERR(state->handle, "No role mapping for %s", (char *)key); + return -1; + } dest = hashtab_search(state->out->p_roles.table, (char *)key); if (!dest) { @@ -706,6 +714,10 @@ static int user_bounds_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return 0; bounds_val = state->usermap[user->bounds - 1]; + if (!bounds_val) { + ERR(state->handle, "No user mapping for %s", (char *)key); + return -1; + } dest = hashtab_search(state->out->p_users.table, (char *)key); if (!dest) { @@ -782,6 +794,13 @@ static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, else assert(0); /* unreachable */ + if (!new_alias->s.value) { + ERR(state->handle, "No type mapping for %s", new_id); + free(new_alias); + free(new_id); + return -1; + } + new_alias->flags = alias->flags; ret = hashtab_insert(state->out->p_types.table, (hashtab_key_t)new_id, @@ -1559,6 +1578,11 @@ static int copy_role_trans(expand_state_t *state, role_trans_rule_t *rules) state->rolemap [cur->new_role - 1]; + if (!mapped_role) { + ERR(state->handle, + "No role mapping"); + return -1; + } if ((cur_trans->role == i + 1) && @@ -1607,6 +1631,11 @@ static int copy_role_trans(expand_state_t *state, role_trans_rule_t *rules) n->new_role = state->rolemap[cur->new_role - 1]; + if (!n->new_role) { + ERR(state->handle, + "No role mapping"); + return -1; + } if (l) l->next = n; else @@ -1633,6 +1662,10 @@ static int expand_filename_trans_helper(expand_state_t *state, int rc; mapped_otype = state->typemap[rule->otype - 1]; + if (!mapped_otype) { + ERR(state->handle, "No type mapping"); + return -1; + } rc = policydb_filetrans_insert(state->out, s + 1, t + 1, rule->tclass, rule->name, NULL, mapped_otype, @@ -1940,8 +1973,18 @@ static int expand_terule_helper(sepol_handle_t *handle, policydb_t *p, cur = perms; while (cur) { - uint32_t remapped_data = typemap ? typemap[cur->data - 1] : - cur->data; + uint32_t remapped_data; + + if (typemap) { + remapped_data = typemap[cur->data - 1]; + if (!remapped_data) { + ERR(handle, "No type mapping"); + return -1; + } + } else { + remapped_data = cur->data; + } + avkey.target_class = cur->tclass; conflict = 0; @@ -2245,13 +2288,23 @@ static int cond_node_map_bools(expand_state_t *state, cond_node_t *cn) cur = cn->expr; while (cur) { - if (cur->boolean) + if (cur->boolean) { cur->boolean = state->boolmap[cur->boolean - 1]; + if (!cur->boolean) { + ERR(state->handle, "No bool mapping"); + return -1; + } + } cur = cur->next; } - for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) + for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) { cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; + if (!cn->bool_ids[i]) { + ERR(state->handle, "No bool mapping"); + return -1; + } + } if (cond_normalize_expr(state->out, cn)) { ERR(state->handle, "Error while normalizing conditional"); @@ -2329,8 +2382,23 @@ static int context_copy(context_struct_t *dst, context_struct_t *src, expand_state_t *state) { dst->user = state->usermap[src->user - 1]; + if (!dst->user) { + ERR(state->handle, "No user mapping"); + return -1; + } + dst->role = state->rolemap[src->role - 1]; + if (!dst->role) { + ERR(state->handle, "No role mapping"); + return -1; + } + dst->type = state->typemap[src->type - 1]; + if (!dst->type) { + ERR(state->handle, "No type mapping"); + return -1; + } + return mls_context_cpy(dst, src); } -- 2.55.0