Check the type for type and role sets is valid.
Check the scope of a scope datum is valid.
Check the flavor and flags of a type datum are valid.
Check xperms are set if and only if it is an extended permission avrule.
Check xperms has a valid specified field.
Check the flag of avrule blocks is valid.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check the permission bitset in normal constraints is not empty and has
no invalid bits set.
Check the names and type_names members are empty in case they are not
used.
Check the operator and attribute type are not set for simple expression
types.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
The callback function apply in hashtap_map has a return type of int and
can return -1 on error. Use int as type to save the return value to
avoid implicit conversions:
hashtab.c:236:10: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'unsigned int' changed the value to 4294967295 (32-bit, unsigned)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Add a new command-line option "--rebuild-if-modules-changed" to control
the newly introduced check_ext_changes libsemanage flag.
For example, running `semodule --rebuild-if-modules-changed` will ensure
that any externally added/removed modules (e.g. by an RPM transaction)
are reflected in the compiled policy, while skipping the most expensive
part of the rebuild if no module change was deteceted since the last
libsemanage transaction.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
In Fedora/RHEL's selinux-policy package we ship a pre-built SELinux
policy store in the RPMs. When updating the main policy RPM, care must
be taken to rebuild the policy using `semodule -B` if there are any
other SELinux modules installed (whether shipped via another RPM or
manually installed locally).
However, this way of shipping/managing the policy creates complications
on systems, where system files are managed by rpm-ostree (such as Fedora
CoreOS or Red Hat CoreOS), where the "package update" process is more
sophisticated.
(Disclaimer: The following is written according to my current limited
understanding of rpm-ostree and may not be entirely accurate, but the
gist of it should match the reality.)
Basically, one can think of rpm-ostree as a kind of Git for system
files. The package content is provided on a "branch", where each
"commit" represents a set of package updates layered on top of the
previous commit (i.e. it is a rolling release with some defined
package content snapshots). The user can then maintain their own branch
with additional package updates/installations/... and "rebase" it on top
of the main branch as needed. On top of that, the user can also have
additional configuration files (or modifications to existing files) in
/etc, which represent an additional layer on top of the package content.
When updating the system (i.e. rebasing on a new "commit" of the "main
branch"), the files on the running system are not touched and the new
system state is prepared under a new root directory, which is chrooted
into on the next reboot.
When an rpm-ostree system is updated, there are three moments when the
SELinux module store needs to be rebuilt to ensure that all modules are
included in the binary policy:
1. When the local RPM installations are applied on top of the base
system snapshot.
2. When local user configuartion is applied on top of that.
3. On system shutdown, to ensure that any changes in local configuration
performed since (2.) are reflected in the final new system image.
Forcing a full rebuild at each step is not optimal and in many cases is
not necessary, as the user may not have any custom modules installed.
Thus, this patch extends libsemanage to compute a checksum of the
content of all enabled modules, which is stored in the store, and adds a
flag to the libsemanage handle that instructs it to check the module
content checksum against the one from the last successful transaction
and force a full policy rebuild if they don't match.
This will allow rpm-ostree systems to potentially reduce delays when
reconciling the module store when applying updates.
I wasn't able to measure any noticeable overhead of the hash
computation, which is now added for every transaction (both before and
after this change a full policy rebuild took about 7 seconds on my test
x86 VM). With the new option check_ext_changes enabled, rebuilding a
policy store with unchanged modules took only about 0.96 seconds.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
In order to reduce exisiting and future code duplication and to avoid
some unnecessary allocations and copying, factor the compressed file
utility functions out into a separate C/header file and refactor their
interface.
Note that this change effectively removes the __fsetlocking(3) call from
semanage_load_files() - I haven't been able to figure out what purpose
it serves, but it seems pointless...
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
The main goal of this move is to have the SHA-256 implementation under
libsemanage, since upcoming patches will make use of SHA-256 for a
different (but similar) purpose in libsemanage. Having the hashing code
in libsemanage will reduce code duplication and allow for easier hash
algorithm upgrade in the future.
Note that libselinux currently also contains a hash function
implementation (for yet another different purpose). This patch doesn't
make any effort to address that duplicity yet.
This patch also changes the format of the hash string printed by
semodule to include the name of the hash. The intent is to avoid
ambiguity and potential collisions when the algorithm is potentially
changed in the future.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Map classes use the same struct as kernel classes, but only the kernel
class uses the pointer to a common class. When resolving a classcommon,
make sure that the class that is found is a kernel class and not a
map class. If not, then return an error.
Found by oss-fuzz (#43209)
Signed-off-by: James Carter <jwcart2@gmail.com>
Since abstract blocks will not appear in the final policy, do not
resolve names to a declaration inside one.
When resolving blockabstract rules, they must be collected in a list
and processed at the end of the pass because if a parent block is
marked as abstract, then a blockabstract rule for a sub-block will
fail to resolve.
Found by oss-fuzz (#42981)
Signed-off-by: James Carter <jwcart2@gmail.com>
If a block is marked as abstract, then it will be skipped during
every pass after blockabstracts are resolved (only tunables,
in-befores, and blockinherits are before blockabstracts), so mark
all of its sub-blocks as abstract to reflect their actual status.
Signed-off-by: James Carter <jwcart2@gmail.com>
Do not copy any blockabstract statements when copying a block to
resolve a blockinherit statement. Inheriting a block from what was
just inherited does not work, so there is no reason to create an
abstract block.
Signed-off-by: James Carter <jwcart2@gmail.com>
When converting an ebitmap into a string list, skip potential gaps in
ebitmap_to_strs(). All converting functions like strs_to_str(),
strs_write_each() and strs_write_each_indented() do already skip NULL
elements, but sorting such a list will lead to a NULL dereference.
#0 0x432ce5 in strcmp /src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc:462:25
#1 0x4f4893 in strs_cmp selinux/libsepol/src/kernel_to_common.c:258:9
#2 0x47b74b in qsort_r /src/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc:9994:7
#3 0x4f481d in strs_sort selinux/libsepol/src/kernel_to_common.c:266:2
#4 0x4fe781 in attrmap_to_str selinux/libsepol/src/kernel_to_conf.c:1560:2
#5 0x4fe781 in write_type_attribute_sets_to_conf selinux/libsepol/src/kernel_to_conf.c:1599:11
#6 0x4f8098 in sepol_kernel_policydb_to_conf selinux/libsepol/src/kernel_to_conf.c:3182:7
#7 0x4e0277 in LLVMFuzzerTestOneInput selinux/libsepol/fuzz/binpolicy-fuzzer.c:50:9
#8 0x4d613b in main
#9 0x7fa2d50260b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/libc-start.c:308:16
#10 0x41d4ed in _start
Found by oss-fuzz (#44170)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
The number of arguments passed to main(), argc, can be zero if the
pathname passed to execve(2) is NULL, e.g. via:
execve("/path/to/exe", {NULL}, {NULL});
Also avoid NULL pointer dereferences on the argument value.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
The length of an ebitmap is the current highest allocated (not set) bit
and always a multiple of MAPTYPE (= 64). The role ebitmap should only
have valid role bits set, even after inverting. The length might be
smaller than the maximum number of defined roles leading to non defined
role bits set afterwards.
Only invert up to the number of roles defined instead the full ebitmap
length, similar to type_set_expand().
This also avoids timeouts on an invalid huge highbit set, since the
ebitmap has not been validated yet, on which inverting will take
excessive amount of memory and time, found by oss-fuzz (#43709).
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
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>
The default log handler sepol_msg_default_handler() appends a newline
and the majority of log messages do not contain a trailing newline in
the format string.
Fixes: 5c178f9f55 ("libsepol: use logging framework in conditional.c")
Fixes: 852f14d43d ("libsepol: use logging framework in ebitmap.c")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Do not return success if the class name length is saturated (or too big
in the fuzzer build).
Fixes: c3d52a6a ("libsepol: check for saturated class name length")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check the from the polciy read length value to guard allocations.
In the fuzzer build the value will also be bounded to avoid oom reports.
==143646==ERROR: AddressSanitizer: allocator is out of memory trying to allocate 0xd60000000 bytes
#0 0x4dac18 in __interceptor_calloc (./out/binpolicy-fuzzer+0x4dac18)
#1 0x55d388 in scope_index_read ./libsepol/src/policydb.c:3945:7
#2 0x550097 in avrule_decl_read ./libsepol/src/policydb.c:3984:6
#3 0x550097 in avrule_block_read ./libsepol/src/policydb.c:4044:8
#4 0x54b3ac in policydb_read ./libsepol/src/policydb.c:4456:7
#5 0x518fd9 in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:35:6
#6 0x43f623 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (./out/binpolicy-fuzzer+0x43f623)
#7 0x42910f in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (./out/binpolicy-fuzzer+0x42910f)
#8 0x42ee76 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (./out/binpolicy-fuzzer+0x42ee76)
#9 0x458ff2 in main (./out/binpolicy-fuzzer+0x458ff2)
#10 0x7fd37b7931c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
Found by oss-fuzz (#42909)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
When selabel_open fails to locate file_context files and
selabel_opt_path is not specified (e.g. when the policy type is
missconfigured in /etc/selinux/config), perror only prints
"No such file or directory".
This can be confusing in case of "restorecon" since it's
not apparent that the issue is in policy store.
Before:
\# restorecon -v /tmp/foo.txt
No such file or directory
After:
\# restorecon -v /tmp/foo.txt
/etc/selinux/yolo/contexts/files/file_contexts: No such file or directory
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Check the sensitivity is valid and thus the lookup in the name array
`p_sens_val_to_name` is valid.
Found by oss-fuzz (#42729, #42730, #42735, #42741)
==54784==The signal is caused by a READ memory access.
#0 0x5a10f3 in mls_semantic_level_expand ./selinux/libsepol/src/expand.c:934:11
#1 0x53839e in policydb_user_cache ./selinux/libsepol/src/policydb.c:972:7
#2 0x5c6325 in hashtab_map ./selinux/libsepol/src/hashtab.c:236:10
#3 0x5392e9 in policydb_index_others ./selinux/libsepol/src/policydb.c:1274:6
#4 0x53f90a in policydb_read ./selinux/libsepol/src/policydb.c:4496:6
#5 0x50c679 in LLVMFuzzerTestOneInput ./selinux/libsepol/fuzz/binpolicy-fuzzer.c:35:6
#6 0x4409e3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (./selinux/out/binpolicy-fuzzer+0x4409e3)
#7 0x4295bf in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) (./selinux/out/binpolicy-fuzzer+0x4295bf)
#8 0x42f850 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (./selinux/out/binpolicy-fuzzer+0x42f850)
#9 0x45b6d2 in main (./selinux/out/binpolicy-fuzzer+0x45b6d2)
#10 0x7f059fcd71c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#11 0x7f059fcd7277 in __libc_start_main csu/../csu/libc-start.c:409:3
#12 0x423900 in _start (./out/binpolicy-fuzzer+0x423900)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Do not continue with a negative return value once a string append
operation fails to avoid increasing the buffer length variable
`str_len`, potentially leading to an out-of-bounds write.
Found by GitHub CodeQL.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check the class default targets are valid values, e.g. source or target
for user, role and type.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check all categories have valid values, especially important for
aliases.
==7888==ERROR: AddressSanitizer: SEGV on unknown address 0x602000400710 (pc 0x00000055debc bp 0x7ffe0ff2a9d0 sp 0x7ffe0ff2a8e0 T0)
==7888==The signal is caused by a READ memory access.
#0 0x55debc in write_category_rules_to_conf ./libsepol/src/kernel_to_conf.c:946:9
#1 0x55debc in write_mls_rules_to_conf ./libsepol/src/kernel_to_conf.c:1137:7
#2 0x55adb1 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3106:7
#3 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:37:9
#4 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#5 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#6 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#7 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#8 0x7fe80ccaf7ec in __libc_start_main csu/../csu/libc-start.c:332:16
#9 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check the literal contexts in ocontext statements are defined.
==91274==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f60b0afe8c6 bp 0x7ffd42edc990 sp 0x7ffd42edc148 T0)
==91274==The signal is caused by a READ memory access.
==91274==Hint: address points to the zero page.
#0 0x7f60b0afe8c6 string/../sysdeps/x86_64/multiarch/../strlen.S:120
#1 0x4bd128 in __interceptor_strlen (./out/binpolicy-fuzzer+0x4bd128)
#2 0x5eb387 in create_str_helper ./libsepol/src/kernel_to_common.c:69:10
#3 0x5eb11e in create_str ./libsepol/src/kernel_to_common.c:99:8
#4 0x56ad7b in context_to_str ./libsepol/src/kernel_to_conf.c:2408:9
#5 0x56a717 in write_sid_context_rules_to_conf ./libsepol/src/kernel_to_conf.c:2441:9
#6 0x55b26c in write_selinux_isid_rules_to_conf ./libsepol/src/kernel_to_conf.c:2476:9
#7 0x55b26c in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3206:8
#8 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#9 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#10 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#11 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#12 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#13 0x7f60b0a887ec in __libc_start_main csu/../csu/libc-start.c:332:16
#14 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
==80903==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000005c0 at pc 0x0000005696c8 bp 0x7ffdb11ea560 sp 0x7ffdb11ea558
READ of size 8 at 0x6020000005c0 thread T0
#0 0x5696c7 in avtab_node_to_str ./libsepol/src/kernel_to_conf.c:1736:9
#1 0x569013 in map_avtab_write_helper ./libsepol/src/kernel_to_conf.c:1767:10
#2 0x5ab837 in avtab_map ./libsepol/src/avtab.c:347:10
#3 0x561f9a in write_avtab_flavor_to_conf ./libsepol/src/kernel_to_conf.c:1798:7
#4 0x561f9a in write_avtab_to_conf ./libsepol/src/kernel_to_conf.c:1819:8
#5 0x55afba in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3159:7
#6 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#7 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#8 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#9 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#10 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#11 0x7f97a83fd7ec in __libc_start_main csu/../csu/libc-start.c:332:16
#12 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check a common class or a class together with its common class parent
does not have more than the supported 32 permissions.
==28413==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f74ec3341a3 bp 0x7ffd0b7e5030 sp 0x7ffd0b7e47e8 T0)
==28413==The signal is caused by a READ memory access.
==28413==Hint: address points to the zero page.
#0 0x7f74ec3341a3 string/../sysdeps/x86_64/multiarch/../strchr.S:32
#1 0x4bfc78 in strchr (./out/binpolicy-fuzzer+0x4bfc78)
#2 0x55b7f2 in class_constraint_rules_to_strs ./libsepol/src/kernel_to_conf.c:288:7
#3 0x55b7f2 in constraint_rules_to_strs ./libsepol/src/kernel_to_conf.c:364:9
#4 0x55ac80 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3071:7
#5 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#6 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#7 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#8 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#9 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#10 0x7f74ec2be7ec in __libc_start_main csu/../csu/libc-start.c:332:16
#11 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Check those contains valid values.
==57532==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000001178 at pc 0x000000564c04 bp 0x7ffed7a5ad90 sp 0x7ffed7a5ad88
READ of size 8 at 0x603000001178 thread T0
#0 0x564c03 in level_to_str ./libsepol/src/kernel_to_conf.c:1901:19
#1 0x564c03 in range_to_str ./libsepol/src/kernel_to_conf.c:1926:9
#2 0x564c03 in write_user_decl_rules_to_conf ./libsepol/src/kernel_to_conf.c:2367:12
#3 0x55b137 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3184:7
#4 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#5 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#6 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#7 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#8 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#9 0x7f2c2e1a77ec in __libc_start_main csu/../csu/libc-start.c:332:16
#10 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Validate the level map of the policy to ensure no level refers to a non
existent category.
READ of size 8 at 0x602000000c58 thread T0
#0 0x568d2c in cats_ebitmap_len ./libsepol/src/kernel_to_conf.c:1003:14
#1 0x568d2c in cats_ebitmap_to_str ./libsepol/src/kernel_to_conf.c:1038:19
#2 0x55e371 in write_level_rules_to_conf ./libsepol/src/kernel_to_conf.c:1106:11
#3 0x55e371 in write_mls_rules_to_conf ./libsepol/src/kernel_to_conf.c:1140:7
#4 0x55adb1 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3103:7
#5 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#6 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#7 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#8 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#9 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#10 0x7f741d0d67ec in __libc_start_main csu/../csu/libc-start.c:332:16
#11 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Split the validation of array datums regarding their gaps and entries to
simplify further checking of common classes, booleans, levels and
categories.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Currently is it implementation defined, due to the size being passed to
calloc(3), whether the operations fails nor not.
Also strs_add() does not handle a size of zero, cause it just multiplies
the size by two.
Use a default size of 1 if 0 is passed and swap the calloc arguments for
consistency.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Use the number of categories not levels, which might be zero, for the
string list initial size of categories.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Handle gaps in the user table while printing a policy configuration.
==24424==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x0000004bdc55 bp 0x7ffc8790b810 sp 0x7ffc8790afb0 T0)
==24424==The signal is caused by a READ memory access.
==24424==Hint: address points to the zero page.
#0 0x4bdc55 in __interceptor_strcmp (./out/binpolicy-fuzzer+0x4bdc55)
#1 0x5ebdf6 in strs_cmp ./libsepol/src/kernel_to_common.c:253:9
#2 0x505669 in __interceptor_qsort (./out/binpolicy-fuzzer+0x505669)
#3 0x5ebd84 in strs_sort ./libsepol/src/kernel_to_common.c:261:2
#4 0x564550 in write_user_decl_rules_to_conf ./libsepol/src/kernel_to_conf.c:2333:2
#5 0x55b137 in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3190:7
#6 0x55a34f in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:38:9
#7 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#8 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#9 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#10 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#11 0x7f530128d7ec in __libc_start_main csu/../csu/libc-start.c:332:16
#12 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
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@googlemail.com>
Handle format arguments that do not have a size of at least 2.
kernel_to_common.c:69:20: runtime error: unsigned integer overflow: 1 - 2 cannot be represented in type 'unsigned long'
#0 0x557b0b in create_str_helper ./libsepol/src/kernel_to_common.c:69:20
#1 0x5577b8 in create_str ./libsepol/src/kernel_to_common.c:99:8
#2 0x56448c in cond_expr_to_str ./libsepol/src/kernel_to_conf.c:82:15
#3 0x56448c in write_cond_nodes_to_conf ./libsepol/src/kernel_to_conf.c:2103:10
#4 0x55bd9b in sepol_kernel_policydb_to_conf ./libsepol/src/kernel_to_conf.c:3171:7
#5 0x4f9d79 in main ./checkpolicy/checkpolicy.c:684:11
#6 0x7fe2a342b7ec in __libc_start_main csu/../csu/libc-start.c:332:16
#7 0x41f3a9 in _start (./checkpolicy/checkpolicy+0x41f3a9)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
The `next` member might be checked against NULL and dereferenced before
it gets assigned, due to jumps from failure gotos to the cleanup
section.
==31017==ERROR: AddressSanitizer: SEGV on unknown address (pc 0x000000579654 bp 0x7ffd3a07d110 sp 0x7ffd3a07d000 T0)
==31017==The signal is caused by a READ memory access.
==31017==Hint: this fault was caused by a dereference of a high value address (see register values below). Disassemble the provided pc to learn which register was used.
#0 0x579654 in filename_trans_read_one ./libsepol/src/policydb.c:2874:55
#1 0x579654 in filename_trans_read ./libsepol/src/policydb.c:2902:9
#2 0x5771b7 in policydb_read ./libsepol/src/policydb.c:4509:7
#3 0x55a1f5 in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:24:6
#4 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#5 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#6 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#7 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#8 0x7f2a4e7f97ec in __libc_start_main csu/../csu/libc-start.c:332:16
#9 0x423689 in _start (./out/binpolicy-fuzzer+0x423689)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Free the local access vector list on failure as it does not get moved
into the policy structure.
Drop the now redundant, but non-exhaustive, resource cleanup in
cond_insertf().
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x52596d in malloc (./out/binpolicy-fuzzer+0x52596d)
#1 0x5b30d2 in cond_insertf ./libsepol/src/conditional.c:682:9
#2 0x5ac218 in avtab_read_item ./libsepol/src/avtab.c:583:10
#3 0x5b21f4 in cond_read_av_list ./libsepol/src/conditional.c:725:8
#4 0x5b21f4 in cond_read_node ./libsepol/src/conditional.c:798:7
#5 0x5b21f4 in cond_read_list ./libsepol/src/conditional.c:847:7
#6 0x576b6e in policydb_read ./libsepol/src/policydb.c:4436:8
#7 0x55a1fe in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:24:6
#8 0x45aed3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
#9 0x446a12 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
#10 0x44c93b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
#11 0x475dd2 in main (./out/binpolicy-fuzzer+0x475dd2)
#12 0x7f47abeb87ec in __libc_start_main csu/../csu/libc-start.c:332:16
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>