Bump the maximum Python version to 3.12 and the maximum Ruby version to
3.3 in the GitHub CI.
Also bump the setup-python action to v5.
Since Python 3.12 dropped setuptools, install manually.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Drop the global variable policyvers. The variable is only used within
checkpolicy.c and checkmodule.c, but never in any shared code.
Since the variable declaration is the only content of checkpolicy.h drop
it.
Also set the policy version before calls to read_source_policy(), so the
parser can access the requested version for checks this way.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The variable policy_type used by checkmodule is only used inside of
checkmodule.c.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
An extended permission rule statement might get split into multiple
access vector rules, due to size limitations.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
If a policy version cannot be found include the policy target, and a
module prefix for non kernel policies in the message.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The function pointer arrays are never changed, declare them const.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Free the ebitmaps inside the rolesets on error.
Reported-by: oss-fuzz (issue 67769)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The union stack_item_u is only used as a member in struct scope_stack,
but actually never used.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The struct scope_stack member child is never read, drop it.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Since commit c205b924e2 ("libsepol: Fix buffer overflow when using
sepol_av_to_string()") writing an access vector with no valid permission
results in an error instead of an empty string being written.
Validate that at least one permission of an access vector is valid.
There might be invalid bits set, e.g. by previous versions of
checkpolicy setting all bits for the wildcard (*) permission.
Reported-by: oss-fuzz (issue 67730)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The default action of the lexer macro YY_FATAL_ERROR(msg) is to print
the message and call exit(). This might happen on an overlong token
(8192 bytes) that does not fit into the token buffer.
Fuzz targets must not call exit() though, since an exit is treated as an
abnormal behavior, see https://llvm.org/docs/LibFuzzer.html#fuzz-target.
Since YY_FATAL_ERROR is used in functions with different return value
types and is expected to not return, jump to a location in the fuzzer
right before yyparse() instead.
Reported-by: oss-fuzz (issue 67728)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Include the necessary header for isprint(3) to avoid an implicit
function declaration:
policy_scan.l: In function ‘yyerror’:
policy_scan.l:342:13: warning: implicit declaration of function ‘isprint’ [-Wimplicit-function-declaration]
342 | if (isprint((unsigned char)yytext[0])) {
| ^~~~~~~
policy_scan.l:36:1: note: include ‘<ctype.h>’ or provide a declaration of ‘isprint’
35 | #include "y.tab.h"
+++ |+#include <ctype.h>
36 | #endif
This does not currently break the build cause -Werror is stripped for
the parsing code to avoid breakage on old flex/bison versions that might
not generate warning free code.
Fixes: 39b3cc5135 ("checkpolicy: handle unprintable token")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Commit e81c466 "Fix class permission verification in CIL", added a
check for the use of "all" in a permission expression for a class
that had no permissions. Unfortunately, that change did not take
into account a class that had common permissions, so a class that
has no permmissions of its own, but inherits permissions from a
common, will fail the verification check.
If the class inherits from a common, then add those permissions to
the permmission list when verifying the permission expression.
Example/
(common co1 (cop1))
(class cl1 ())
(classcommon cl1 co1)
(classorder (CLASS cl1))
(classpermission cp1)
(classpermissionset cp1 (cl1 (all)))
(classmap cm1 (cmp1))
(classmapping cm1 cmp1 (cl1 (all)))
Previously, both the classpermissionset and the classmapping rules
would fail verification, but now they pass as expected.
Patch originally from Ben Cressey <bcressey@amazon.com>, I have
expanded the explanation.
Reported-by: Ben Cressey <bcressey@amazon.com>
Signed-off-by: James Carter <jwcart2@gmail.com>
I am not sure what "hoge" supposed to mean; use a message similar to
other diagnostics.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Free the two identifiers on an invalid typebounds in the error branch,
similar to the success branch.
Reported-by: oss-fuzz (issue 67700)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In case the erroneous token is unprintable, e.g. a control character,
print its hex value instead.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The special error value YYerror is only available since bison 3.6
(released 2020). For example the version used by oss-fuzz does not
support it.
Use a special token in case YYerror is not available. Only downside is
a duplicate error message, one from the manual yyerror() call and one
from within bison for the unexpected special token (which would be
omitted by using YYerror).
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
If no policy has been loaded yet and thus the current context is still
"kernel" avoid logging failures in get_ordered_context_list(), like:
get_ordered_context_list: error in processing configuration file /etc/selinux/debian/contexts/users/root
get_ordered_context_list: error in processing configuration file /etc/selinux/debian/contexts/default_contexts
Move the context parsing from get_context_user() to its caller
get_ordered_context_list(), so an invalid context is not treated as an
get_context_user() failure and not logged.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
New flag -C for audit2allow sets output format to CIL instead of
Policy Language.
Example:
;============= mozilla_t ==============
;!!!! This avc is allowed in the current policy
(allow mozilla_t user_sudo_t (fd (use)))
;============= user_t ==============
;!!!! This avc can be allowed using the boolean 'allow_execmem'
(allow user_t self (process (execmem)))
(allow user_t chromium_t (process (noatsecure rlimitinh siginh)))
;!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access.
;Constraint rule:
; constrain dir { ioctl read write create getattr setattr lock relabelfrom relabelto append map unlink link rename execute quotaon mounton audit_access open execmod watch watch_mount watch_sb watch_with_perm watch_reads add_name remove_name reparent search rmdir } ((u1 == u2 -Fail-) or (u1 == system_u -Fail-) or (u1 == unconfined_u -Fail-) or (u1 == sysadm_u -Fail-) or (u2 == system_u -Fail-) or (t1 != ubac_constrained_type -Fail-) or (t2 != ubac_constrained_type -Fail-) or (t1 == ubacfile -Fail-) ); Constraint DENIED
; Possible cause is the source user (user_u) and target user (sysadm_u) are different.
(allow user_t user_home_dir_t (dir (getattr relabelto)))
Signed-off-by: Topi Miettinen <toiwoton@gmail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In libselinux there is an availability check for strlcpy() and
in both libselinux and libsepol there are availability checks for
reallocarray() in the src Makfiles. CFLAGS and LDFLAGS are needed
for cross-compiling, but, unfortunately, the default CFLAGS cause
all of these availability checks to fail to compile because of
compilationerrors (rather than just the function not being available).
Add CFLAGS and LDFLAGS to the availibility checks, update the checks
so that a compilation error will only happen if the function being
checked for is not available, and make checks for the same function
the same in both libselinux and libsepol.
Suggested-by: Jordan Williams <jordan@jwillikers.com>
Suggested-by: Winfried Dobbe <winfried_mb2@xmsnet.nl>
Signed-off-by: James Carter <jwcart2@gmail.com>
Since commit 65c8fd45 ("libselinux: fail selabel_open(3) on invalid
option") selabel_open(3) rejects options not supported for the
respective backend. Pass SELABEL_OPT_BASEONLY only if the file backend
is selected.
Reported-by: zgzxx (https://github.com/SELinuxProject/selinux/issues/427)
Fixes: 65c8fd45 ("libselinux: fail selabel_open(3) on invalid option")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In case the init function for a selabel backend fails, free the possible
already allocated data:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x5e7e2bf001e3 in malloc (/tmp/destdir/usr/sbin/selabel_digest+0xc71e3)
#1 0x7233764baa65 in selabel_media_init /home/christian/Coding/workspaces/selinux/libselinux/src/label_media.c:226:30
#2 0x7233764ac1fe in selabel_open /home/christian/Coding/workspaces/selinux/libselinux/src/label.c:227:6
#3 0x5e7e2bf3ebfc in main /home/christian/Coding/workspaces/selinux/libselinux/utils/selabel_digest.c:125:8
#4 0x7233761856c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: AddressSanitizer: 16 byte(s) leaked in 1 allocation(s).
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In case the specfiles have very long paths or there are too many abort
instead of writing past the stack buffer.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Avoid global variable.
Constify read-only parameters.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The command line option -d is not supported, drop from usage message.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In addition to standard SELinux platform policies also check Xen ones.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
If MLS support is enabled check the policy version supports MLS.
Reported-by: oss-fuzz (issue #67322)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Inform bison about an invalid character by returning YYerror, so the
parser can cleanup internal state and return the failure via yyparse().
Currently the error is only observable via the global variable
policydb_errors, which needs to be checked separately.
Reported-by: oss-fuzz (issue #67270)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In case of aliases clone the level only once to avoid leaking the fist
one.
Example policy:
class p sid h class p{d}sensitivity d alias s0;dominance{s0}level d;level s0;
Reported-by: oss-fuzz (issue #67308)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The level_datum_t member notdefined is checked to be 1 during validation
and the fuzzer calls policydb_validate().
Drop the redundant check (as announced in the TODO).
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The function sepol_av_to_string() normally returns a list of
permissions with a space at the beginning, but it will return '\0'
if there are no permissions. Unfortunately, functions in
kernel_to_cil, kernel_to_conf, and module_to_cil assume there is a
space at the beginning and skip the space by using "perms+1".
In kernel_to_cil, kernel_to_conf, and module_to_cil, check for the
permission string being '\0' and return an error if it is.
Reported-by: oss-fuzz (issue 67276)
Signed-off-by: James Carter <jwcart2@gmail.com>
Currently sepolgen fails to parse the reference policy:
Parsing interface files:
%--10---20---30---40---50---60---70---80---90--100
#############/tmp/destdir/usr/share/selinux/refpolicy/include/kernel/kernel.if: Syntax error on line 1737 - [type=MINUS]
/tmp/destdir/usr/share/selinux/refpolicy/include/kernel/kernel.if: Syntax error on line 1755 - [type=MINUS]
error parsing file /tmp/destdir/usr/share/selinux/refpolicy/include/kernel/kernel.if: could not parse text: "/tmp/destdir/usr/share/selinux/refpolicy/include/kernel/kernel.if: Syntax error on line 1755 - [type=MINUS]"
/tmp/destdir/usr/share/selinux/refpolicy/include/kernel/selinux.if: Syntax error on line 43 - [type=MINUS]
error parsing file /tmp/destdir/usr/share/selinux/refpolicy/include/kernel/selinux.if: could not parse text: "/tmp/destdir/usr/share/selinux/refpolicy/include/kernel/selinux.if: Syntax error on line 43 - [type=MINUS]"
############################/tmp/destdir/usr/share/selinux/refpolicy/include/services/ssh.if: Syntax error on line 183 $1_port_forwarding [type=IDENTIFIER]
/tmp/destdir/usr/share/selinux/refpolicy/include/services/ssh.if: Syntax error on line 293 ' [type=SQUOTE]
error parsing file /tmp/destdir/usr/share/selinux/refpolicy/include/services/ssh.if: could not parse text: "/tmp/destdir/usr/share/selinux/refpolicy/include/services/ssh.if: Syntax error on line 293 ' [type=SQUOTE]"
######/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2137 true [type=TRUE]
/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2148 ' [type=SQUOTE]
/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2152 ' [type=SQUOTE]
/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2163 ' [type=SQUOTE]
/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2167 ' [type=SQUOTE]
error parsing file /tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: could not parse text: "/tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if: Syntax error on line 2167 ' [type=SQUOTE]"
##failed to parse some headers: /tmp/destdir/usr/share/selinux/refpolicy/include/kernel/kernel.if, /tmp/destdir/usr/share/selinux/refpolicy/include/kernel/selinux.if, /tmp/destdir/usr/share/selinux/refpolicy/include/services/ssh.if, /tmp/destdir/usr/share/selinux/refpolicy/include/system/init.if
Missing interface definition for init_startstop_service
Missing interface definition for init_startstop_service
...
Accept chained ifelse blocks, genfscon statements with file specifiers,
and booleans with unquoted identifiers.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Commit fe16f586 (Fix potential double free of mls_level_t) renamed
the "defined" field to "notdefined", but did not update this use of
it.
Use the new field "notdefined" for the check.
Signed-off-by: James Carter <jwcart2@gmail.com>
In checkpolicy, a sensitivity that has one or more aliases will
temporarily share the mls_level_t structure with its aliases until
a level statement is processed for the sensitivity (or one of the
aliases) and the aliases are updated to have their own mls_level_t
structure. If the policydb is destroyed while they are sharing the
mls_level_t structure, then a double free of the shared mls_level_t
will occur. This does not currently occur only because checkpolicy
does very little clean-up before exiting.
The "defined" field of the level_datum_t is set after a level
statement is processed for a sensitivity and its aliases. This means
that we know an alias has its own mls_level_t if the "defined" field
is set. The double free can be avoided by not destroying the
mls_leve_t structure for an alias unless the "defined" field is set.
Since the "defined" field is only set to false while the mls_level_t
structure is being shared, it would be clearer to rename the field
as "notdefined". It would only be set during the time the sensitivity
and its aliases are sharing the mls_level_t structure. Outside of
checkpolicy, the "notdefined" field will always be set to 0.
Also, do more validation of the level_datum_t when validating the
policydb.
Signed-off-by: James Carter <jwcart2@gmail.com>
When trying to add a record with a key that already exists, modify
the existing record instead.
Also, fix "semanage -m -e" (add_equal was called instead of
modify_equal), which meant that existing local equivalency couldn't be
modified (though a user could remove it and add a modified
equivalency).
Fixes:
https://github.com/SELinuxProject/selinux/issues/412
When a port or login definition present in the policy is modified
using "semanage port -m", "semanage export" exports the command as
"port -a" instead of "port -m". This results in "semanage import"
failing (port already defined). The same is true for port, user,
login, ibpkey, ibendport, node, interface and fcontext.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
Entries in file_contexts.local are processed from the most recent one to
the oldest, with first match being used. Therefore it is important to
preserve their order when listing (semanage fcontext -lC) and exporting
(semanage export).
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
Ensure comparison functions used by qsort(3) fulfill transitivity, since
otherwise the resulting array might not be sorted correctly or worse[1]
in case of integer overflows.
[1]: https://www.qualys.com/2024/01/30/qsort.txt
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Ensure comparison functions used by qsort(3) fulfill transitivity, since
otherwise the resulting array might not be sorted correctly or worse[1]
in case of integer overflows.
[1]: https://www.qualys.com/2024/01/30/qsort.txt
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Ensure comparison functions used by qsort(3) fulfill transitivity, since
otherwise the resulting array might not be sorted correctly or worse[1]
in case of integer overflows.
[1]: https://www.qualys.com/2024/01/30/qsort.txt
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Sync function parameter names.
Drop superfluous return value.
The function avrule_merge_ioctls() has no failure conditions and
always returns 0.
Drop duplicate include.
Use native type for ranges.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Only assign the computed value on success, since it is not set by
declare_symbol() on failure.
Reported by GCC:
module_compiler.c: In function 'create_role':
module_compiler.c:287:24: warning: use of uninitialized value 'value' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
287 | datum->s.value = value;
| ~~~~~~~~~~~~~~~^~~~~~~
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Free the temporary bounds type in the error branches.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Provide more descriptive error messages by including the identifier
or other kind of value if available.
Also drop duplicate newlines at the end of messages.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Convert the only usage of the raw type struct level_datum to use the
typedef. Simplifies refactorizations on the type.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Return early on invalid roles in user definition.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Calling the parser macro YYABORT allows the parser to cleanup up any
allocated resources before returning.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The passed expression needs to be transferred into the policy or free'd
by the sink functions define_constraint() and define_validatetrans().
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Free identifiers removed from the queue but not yet owned by the policy
on errors.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>