Handle gaps in the class table while printing a policy configuration. ==21763==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000028 (pc 0x00000055b696 bp 0x7ffe69e8ab50 sp 0x7ffe69e8aa60 T0) ==21763==The signal is caused by a READ memory access. ==21763==Hint: address points to the zero page. #0 0x55b696 in constraint_rules_to_strs ./libsepol/src/kernel_to_conf.c:361:14 #1 0x55ac80 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3063:7 #2 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9 #3 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o #4 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o #5 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o #6 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2) #7 0x7fc60d39e7ec in __libc_start_main csu/../csu/libc-start.c:332:16 #8 0x423689 in _start (./out/binpolicy-fuzzer+0x423689) Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- libsepol/src/kernel_to_cil.c | 9 +++++++++ libsepol/src/kernel_to_conf.c | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index b81cdb22..d9afdda6 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -358,6 +358,7 @@ static int constraint_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->constraints) { name = pdb->p_class_val_to_name[i]; rc = class_constraint_rules_to_strs(pdb, name, class, class->constraints, mls_strs, non_mls_strs); @@ -383,6 +384,7 @@ static int validatetrans_rules_to_strs(struct policydb *pdb, struct strs *mls_st for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->validatetrans) { name = pdb->p_class_val_to_name[i]; rc = class_validatetrans_rules_to_strs(pdb, name, class->validatetrans, mls_strs, non_mls_strs); @@ -461,6 +463,7 @@ static int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb) /* class */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; name = pdb->p_class_val_to_name[i]; perms = class_or_common_perms_to_str(&class->permissions); if (perms) { @@ -488,6 +491,7 @@ static int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb) /* classcommon */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; name = pdb->p_class_val_to_name[i]; if (class->comkey != NULL) { sepol_printf(out, "(classcommon %s %s)\n", name, class->comkey); @@ -503,6 +507,7 @@ static int write_class_decl_rules_to_cil(FILE *out, struct policydb *pdb) } for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; name = class->comkey; if (name != NULL) { common = hashtab_search(pdb->p_commons.table, name); @@ -727,6 +732,7 @@ static int write_default_rules_to_cil(FILE *out, struct policydb *pdb) /* default_user */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_user != 0) { rc = write_default_user_to_cil(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -738,6 +744,7 @@ static int write_default_rules_to_cil(FILE *out, struct policydb *pdb) /* default_role */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_role != 0) { rc = write_default_role_to_cil(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -749,6 +756,7 @@ static int write_default_rules_to_cil(FILE *out, struct policydb *pdb) /* default_type */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_type != 0) { rc = write_default_type_to_cil(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -764,6 +772,7 @@ static int write_default_rules_to_cil(FILE *out, struct policydb *pdb) /* default_range */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_range) { rc = write_default_range_to_cil(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c index 460209c8..92a342d1 100644 --- a/libsepol/src/kernel_to_conf.c +++ b/libsepol/src/kernel_to_conf.c @@ -362,7 +362,7 @@ static int constraint_rules_to_strs(struct policydb *pdb, struct strs *mls_strs, for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; - if (class->constraints) { + if (class && class->constraints) { name = pdb->p_class_val_to_name[i]; rc = class_constraint_rules_to_strs(pdb, name, class, class->constraints, mls_strs, non_mls_strs); if (rc != 0) { @@ -387,7 +387,7 @@ static int validatetrans_rules_to_strs(struct policydb *pdb, struct strs *mls_st for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; - if (class->validatetrans) { + if (class && class->validatetrans) { name = pdb->p_class_val_to_name[i]; rc = class_validatetrans_rules_to_strs(pdb, name, class->validatetrans, mls_strs, non_mls_strs); if (rc != 0) { @@ -555,6 +555,7 @@ static int write_class_and_common_rules_to_conf(FILE *out, struct policydb *pdb) } for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; name = class->comkey; if (!name) continue; common = hashtab_search(pdb->p_commons.table, name); @@ -581,6 +582,7 @@ static int write_class_and_common_rules_to_conf(FILE *out, struct policydb *pdb) /* class */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; name = pdb->p_class_val_to_name[i]; sepol_printf(out, "class %s", name); if (class->comkey) { @@ -706,6 +708,7 @@ static int write_default_rules_to_conf(FILE *out, struct policydb *pdb) /* default_user */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_user != 0) { rc = write_default_user_to_conf(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -717,6 +720,7 @@ static int write_default_rules_to_conf(FILE *out, struct policydb *pdb) /* default_role */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_role != 0) { rc = write_default_role_to_conf(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -728,6 +732,7 @@ static int write_default_rules_to_conf(FILE *out, struct policydb *pdb) /* default_type */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_type != 0) { rc = write_default_type_to_conf(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { @@ -743,6 +748,7 @@ static int write_default_rules_to_conf(FILE *out, struct policydb *pdb) /* default_range */ for (i=0; i < pdb->p_classes.nprim; i++) { class = pdb->class_val_to_struct[i]; + if (!class) continue; if (class->default_range != 0) { rc = write_default_range_to_conf(out, pdb->p_class_val_to_name[i], class); if (rc != 0) { -- 2.34.1