On Fri, Dec 24, 2021 at 8:10 PM Christian Göttsche <cgzones@xxxxxxxxxxxxxx> wrote: > > For policy versions between 20 and 23 the type_val_to_struct array might > contain gaps. Skip those gaps to avoid NULL pointer dereferences: > > ==1250==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x00000058560b bp 0x7ffdca60c110 sp 0x7ffdca60bfc0 T0) > ==1250==The signal is caused by a READ memory access. > ==1250==Hint: address points to the zero page. > #0 0x58560b in build_type_map selinux/libsepol/src/optimize.c:107:33 > #1 0x58560b in policydb_optimize selinux/libsepol/src/optimize.c:441:13 > #2 0x55e63e in LLVMFuzzerTestOneInput selinux/libsepol/fuzz/binpolicy-fuzzer.c:42:10 > #3 0x455283 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) cxa_noexception.cpp:0 > #4 0x440ec2 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6 > #5 0x44671c in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) cxa_noexception.cpp:0 > #6 0x46f522 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10 > #7 0x7f9c160d00b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16 > #8 0x41f67d in _start > > Found by oss-fuzz (#42697) > > Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> > --- > libsepol/src/optimize.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/libsepol/src/optimize.c b/libsepol/src/optimize.c > index 8a048702..678d22bd 100644 > --- a/libsepol/src/optimize.c > +++ b/libsepol/src/optimize.c > @@ -104,6 +104,10 @@ static struct type_vec *build_type_map(const policydb_t *p) > if (type_vec_init(&map[i])) > goto err; > > + /* Gap in types for policy versions between 20 and 23 */ > + if (!p->type_val_to_struct[i]) > + continue; > + > if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { > ebitmap_for_each_positive_bit(&p->type_attr_map[i], > n, k) { > @@ -114,11 +118,17 @@ static struct type_vec *build_type_map(const policydb_t *p) > ebitmap_t *types_i = &p->attr_type_map[i]; > > for (k = 0; k < p->p_types.nprim; k++) { > - ebitmap_t *types_k = &p->attr_type_map[k]; > + ebitmap_t *types_k; > + > + /* Gap in types for policy versions between 20 and 23 */ > + if (!p->type_val_to_struct[k]) > + continue; > > if (p->type_val_to_struct[k]->flavor != TYPE_ATTRIB) > continue; > > + types_k = &p->attr_type_map[k]; > + > if (ebitmap_contains(types_k, types_i)) { > if (type_vec_append(&map[i], k)) > goto err; > -- > 2.34.1 > Before policy version 20, there are no attributes, so I think that a check should be made in policydb_optimize() for a version less than 24 and just exit with an error there with an error message. Policy version 23 has not been the latest for more than 10 years. Thanks, Jim