SELinuxProject / selinux

This is the upstream repository for the Security Enhanced Linux (SELinux) userland libraries and tools. The software provided by this project complements the SELinux features integrated into the Linux kernel and is used by Linux distributions. All bugs and patches should be submitted to selinux@vger.kernel.org
Other
1.31k stars 352 forks source link

libsepol:The libsepol package detects memory leaks and segmentation errors when tested by OSS-fuzz. #404

Open muyu888 opened 1 year ago

muyu888 commented 1 year ago

libsepol version 3.1.10 Operating system Linux

Description I found memory leaks and segment errors while performing OSS-fuzz testing with the following steps,Maybe you can tell me whether it's reasonable or not. Steps to Reproduce Issue one: 1、 Compilation python3 infra/helper.py build_fuzzers --sanitizer address selinux 2、Check the output file python3 infra/helper.py reproduce selinux secilc-fuzzer build/out/selinux/leak-0790666db6912b2950c819fa190a5aa32aa23c36 3、 Report the contents of the error INFO: Seed: 1882425977 INFO: Loaded 1 modules (14356 inline 8-bit counters): 14356 [0xa757a0, 0xa78fb4), INFO: Loaded 1 PC tables (14356 PCs): 14356 [0xa78fb8,0xab10f8), /out/secilc-fuzzer: Running 1 inputs 100 time(s) each. Running: /testcase

================================================================= ==6==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 2 object(s) allocated from:

0 0x51dd5d in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3

#1 0x6350d4 in cil_malloc /src/selinux/src/../cil/src/cil_mem.c:39:14
#2 0x631f4e in cil_list_init /src/selinux/src/../cil/src/cil_list.c:49:30
#3 0x66e5ff in __cil_resolve_perms /src/selinux/src/../cil/src/cil_resolve_ast.c:117:2
#4 0x66de38 in cil_resolve_classperms /src/selinux/src/../cil/src/cil_resolve_ast.c:178:7
#5 0x66f45e in cil_resolve_classperms_list /src/selinux/src/../cil/src/cil_resolve_ast.c:221:9
#6 0x66f22c in cil_resolve_classperms_set /src/selinux/src/../cil/src/cil_resolve_ast.c:202:8
#7 0x66f501 in cil_resolve_classperms_list /src/selinux/src/../cil/src/cil_resolve_ast.c:226:9
#8 0x670a64 in cil_resolve_avrule /src/selinux/src/../cil/src/cil_resolve_ast.c:344:8
#9 0x694361 in __cil_resolve_ast_node /src/selinux/src/../cil/src/cil_resolve_ast.c:3613:9
#10 0x695cea in __cil_resolve_ast_node_helper /src/selinux/src/../cil/src/cil_resolve_ast.c:3819:7
#11 0x6a18a0 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:272:9
#12 0x6a1e51 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#13 0x6a1a84 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#14 0x6a1e51 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#15 0x6a1a84 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#16 0x6a1e51 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#17 0x6a1a84 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#18 0x6a1e51 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#19 0x69758b in cil_resolve_ast /src/selinux/src/../cil/src/cil_resolve_ast.c:3955:8
#20 0x57a7ed in cil_compile /src/selinux/src/../cil/src/cil.c:575:7
#21 0x5506de in LLVMFuzzerTestOneInput /src/secilc-fuzzer.c:59:6
#22 0x4586a1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#23 0x443a02 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:296:6
#24 0x449a97 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:776:9
#25 0x4720e2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#26 0x7f7c9aafc82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: 96 byte(s) leaked in 4 allocation(s). INFO: a leak has been found in the initial corpus. INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.

4.My analysis: In the file /cil/src/cil_resolve_ast.c, there are two branches in the static int __cil_resolve_perms(), one of which applies for memory that has not been visibly found to be used externally, and whether it can be released! else { cil_list_append(*perm_datums, curr->flavor, curr->data); } } return SEPOL_OK;

exit: cil_list_destroy(perm_datums, CIL_FALSE); return rc; } Issue two: 1、 Compilation python3 infra/helper.py build_fuzzers --sanitizer undefined selinux 2、 Check the output file python3 infra/helper.py reproduce selinux secilc-fuzzer build/out/selinux/crash-cb5d181cd5ac1886a7b128f6c58b5638edc7f26d 3、 Report the contents of the error INFO: Seed: 820964843 INFO: Loaded 1 modules (51925 inline 8-bit counters): 51925 [0xb9ff68, 0xbaca3d), INFO: Loaded 1 PC tables (51925 PCs): 51925 [0xbaca40,0xc77790), /out/secilc-fuzzer: Running 1 inputs 100 time(s) each. Running: /testcase UndefinedBehaviorSanitizer:DEADLYSIGNAL ==6==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fcf403a1746 bp 0x7fff63ca2990 sp 0x7fff63ca28f8 T6) ==6==The signal is caused by a READ memory access. ==6==Hint: address points to the zero page.

0 0x7fcf403a1746 in strlen (/lib/x86_64-linux-gnu/libc.so.6+0x8b746)

#1 0x7a0f92 in symhash /src/selinux/src/symtab.c:22:9
#2 0x70cef9 in hashtab_insert /src/selinux/src/hashtab.c:115:11
#3 0x6454cd in cil_symtab_insert /src/selinux/src/../cil/src/cil_symtab.c:90:11
#4 0x5b5dc2 in __cil_copy_node_helper /src/selinux/src/../cil/src/cil_copy_ast.c:2056:9
#5 0x64d867 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:272:9
#6 0x64de26 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#7 0x64d9f8 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#8 0x64de26 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#9 0x64d9f8 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#10 0x64de26 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#11 0x5b04a7 in cil_copy_ast /src/selinux/src/../cil/src/cil_copy_ast.c:2144:7
#12 0x6363cd in cil_resolve_call1 /src/selinux/src/../cil/src/cil_resolve_ast.c:2958:8
#13 0x63aafc in __cil_resolve_ast_node /src/selinux/src/../cil/src/cil_resolve_ast.c:3504:9
#14 0x63da17 in __cil_resolve_ast_node_helper /src/selinux/src/../cil/src/cil_resolve_ast.c:3818:7
#15 0x64d867 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:272:9
#16 0x64de26 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#17 0x64d9f8 in cil_tree_walk_core /src/selinux/src/../cil/src/cil_tree.c:284:9
#18 0x64de26 in cil_tree_walk /src/selinux/src/../cil/src/cil_tree.c:316:7
#19 0x63f553 in cil_resolve_ast /src/selinux/src/../cil/src/cil_resolve_ast.c:3954:8
#20 0x4e6960 in cil_compile /src/selinux/src/../cil/src/cil.c:575:7
#21 0x4b046b in LLVMFuzzerTestOneInput /src/secilc-fuzzer.c:59:6
#22 0x441711 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
#23 0x42ca72 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:296:6
#24 0x432b07 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:776:9
#25 0x45b152 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
#26 0x7fcf4033682f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#27 0x407088 in _start (/out/secilc-fuzzer+0x407088)

UndefinedBehaviorSanitizer can not provide additional info. SUMMARY: UndefinedBehaviorSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x8b746) in strlen ==6==ABORTING

  1. My analysis: In the src/symtab.c file, the test reported an error suggesting that there was a problem calculating the string length. Initial thoughts were to make sure that the key parameter passed in is not NULL and to check for the presence of an empty string. But my attempts did not work! keyp = (const char *)key; if (keyp == NULL) { return 0; } size = strlen(keyp); if (size == 0) { return 0; }

Hope can give conclusion can pass this OSS-fuzz fuzz test, thanks~!

jwcart2 commented 1 year ago

This might be related to a problem found by oss-fuzz earlier in the year. I sent a patch to the list on April 20th, but that patch has not been reviewed or merged yet. If you are able, please try that patch and see if it fixes the problem. If it doesn't, it would be very helpful if you could attach the CIL policy that oss-fuzz created to find this problem. Thanks!

muyu888 commented 1 year ago

Thanks for the answer, but I didn't find the patch you mentioned for the 20th of April, could you please provide it again? And then I didn't find the cil strategy file over here either, maybe it has another name, painstakingly you say more details!

jwcart2 commented 1 year ago

Just to be clear, the patch was posted on the SELinux mailing list here: https://lore.kernel.org/selinux/20230420125801.999381-1-jwcart2@gmail.com/

oss-fuzz is generating CIL policies and then trying to compile them, so there should be a policy file somewhere. I know when I receive reports from oss-fuzz it includes a link to the CIL policy file that caused the problem.

muyu888 commented 1 year ago

I've found the cause, the memory leak is due to the following merge-in:https://github.com/SELinuxProject/selinux/commit/c49a8ea09501ad66e799ea41b8154b6770fec2c8; but later on this merge-in will fix the leak:https://github.com/SELinuxProject/selinux/commit/2d2c76fc613ba338476a3a1741c2a3af5e04d154; As for the segment error, it's only known to be caused by this merge-in code:https://github.com/SELinuxProject/selinux/commit/67a8dc8117e0c3887c39f7add8932e4ad23c1d9c; it's not clear which merge-in or multiple merges fixed it, but as of version 3.3, this version is working fine!