Add support for extended permission rules in conditional policies.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Example policy generated by fuzzer:
class s
sid k
class s { i }
optional{
require{
attribute i;
}
}
type m;
typealias m alias i;
typeai
Reported-by: oss-fuzz (issue 377576480)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
If declare_symbol() returns 1 the id and the datum are already defined
and not consumed by the function, so it they must be free'd by the
caller.
Example policy (generated by fuzzer):
class s sid e class s{i}optional{require{bool K;}bool K true;
Reported-by: oss-fuzz (issue 377544445)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
When a user is created in an optional block, a user datum is added
to both the avrule_decl's symtab and the policydb's symtab, but
the semantic MLS information is only added to the avrule_decl's
user datum. This causes an error to occur during policy expansion
when user_copy_callback() is called. If this error did not occur
then the policydb's user datum would be written without any MLS
info and the policy would fail validation when read later.
When creating a user datum, search for a user datum with the same
key in the policydb's symtab. If that datum has no MLS information,
then copy the MLS information from the avrule_decl's datum. If it
does, then compare the default level, low level, and high level
sensitivities and give an error if they do not match. There is not
enough information to expand the categories for the high and low
levels, so merge the semantic categories. If the two category sets
are not equal an error will occur during the expansion phase.
A minimum policy to demonstrate the bug:
class CLASS1
sid kernel
class CLASS1 { PERM1 }
sensitivity SENS1;
dominance { SENS1 }
level SENS1;
mlsconstrain CLASS1 { PERM1 } ((h1 dom h2) and (l1 domby h1));
type TYPE1;
allow TYPE1 self : CLASS1 PERM1;
role ROLE1;
role ROLE1 types TYPE1;
optional {
require {
role ROLE1;
}
user USER2 roles ROLE1 level SENS1 range SENS1;
}
user USER1 roles ROLE1 level SENS1 range SENS1;
sid kernel USER1:ROLE1:TYPE1:SENS1
Signed-off-by: James Carter <jwcart2@gmail.com>
Add support for AVTAB_XPERMS_NLMSG as extended permissions for netlink
sockets. The behaviour is similar to the existing
AVTAB_XPERMS_IOCTLFUNCTION.
Signed-off-by: Thiébaud Weksteen <tweek@google.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
The ioctl extended permission structures and functions can be reused for
other extended permissions. Use the more generic term "xperm" instead of
"ioctl".
Signed-off-by: Thiébaud Weksteen <tweek@google.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
The lower 64 bits of the subnet prefix for an ibpkeycon rule should
all be 0's. Unfortunately the check uses the s6_addr macro which refers
to the 16 entry array of 8-bit values in the union and does not refer
to the correct bits.
Use the s6_addr32 macro instead which refers to the 4 entry array of
32-bit values in the union and refers to the lower 64 bits.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reject multiple nodecon declarations with the same address and netmask.
Avoids mistakes when defining them in different places or using both the
address-with-netmask and CIDR-notation syntax.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Support the Classless Inter-Domain Routing (CIDR) notation for IP
addresses with their associated network masks in nodecon statements.
The two following statements are equivalent:
nodecon 10.8.0.0 255.255.0.0 USER1:ROLE1:TYPE1
nodecon 10.8.0.0/16 USER1:ROLE1:TYPE1
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The contiguous check for network masks requires host byte order on the
underlying integers.
Convert from network byte order to avoid wrong warnings.
Fixes: 01b88ac3 ("checkpolicy: warn on bogus IP address or netmask in nodecon statement")
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>
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>
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>
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>
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>
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>
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>
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>
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>
Close the input file and free all memory by the queue and lexer on a
syntax or parse error.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Introduce a libfuzz[1] based fuzzer testing the parsing and policy
generation code used within checkpolicy(8) and checkmodule(8), similar
to the fuzzer for secilc(8).
The fuzzer will work on generated source policy input and try to parse,
link, expand, optimize, sort and output it.
This fuzzer will also ensure policy validation is not too strict by
checking compilable source policies are valid.
Build the fuzzer in the oss-fuzz script.
[1]: https://llvm.org/docs/LibFuzzer.html
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In the internal function sepol_av_to_string(), use a dynamically
allocated buffer for the permission names of an access vector instead
of a fixed static buffer to support very long permission names.
Update the internal users of sepol_av_to_string() to free the buffer.
The exported function sepol_perm_to_string() is just a wrapper to
the internal function. To avoid changing the behavior of this function,
use a static buffer and copy the resulting string from the internal
function. If the string is too long for the buffer or there was an
error in creating the string, return a string indicating the error.
All of the changes to the internal function and users was the work
of Christian Göttsche <cgzones@googlemail.com>.
Reported-by: oss-fuzz (issue 64832, 64933)
Suggested-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: James Carter <jwcart2@gmail.com>
* add option to display users
* drop duplicate option to display booleans
* show number of entries before listing them
* drop global variable
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
This patch adds CPPFLAGS to all of the Makefiles as suggested.
Signed-off-by: Cameron Williams <ckwilliams.work@gmail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Avoid duplicate policydb initialization when reading a kernel policy.
One caller, main(), already performs the initialization. The other one,
link_module(), needs to do it also for the module policy case.
Also set the target platform to enable module linking.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>