diff mbox series

libsepol: handle type gaps when optimizing

Message ID 20211223185004.77862-1-cgzones@googlemail.com (mailing list archive)
State Superseded
Headers show
Series libsepol: handle type gaps when optimizing | expand

Commit Message

Christian Göttsche Dec. 23, 2021, 6:50 p.m. UTC
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@googlemail.com>
---
 libsepol/src/optimize.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

James Carter Jan. 3, 2022, 6:10 p.m. UTC | #1
On Fri, Dec 24, 2021 at 8:10 PM Christian Göttsche
<cgzones@googlemail.com> 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@googlemail.com>
> ---
>  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
diff mbox series

Patch

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;