Commit Graph

3254 Commits

Author SHA1 Message Date
James Carter
c2af8933ef libsepol: Change label in check_assertion_avtab_match()
Change the label name from "exit" to "nomatch' to make it clearer
what is happening.

Signed-off-by: James Carter <jwcart2@gmail.com>
2022-02-24 10:37:47 -05:00
James Carter
521e6ad713 libsepol: Return an error if check_assertion() returns an error.
Instead of calling report_assertion_failures() and treating an
error like it was a neverallow violation, just return an error.

Signed-off-by: James Carter <jwcart2@gmail.com>
2022-02-24 10:37:44 -05:00
Christian Göttsche
4be0e2e19c checkpolicy: allow wildcard permissions in constraints
Allow all and complement permission sets in constraints, e.g.:

    constrain service ~ { status } (...);
    constrain service * (...);

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2022-02-18 14:48:57 -05:00
Christian Göttsche
ff25475ce7 libsepol: validate several flags
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>
2022-02-18 11:08:54 -05:00
Christian Göttsche
9bee80da00 libsepol: more strict constraint validation
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>
2022-02-18 11:08:51 -05:00
Christian Göttsche
496002e7ea libsepol: use correct error type to please UBSAN
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>
2022-02-18 11:08:48 -05:00
Ondrej Mosnacek
2d08c5dd89 semodule: add command-line option to detect module changes
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>
2022-02-18 11:08:41 -05:00
Ondrej Mosnacek
286a679fad libsemanage: optionally rebuild policy when modules are changed externally
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>
2022-02-18 11:08:39 -05:00
Ondrej Mosnacek
df9f71ab50 libsemanage: clean up semanage_direct_commit() a bit
Do some minor cosmetic cleanup, mainly to eliminate the 'rebuilt' goto
label.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
2022-02-18 11:08:36 -05:00
Ondrej Mosnacek
d01ec02fb9 libsemanage: move compressed file handling into a separate object
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>
2022-02-18 11:08:34 -05:00
Ondrej Mosnacek
67e6201bc8 semodule,libsemanage: move module hashing into libsemanage
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>
2022-02-18 11:08:30 -05:00
Ondrej Mosnacek
6f9e771987 libsemanage: add missing include to boolean_record.c
It uses asprintf(3), but doesn't directly include <stdio.h> - fix it.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
2022-02-18 11:08:27 -05:00
James Carter
86cdb9f119 libsepol/cil: Ensure that the class in a classcommon is a kernel class
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>
2022-02-11 14:07:03 -05:00
James Carter
f0823bbbb5 libsepol/cil: Do not resolve names to declarations in abstract blocks
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>
2022-02-11 14:05:19 -05:00
James Carter
6d783e5bb3 libsepol/cil: Mark as abstract all sub-blocks of an abstract block
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>
2022-02-11 14:05:15 -05:00
James Carter
e6429963eb libsepol/cil: Do not copy blockabstracts when inheriting a block
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>
2022-02-11 14:05:12 -05:00
Christian Göttsche
58443a00db libsepol: do not add gaps to string list
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>
2022-02-07 11:14:53 -05:00
Christian Göttsche
9229f8b3b7 policycoreutils: handle argument counter of zero
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>
2022-02-07 11:14:26 -05:00
Christian Göttsche
7385004162 libsepol: invert only valid range of role bitmap
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>
2022-01-27 09:52:10 -05:00
Christian Göttsche
42a8dc46a7 libsepol: handle type gaps
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>
2022-01-27 09:51:50 -05:00
Christian Göttsche
b8cba274be libsepol: drop trailing newlines in log messages
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>
2022-01-27 09:51:37 -05:00
Christian Göttsche
f52f5e2715 libsepol: return failure on saturated class name length
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>
2022-01-27 09:51:21 -05:00
Christian Göttsche
c3d52a6a30 libsepol: check for saturated class name length
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>
2022-01-18 11:03:01 -05:00
Vit Mojzis
b8004f0586 policycoreutils: Improve error message when selabel_open fails
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>
2022-01-14 08:55:13 -06:00
Evgeny Vereshchagin
ad2ff8a840 ci: run the tests under ASan/UBsan on GHActions
It was tested in https://github.com/SELinuxProject/selinux/pull/321 and
https://github.com/SELinuxProject/selinux/pull/320. In the process
it discovered a few issues all of which were fixed in
b98d3c4c53
ea539017fb
fe01a91a79
f95dbf2c74

Now that all the issues are gone it should be safe to turn it on
to make it easier to automatically catch bugs like that almost as soon as
they end up in the repository.

Signed-off-by: Evgeny Vereshchagin <evvers@ya.ru>
2022-01-06 10:34:33 -05:00
Christian Göttsche
b78560fd37 libsepol: check for valid sensitivity before lookup
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>
2022-01-05 13:22:55 -05:00
Christian Göttsche
b2ba721ebb libsepol/cil: bail out on snprintf failure
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>
2022-01-05 13:22:45 -05:00
Christian Göttsche
5e6e516ee0 libsepol: validate class default targets
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>
2021-12-15 12:52:25 -05:00
Christian Göttsche
24618ad3f5 libsepol: validate fsuse types
Check the fsuse type is valid, e.g. of type xattr, trans or task.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:23 -05:00
Christian Göttsche
8a7215c6a5 libsepol: validate categories
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>
2021-12-15 12:52:20 -05:00
Christian Göttsche
80b9441588 libsepol: validate policy properties
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:18 -05:00
Christian Göttsche
2c4da50a9b libsepol: validate permissive types
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:16 -05:00
Christian Göttsche
88e280a1d9 libsepol: validate genfs contexts
Check the literal contexts in a genfs statement are defined.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:14 -05:00
Christian Göttsche
8628133757 libsepol: validate ocontexts
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>
2021-12-15 12:52:12 -05:00
Christian Göttsche
5f81623245 libsepol: validate type of avtab type rules
==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>
2021-12-15 12:52:08 -05:00
Christian Göttsche
8c59d614b3 libsepol: validate constraint expression operators and attributes
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:05 -05:00
Christian Göttsche
312eac1c18 libsepol: validate avtab and avrule types
Check for invalid avtab or avrule types.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:52:02 -05:00
Christian Göttsche
ba6d82255b libsepol: resolve log message mismatch
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:51:59 -05:00
Christian Göttsche
e39cf0a1f0 libsepol: validate permission count of classes
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>
2021-12-15 12:51:57 -05:00
Christian Göttsche
fffb16093c libsepol: validate expanded user range and level
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>
2021-12-15 12:51:54 -05:00
Christian Göttsche
8fdb3eb272 libsepol: validate MLS levels
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>
2021-12-15 12:51:52 -05:00
Christian Göttsche
e2e60d9b96 libsepol: split validation of datum array gaps and entries
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>
2021-12-15 12:51:49 -05:00
Christian Göttsche
691e6aff4c libsepol: do not create a string list with initial size zero
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>
2021-12-15 12:51:47 -05:00
Christian Göttsche
35ef9b95e7 libsepol: use correct size for initial string list
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>
2021-12-15 12:51:45 -05:00
Christian Göttsche
731540202a libsepol: do not crash on user gaps
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>
2021-12-15 12:51:42 -05:00
Christian Göttsche
b76eda527f libsepol: do not crash on class gaps
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>
2021-12-15 12:51:36 -05:00
Christian Göttsche
c12b7d907a libsepol: do not underflow on short format arguments
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>
2021-12-15 12:51:33 -05:00
Christian Göttsche
47c3d96e56 libsepol: use size_t for indexes in strs helpers
Use size_t, as the strs struct uses it for its size member.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:51:30 -05:00
Christian Göttsche
8565e2c5c8 libsepol: zero member before potential dereference
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>
2021-12-15 12:51:27 -05:00
Christian Göttsche
1b4979c528 libsepol: reject invalid filetrans source type
Avoid integer underflow on invalid filetrans source types.

    policydb.c:2658:47: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'unsigned int'
        #0 0x4cf4cb in policydb_filetrans_insert ./libsepol/src/policydb.c:2658:47
        #1 0x4d221a in filename_trans_read_one_compat ./libsepol/src/policydb.c:2691:7
        #2 0x4d221a in filename_trans_read ./libsepol/src/policydb.c:2842:9
        #3 0x4d1370 in policydb_read ./libsepol/src/policydb.c:4447:7
        #4 0x4b1ee3 in LLVMFuzzerTestOneInput ./libsepol/fuzz/binpolicy-fuzzer.c:35:6
        #5 0x43f2f3 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) fuzzer.o
        #6 0x42ae32 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) fuzzer.o
        #7 0x430d5b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) fuzzer.o
        #8 0x45a1f2 in main (./out/binpolicy-fuzzer+0x45a1f2)
        #9 0x7f8b8923a7ec in __libc_start_main csu/../csu/libc-start.c:332:16
        #10 0x407aa9 in _start (./out/binpolicy-fuzzer+0x407aa9)

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-12-15 12:51:24 -05:00