diff options
| author | Christian Göttsche <cgzones@googlemail.com> | 2026-09-03 13:35:38 +0200 |
|---|---|---|
| committer | Paul Moore <paul@paul-moore.com> | 2026-09-24 17:30:18 -0400 |
| commit | 641bd5750517d2e5c128c566669c190857260693 (patch) | |
| tree | 13403804cf533b16e3f0c4147f5a813a0bb5f6f1 | |
| parent | 508d1fcc2d099e1e8d9b6fc14cb150adb8c4b092 (diff) | |
| download | linux-641bd5750517d2e5c128c566669c190857260693.tar.gz linux-641bd5750517d2e5c128c566669c190857260693.zip | |
selinux: reject duplicate symbol values during policy load
The symbol index functions assign unconditionally, so two symbols that
share a value silently overwrite each other and leave another value with
no entry.
Reject a value whose slot is already populated, for commons, classes,
roles, types, users, sensitivities and categories;
booleans already have their own "declared but not defined" check.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
| -rw-r--r-- | security/selinux/ss/policydb.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 7eeaf7076c52..6119df551f23 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -560,6 +560,9 @@ static int common_index(void *key, void *datum, void *datap) if (!comdatum->value || comdatum->value > p->p_commons.nprim) return -EINVAL; + if (p->sym_val_to_name[SYM_COMMONS][comdatum->value - 1]) + return -EINVAL; + p->sym_val_to_name[SYM_COMMONS][comdatum->value - 1] = key; return 0; @@ -575,6 +578,9 @@ static int class_index(void *key, void *datum, void *datap) if (!cladatum->value || cladatum->value > p->p_classes.nprim) return -EINVAL; + if (p->class_val_to_struct[cladatum->value - 1]) + return -EINVAL; + p->sym_val_to_name[SYM_CLASSES][cladatum->value - 1] = key; p->class_val_to_struct[cladatum->value - 1] = cladatum; return 0; @@ -591,6 +597,9 @@ static int role_index(void *key, void *datum, void *datap) role->bounds > p->p_roles.nprim) return -EINVAL; + if (p->role_val_to_struct[role->value - 1]) + return -EINVAL; + p->sym_val_to_name[SYM_ROLES][role->value - 1] = key; p->role_val_to_struct[role->value - 1] = role; return 0; @@ -613,6 +622,8 @@ static int type_index(void *key, void *datum, void *datap) } if (typdatum->primary) { + if (p->type_val_to_struct[typdatum->value - 1]) + return -EINVAL; p->sym_val_to_name[SYM_TYPES][typdatum->value - 1] = key; p->type_val_to_struct[typdatum->value - 1] = typdatum; } @@ -631,6 +642,9 @@ static int user_index(void *key, void *datum, void *datap) usrdatum->bounds > p->p_users.nprim) return -EINVAL; + if (p->user_val_to_struct[usrdatum->value - 1]) + return -EINVAL; + p->sym_val_to_name[SYM_USERS][usrdatum->value - 1] = key; p->user_val_to_struct[usrdatum->value - 1] = usrdatum; return 0; @@ -647,8 +661,11 @@ static int sens_index(void *key, void *datum, void *datap) if (!levdatum->level.sens || levdatum->level.sens > p->p_levels.nprim) return -EINVAL; - if (!levdatum->isalias) + if (!levdatum->isalias) { + if (p->sym_val_to_name[SYM_LEVELS][levdatum->level.sens - 1]) + return -EINVAL; p->sym_val_to_name[SYM_LEVELS][levdatum->level.sens - 1] = key; + } return 0; } @@ -664,8 +681,11 @@ static int cat_index(void *key, void *datum, void *datap) if (!catdatum->value || catdatum->value > p->p_cats.nprim) return -EINVAL; - if (!catdatum->isalias) + if (!catdatum->isalias) { + if (p->sym_val_to_name[SYM_CATS][catdatum->value - 1]) + return -EINVAL; p->sym_val_to_name[SYM_CATS][catdatum->value - 1] = key; + } return 0; } |
