For policy versions between 20 and 23, attributes exist in the policy, but only in the type_attr_map. This means that there are gaps in both the type_val_to_struct and p_type_val_to_name arrays and policy rules can refer to those gaps which can lead to NULL dereferences when using sepol_kernel_policydb_to_conf() and sepol_kernel_policydb_to_cil(). This can be seen with the following policy: class CLASS1 sid SID1 class CLASS1 { PERM1 } attribute TYPE_ATTR1; type TYPE1; typeattribute TYPE1 TYPE_ATTR1; allow TYPE_ATTR1 self : CLASS1 PERM1; role ROLE1; role ROLE1 types TYPE1; user USER1 roles ROLE1; sid SID1 USER1:ROLE1:TYPE1 Compile the policy: checkpolicy -c 23 -o policy.bin policy.conf Converting back to a policy.conf causes a segfault: checkpolicy -F -b -o policy.bin.conf policy.bin Have both sepol_kernel_policydb_to_conf() and sepol_kernel_policydb_to_cil() exit with an error if the kernel policy version is between 20 and 23. Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- libsepol/src/kernel_to_cil.c | 12 ++++++++++++ libsepol/src/kernel_to_conf.c | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index a146ac51..edfebeaf 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -3164,6 +3164,18 @@ int sepol_kernel_policydb_to_cil(FILE *out, struct policydb *pdb) goto exit; } + if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map. This means that there are gaps in both + * the type_val_to_struct and p_type_val_to_name arrays and policy rules + * can refer to those gaps. + */ + sepol_log_err("Writing policy versions between 20 and 23 as CIL is not supported"); + rc = -1; + goto exit; + } + rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); if (rc != 0) { goto exit; diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c index a22f196d..ea58a026 100644 --- a/libsepol/src/kernel_to_conf.c +++ b/libsepol/src/kernel_to_conf.c @@ -3041,6 +3041,18 @@ int sepol_kernel_policydb_to_conf(FILE *out, struct policydb *pdb) goto exit; } + if (pdb->policyvers >= POLICYDB_VERSION_AVTAB && pdb->policyvers <= POLICYDB_VERSION_PERMISSIVE) { + /* + * For policy versions between 20 and 23, attributes exist in the policy, + * but only in the type_attr_map. This means that there are gaps in both + * the type_val_to_struct and p_type_val_to_name arrays and policy rules + * can refer to those gaps. + */ + sepol_log_err("Writing policy versions between 20 and 23 as a policy.conf is not supported"); + rc = -1; + goto exit; + } + rc = constraint_rules_to_strs(pdb, mls_constraints, non_mls_constraints); if (rc != 0) { goto exit; -- 2.26.2