Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
muyu888 opened this issue Jul 12, 2023 · 4 comments

Comments

@muyu888
Copy link

muyu888 commented Jul 12, 2023

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
4. 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
Copy link
Contributor

jwcart2 commented Jul 12, 2023

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
Copy link
Author

muyu888 commented Jul 13, 2023

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
Copy link
Contributor

jwcart2 commented Jul 13, 2023

Just to be clear, the patch was posted on the SELinux mailing list here:
https://lore.kernel.org/selinux/[email protected]/

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
Copy link
Author

muyu888 commented Aug 4, 2023

I've found the cause, the memory leak is due to the following merge-in:c49a8ea;
but later on this merge-in will fix the leak:2d2c76f;
As for the segment error, it's only known to be caused by this merge-in code:67a8dc8;
it's not clear which merge-in or multiple merges fixed it, but as of version 3.3, this version is working fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants