Commit graph

3152 commits

Author SHA1 Message Date
James Carter
4878981229 libsepol/secilc/docs: Update the CIL documentation
Update the CIL documentation for the in-statement processing and
duplicate macro and block declarations with block inheritance.

Duplicate macro and block declarations are allowed if they occur as
the result of block inheritance. Document the fact that inherited
macros are overridden by any macros already declared in a
namespace and that declaring a block in a namespace that will
inherit a block with the same name can be used to allow in-statements
to be used on the block.

The new in-statement syntax still supports the old syntax but adds
the ability to specify whether the in-statement should be resolved
before or after block inheritance is resolved.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-07 10:28:46 -04:00
James Carter
68573634b4 libsepol/cil: Improve in-statement to allow use after inheritance
CIL's in-statement is resolved before block inheritance. This has
the advantage of allowing an in-statement to add rules to a base
block (say for a new permission) and having those rules also be
added everywhere that base block is inherited. But the disadvantage
of this behavior is that it is not possible to use an in-statement
on a block that is inherited for the simple reason that that block
does not exist when the in-statment is resolved.

Change the syntax of the in-statement to allow specifying whether
the rules should be added before or after inheritance. If neither
is specified, then the behavior remains the same. All current
in-statements will work as before.

Either the old syntax
  (in container_id
      cil_statement
      ...
  )
or the new syntax
  (in before|after container_id
      cil_statement
      ...
  )
may be used for in-statements. But only "(in after ..." will have
the new behavior. Using "(in before ..." will give the same
behavior as before.

Macro Example
;
(block b1
  (macro m1 ((type ARG1))
    (allow ARG1 self (C1 (P1a)))
  )
)
(in after b1.m1
  (allow ARG1 self (C1 (P1c)))
)
(type t1a)
(call b1.m1 (t1a))
(blockinherit b1)
(in after m1
  (allow ARG1 self (C1 (P1b)))
)
(type t1b)
(call m1 (t1b))
;
This results in the following rules:
  (allow t1a self (C1 (P1a)))
  (allow t1a self (C1 (P1c)))
  (allow t1b self (C1 (P1a)))
  (allow t1b self (C1 (P1b)))

Block Example
;
(block b2
  (block b
    (type ta)
    (allow ta self (C2 (P2a)))
  )
)
(in before b2.b
  (type tb)
  (allow tb self (C2 (P2b)))
)
(block c2
  (blockinherit b2)
  (in after b
    (type tc)
    (allow tc self (C2 (P2c)))
  )
)
;
This results in the following rules:
  (allow b2.b.ta self (C2 (P2a)))
  (allow b2.b.tb self (C2 (P2b)))
  (allow c2.b.ta self (C2 (P2a)))
  (allow c2.b.tb self (C2 (P2b)))
  (allow c2.b.tc self (C2 (P2c)))

Using in-statements on optionals also works as expected.

One additional change is that blockabstract and blockinherit rules
are not allowed when using an after in-statement. This is because
both of those are resolved before an after in-statement would be
resolved.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-07 10:28:27 -04:00
James Carter
2a6a883eed libsepol/cil: Simplify cil_tree_children_destroy()
Use a simpler recursive solution and set the head and tail pointers
of the starting node to NULL when done.

Remove the now uneeded setting of the head and tail pointers to NULL
in cil_resolve_in().

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:49:22 -04:00
James Carter
05e8f155d5 libsepol/cil: Refactor the function __cil_build_ast_node_helper()
Refactor the function __cil_build_ast_node_helper() by moving the
check for illegal statements and the large if-then-else statement
to determine which function to call to parse the policy statements
to different functions.

There is no need to keep walking the nodes of a policy statement
that has already been completely parsed. This means that the
remaining nodes of any policy statement that does not contain a list
of policy statements can be skipped. This was done inconsistently
before. The following policy statements now have all nodes after
the first one skipped: blockinherit, blockabstract, classcommon,
user, userattribute, userbounds, userprefix, type, typeattribute,
typealias, typealiasactual, typebounds, typepermissive, role,
userrole, roletype, roletransition, roleallow, roleattribute,
rolebounds, bool, tunable, typetransition, typechange, typemember,
sensitivity, sensitivityalias, senistivityaliasactual, category,
categoryalias, categoryaliasactual, and ipaddr. The only policy
statements that do contain a list of policy statements are:
block, in, tunableif, booleanif, true (conditional block), false
(conditional block), macro, optional, and src_info.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:49:18 -04:00
James Carter
3cbae1b68b libsepol/cil: Don't destroy optionals whose parent will be destroyed
If an optional that is to be disabled is the child of an optional that
is going to be disabled, then there is no reason to add that optional
to the stack of disabled optionals, because it is going to be destroyed
anyways. This means that there is no reason to maintain a stack of
disabled optionals at all.

Instead of using a stack to track disabled optionals, use a pointer
that points to the top-most optional that is to be disabled. When a
rule fails to resolve in an optional, if the disabled optional pointer
has not been set, then set it to that optional. If the pointer has
been set already, then the optional is already going to be destroyed,
so nothing else needs to be done. The resolution failure and the fact
that the optional is being disabled is reported in either case.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:49:14 -04:00
James Carter
05d1c66aaa libsepol/cil: Properly check for parameter when inserting name
File names for typetransition rules are stored in their own datums.
This allows them to be passed as a parameter, but there needs to be
a check in __cil_insert_name() so that parameter names are not
mistaken for file name strings. This check did not verify that a
matching parameter name had the flavor of CIL_NAME.

Check that the parameter flavor is CIL_NAME and that the paramter
name matches the file name to be stored in the datum.

This bug was found by the secilc-fuzzer.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:48:08 -04:00
James Carter
b57535318a libsepol/cil: Reset expandtypeattribute rules when resetting AST
A list is created to store type attribute datums when resolving an
expandtypeattribute rule and that list needs to be destroyed if the
AST is reset or a memory leak will occur.

Destroy the list storing type attributes datums when resetting
expandtypeattribute rules.

This bug was found by the secilc-fuzzer.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:48:02 -04:00
James Carter
4469c9796e libsepol/cil: Properly check parse tree when printing error messages
The function cil_tree_get_next_path() does not check whether the
parse tree node that stores the high-level language file path of a
src_info rule actually exists before trying to read the path. This
can result in a NULL dereference.

Check that all of the parse tree nodes of a src_info rule exist
before reading the data from them.

This bug was found by the secilc-fuzzer.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-09-02 10:47:59 -04:00
Michał Górny
ba23ba0683 python: Import specific modules from setools for less deps
Import the setools classes needed for Python bindings from specific
setools modules in order to reduce the dependency footprint
of the Python bindings.  Importing the top-level module causes all
setools modules to be loaded which includes the modules that require
networkx.

SELinux packages belong to the group of core system packages on Gentoo
Linux.  It is desirable to keep the system set as small as possible,
and the dependency between setools and networkx seems to be the easiest
link to break without major loss of functionality.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
2021-09-02 10:47:19 -04:00
Kelvin Zhang
8c21eeeace Improve error message for label file validation
Signed-off-by: Kelvin Zhang <zhangxp1998@gmail.com>
2021-08-23 10:30:10 -04:00
James Carter
8d197879f9 libsepol/cil: Allow some duplicate macro and block declarations
The commit d155b410d4 (libsepol/cil:
Check for duplicate blocks, optionals, and macros) added checks when
copying blocks, macros, and optionals so that a duplicate would cause
an exit with an error. Unfortunately, some policies exist that depend
on this behavior when using inheritance.

The behavior is as follows.

For macros only the first declared macro matters.
;
(macro m ((type ARG1))
  (allow ARG1 self (CLASS (PERM1)))
)
(block b
  (macro m ((type ARG1))
    (allow ARG1 self (CLASS (PERM2)))
  )
)
(blockinherit b)
(type t)
(call m (t))
;
For this policy segment, the macro m in block b will not be called.
Only the original macro m will be.

This behavior has been used to override macros that are going to
be inherited. Only the inherited macros that have not already been
declared in the destination namespace will be used.

Blocks seem to work fine even though there are two of them
;
(block b1
  (blockinherit b2)
  (block b
    (type t1)
    (allow t1 self (CLASS (PERM)))
  )
)
(block b2
  (block b
    (type t2)
    (allow t2 self (CLASS (PERM)))
  )
)
(blockinherit b1)
;
In this example, the blockinherit of b2 will cause there to be
two block b's in block b1. Note that if both block b's tried to
declare the same type, then that would be an error. The blockinherit
of b1 will copy both block b's.

This behavior has been used to allow the use of in-statements for
a block that is being inherited. Since the in-statements are resolved
before block inheritance, this only works if a block with the same
name as the block to be inherited is declared in the namespace.

To support the use of these two behaviors, allow duplicate blocks
and macros when they occur as the result of block inheritance. In
any other circumstances and error for a redeclaration will be given.

Since the duplicate macro is not going to be used it is just skipped.
The duplicate block will use the datum of the original block. In both
cases a warning message will be produced (it will only be seen if
"-v" is used when compiling the policy).

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:09:15 -04:00
James Carter
6a2508268d libsepol/cil: When writing AST use line marks for src_info nodes
In order to retain as much information as possible, when writing
out the CIL AST, use line mark notation to write out src_info
nodes. This includes using line marks to denote the original CIL
files the AST comes from.

The line numbers will not always be exactly correct because any
blank lines and comments in the original files will not be
represented in the AST.

Line marks are not written for the parse tree because the line
numbers will be widely inaccurate since each token will be on
a different line.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:09:03 -04:00
James Carter
28ae4adc44 libsepol/cil: Report correct high-level language line numbers
CIL supports specifiying the original high-level language file and
line numbers when reporting errors. This is done through line marks
and is mostly used to report the original Refpolicy file and line
number for neverallow rules that have been converted to CIL.

As long as the line mark remain simple, everything works fine, but
the wrong line numbers will be reported with more complex nextings
of line marks.

Example:
;;* lms 100 file01.hll
(type t1a)
(allow t1a self (CLASS (PERM)))
;;* lmx 200 file02.hll
(type t2a)
(allow t2a self (CLASS (PERM)))
;;* lme
(type t1b)
(allow t1b self (CLASS (PERM)))
(allow bad1b self (CLASS (PERM))) ; file01.hll:101 (Should be 106)
;;* lme

The primary problem is that the tree nodes can only store one hll
line number. Instead a number is needed that can be used by any
number of stacked line mark sections. This number would increment
line a normal line number except when in lmx sections (that have
the same line number throughout the section because they represent
an expansion of a line -- like the expansion of a macro call. This
number can go backwards when exiting a lms section within a lmx
section, because line number will increase in the lms section, but
outside the lmx section, the line number did not advance.

This number is called the hll_offset and this is the value that is
now stored in tree nodes instead of the hll line number. To calculate
the hll line number for a rule, a search is made for an ancestor of
the node that is a line mark and the line number for a lms section
is the hll line number stored in the line mark, plus the hll offset
of the rule, minus the hll offset of the line mark node, minus one.
(hll_lineno + hll_offset_rule - hll_offset_lm - 1)

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:59 -04:00
James Carter
fb9ed092da libsepol/cil: Add line mark kind and line number to src info
To be able to write line mark information when writing the AST,
the line mark kind and line number is needed in the src info.

Instead of indicating whether the src info is for CIL or a hll,
differentiate between CIL, a normal hll line mark, and an expanded
hll line mark. Also include the line mark line number in the src
info nodes.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:56 -04:00
James Carter
31aa43d258 libsepol/cil: Create common string-to-unsigned-integer functions
The functions cil_fill_integer() and cil_fill_integer64() exist in
cil_build_ast.c, but these functions take a node and it would be
better to have a function that can be used in add_hll_linemark()
so that the common functinality is in one place.

Create cil_string_to_uint32() and cil_string_to_uint64() and use
these functions in cil_fill_integer(), cil_fill_integer64(), and
add_hll_linemark().

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:54 -04:00
James Carter
0f12ee87ac libsepol/cil: Push line mark state first when processing a line mark
CIL line mark rules are used to annotate the original line and file
of a rule. It is mostly used for neverallow rules that have been
converted to CIL.

Pushing the current line mark state after processing a line mark
section does not make sense since that information is never used.
When the line mark section ends the information is just popped and
discarded. It also makes pop_hll_info() more complicated than it
needs to be.

Push the line mark state first and simplfy pop_hll_info().

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:51 -04:00
James Carter
4388801685 libsepol/cil: Check for valid line mark type immediately
It clearer to check that the line mark type is a valid option right
after getting the token.

Check that the line mark type is one of the expected values right
awasy.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:47 -04:00
James Carter
2b988acf44 libsepol/cil: Check the token type after getting the next token
In add_hll_linemark(), cil_lexer_next() is called and the token
type is not checked after the call for the expected type (SYMBOL).

Check that the token type is SYMBOL after calling cil_lexer_next().

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:44 -04:00
James Carter
8823bea1b0 libsepol/cil: Check syntax of src_info statement
Every rule other than src_info has their syntax checked when
building the AST. It wasn't considered necessary for src_info rules
because they were expected to always be generated by the parser and
aren't part of the CIL language. But there is no check preventing
them from occurring in a policy and the secilc fuzzer found some bugs
by using src_info rules in a policy. This caused some syntax checking
to be added. Since the parse AST from secil2tree will contain src_info
rules and since the goal is to be able to compile the output of
secil2tree, it makes sense to check the syntax of src_info rules
in the same way that all of the other rules are checked.

Check the syntax of src_info statements in the same way every other
rule is checked.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-08-19 11:08:40 -04:00
Evgeny Vereshchagin
33621cb7c8 libsepol/cil: move the fuzz target and build script to the selinux repository
It should make it easier to reproduce bugs found by OSS-Fuzz locally
without docker. The fuzz target can be built and run with the corpus
OSS-Fuzz has accumulated so far by running the following commands:
```
./scripts/oss-fuzz.sh
wget https://storage.googleapis.com/selinux-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/selinux_secilc-fuzzer/public.zip
unzip -d CORPUS public.zip
./out/secilc-fuzzer CORPUS/
```

It was tested in https://github.com/google/oss-fuzz/pull/6026
by pointing OSS-Fuzz to the branch containing the patch and
running all the tests with all the sanitizers and fuzzing engines
there: https://github.com/google/oss-fuzz/actions/runs/1024673143

[v2]
[1] oss-fuzz: make shellcheck happy

[2] oss-fuzz: build libsepol only

The fuzz target covers libsepol so it's unnecessary to build everything
else. Apart from that, the "LDFLAGS" kludge was removed since libsepol
is compatible with the sanitizers flags passed via CFLAGS only. It
should be brought back one way or another eventually though to fix
build failures like
```
clang -L/home/vagrant/selinux/selinux/DESTDIR/usr/lib -L/home/vagrant/selinux/selinux/DESTDIR/usr/lib -L../src  sefcontext_compile.o ../src/regex.o  -lselinux  -lpcre  ../src/libselinux.a -lsepol -o sefcontext_compile
/usr/bin/ld: sefcontext_compile.o: in function `usage':
/home/vagrant/selinux/selinux/libselinux/utils/sefcontext_compile.c:271: undefined reference to `__asan_report_load8'
/usr/bin/ld: /home/vagrant/selinux/selinux/libselinux/utils/sefcontext_compile.c:292: undefined reference to `__asan_handle_no_return'
/usr/bin/ld: sefcontext_compile.o: in function `asan.module_ctor':
```

[3] oss-fuzz: make it possible to run the script more than once
by removing various build artifacts

[4] oss-fuzz: make it possible to run the script from any directory

[5] oss-fuzz: be a little bit more specific about what the script does

[6] oss-fuzz: stop overwriting all the Makefiles

Signed-off-by: Evgeny Vereshchagin <evvers@ya.ru>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-08-17 10:33:47 -04:00
Christian Göttsche
f068bdcf2d libsepol: replace strerror by %m
The standard function `strerror(3)` is not thread safe.  This does not
only affect the concurrent usage of libselinux itself but also with
other `strerror(3)` linked libraries.
Use the thread safe GNU extension format specifier `%m`[1].

libselinux already uses the GNU extension format specifier `%ms`.

[1]: https://www.gnu.org/software/libc/manual/html_node/Other-Output-Conversions.html

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-08-10 14:21:28 -04:00
Christian Göttsche
2d4904284f libselinux: replace strerror by %m
The standard function `strerror(3)` is not thread safe.  This does not
only affect the concurrent usage of libselinux itself but also with
other `strerror(3)` linked libraries.
Use the thread safe GNU extension format specifier `%m`[1].

libselinux already uses the GNU extension format specifier `%ms`.

[1]: https://www.gnu.org/software/libc/manual/html_node/Other-Output-Conversions.html

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-08-10 14:21:28 -04:00
Petr Lautrbach
cedcbaa824 mcstrans: Improve mlstrans-test output
Fixes:
    trans: a🅱️c:s9 -> a🅱️c:TOP SECRET != a🅱️c:TOP SECRET SUCCESS
    untrans: a🅱️c:T O P S E C R E T -> a🅱️c:s9 != a🅱️c:s9 SUCCESS

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
2021-08-10 12:25:14 -04:00
Ondrej Mosnacek
d0f9a58920 libsepol/cil: remove obsolete comment
Commit a60343cabf ("libsepol/cil: remove unnecessary hash tables")
removed FILENAME_TRANS_TABLE_SIZE macro that this comment was referring
to. Remove the comment as well to avoid confusion.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
2021-08-05 09:55:18 -04:00
Petr Lautrbach
e8b98f67f6 python/sepolicy: Fix COPY_PASTE_ERROR (CWE-398)
Fixes:
    Error: COPY_PASTE_ERROR (CWE-398): [#def3]
    selinux/python/sepolicy/sepolicy/__init__.py:1032: original: ""_key_t"" looks like the original copy.
    selinux/python/sepolicy/sepolicy/__init__.py:1035: copy_paste_error: ""_key_t"" looks like a copy-paste error.
    selinux/python/sepolicy/sepolicy/__init__.py:1035: remediation: Should it say ""_secret_t"" instead?
    # 1033|
    # 1034|       if f.endswith("_secret_t"):
    # 1035|->         return txt + "treat the files as %s secret data." % prettyprint(f, "_key_t")
    # 1036|
    # 1037|       if f.endswith("_ra_t"):

    Error: COPY_PASTE_ERROR (CWE-398): [#def4]
    selinux/python/sepolicy/sepolicy/__init__.py:1065: original: ""_tmp_t"" looks like the original copy.
    selinux/python/sepolicy/sepolicy/__init__.py:1067: copy_paste_error: ""_tmp_t"" looks like a copy-paste error.
    selinux/python/sepolicy/sepolicy/__init__.py:1067: remediation: Should it say ""_etc_t"" instead?
    # 1065|           return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
    # 1066|       if f.endswith("_etc_t"):
    # 1067|->         return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
    # 1068|       if f.endswith("_home_t"):
    # 1069|           return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t")

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-07-30 09:55:33 -04:00
Petr Lautrbach
8b38b04571 dbus: Use GLib.MainLoop()
Fixes:
    PyGIDeprecationWarning: GObject.MainLoop is deprecated; use GLib.MainLoop instead

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-07-28 15:01:56 -04:00
Petr Lautrbach
3f9ff90f9e Do not use Python slip
Python slip is not actively maintained anymore and it was used just as
a polkit proxy. It looks like polkit dbus interface is quite simple to
be used directly via python dbus module.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-07-28 15:01:47 -04:00
Petr Lautrbach
d003c4bad4 libsemanage: Fix USE_AFTER_FREE (CWE-672) in semanage_direct_write_langext()
>From fclose(3):
Upon successful completion, 0 is returned.  Otherwise, EOF is returned
and errno is set to indicate the error. In either case, any further
access (including another call to fclose()) to the stream results in
undefined behavior.

Fixes:
    Error: USE_AFTER_FREE (CWE-672): [#def1]
    libsemanage-3.2/src/direct_api.c:1023: freed_arg: "fclose" frees "fp".
    libsemanage-3.2/src/direct_api.c:1034: use_closed_file: Calling "fclose" uses file handle "fp" after closing it.
    # 1032|
    # 1033|   cleanup:
    # 1034|-> 	if (fp != NULL) fclose(fp);
    # 1035|
    # 1036|   	return ret;

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-07-28 14:23:54 -04:00
Christian Göttsche
32611aea65 policycoreutils: free memory of allocated context in newrole
Found by scan-build.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Christian Göttsche
f0c354afc0 policycoreutils: free memory of allocated context in run_init
Found by scan-build.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Christian Göttsche
d8b9bd5c2a policycoreutils: free memory on lstat failure in sestatus
In case lstat(3) fails the memory is not free'd at the end of the for
loop, due to the control flow change by continue.

Found by scan-build.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Christian Göttsche
6d93701f39 secilc: fix memory leaks in secilc2conf
When specifying -o more than once, the previous allocation leaks.

Found by scan-build.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Christian Göttsche
edb948fb0b secilc: fix memory leaks in secilc
When specifying -o or -f more than once, the previous allocations leak.

Found by scan-build.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Christian Göttsche
54667cdb37 scripts/run-scan-build: update
- use multiple jobs
- define _FORTIFY_SOURCE=2 to enable checks on standard string handling
  functions due to macro/intrinsic overloads or function attributes
- allow to override clang and scan-build binaries, i.e. for using
  versioned ones
- set PYTHON_SETUP_ARGS accordingly on Debian
- enable common warning -Wextra
- print build result

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-19 10:42:45 -04:00
Nicolas Iooss
af29a23553
libsepol/cil: do not allow \0 in quoted strings
Using the '\0' character in strings in a CIL policy is not expected to
happen, and makes the flex tokenizer very slow. For example when
generating a file with:

    python -c 'print("\"" + "\0"*100000 + "\"")' > policy.cil

secilc fails after 26 seconds, on my desktop computer. Increasing the
numbers of \0 makes this time increase significantly. But replacing \0
with another character makes secilc fail in only few milliseconds.

Fix this "possible denial of service" issue by forbidding \0 in strings
in CIL policies.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36016

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-07-13 21:05:03 +02:00
James Carter
8470058934
libsepol/cil: Fix handling category sets in an expression
There are two problems that need to be addressed when resolving an
expression with category sets.

1. Only expand anonymous category sets in an expression.

Commit 982ec302b6 (libsepol/cil:
Account for anonymous category sets in an expression) attempted to
properly handle anonymous category sets when resolving category
expressions. Unfortunately, it did not check whether a category set
was actually an anonymous category set and expanded all category
sets in an expression. If a category set refers to itself in the
expression, then everything from the name of the category set to the
end of the expression is ignored.

For example, the rule "(categoryset cs (c0 cs c1 c2))", would be
equivalent to the rule "(categoryset cs (c0))" as everything from
"cs" to the end would be dropped. The secilc-fuzzer found that the
rule "(categoryset cat (not cat))" would cause a segfault since
"(not)" is not a valid expression and it is assumed to be valid
during later evaluation because syntax checking has already been
done.

Instead, check whether or not the category set is anonymous before
expanding it when resolving an expression.

2. Category sets cannot be used in a category range

A category range can be used to specify a large number of categories.
The range "(range c0 c1023)" refers to 1024 categories. Only categories
and category aliases can be used in a range. Determining if an
identifier is a category, an alias, or a set can only be done after
resolving the identifer.

Keep track of the current operator as an expression is being resolved
and if the expression involves categories and a category set is
encountered, then return an error if the expression is a category
range.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-07-13 21:04:54 +02:00
Evgeny Vereshchagin
e45642441f
README: add OSS-Fuzz/CIFuzz badges
It should make it easier to keep track of what's going on there

Signed-off-by: Evgeny Vereshchagin <evvers@ya.ru>
2021-07-13 21:03:30 +02:00
Evgeny Vereshchagin
a2a40f0345
ci: turn on CIFuzz
Now that almost all the bugs reported by OSS-Fuzz have been
fixed libsepol/cil should be stable enough to get CIFuzz working
more or less reliably. It should help to catch regressions/new bugs
faster.

https://google.github.io/oss-fuzz/getting-started/continuous-integration/

The patch was tested on GitHub in https://github.com/SELinuxProject/selinux/pull/285
The CIFuzz job can be found at https://github.com/SELinuxProject/selinux/actions/runs/1017865690

Signed-off-by: Evgeny Vereshchagin <evvers@ya.ru>
2021-07-13 21:03:29 +02:00
Christian Göttsche
1711757378
checkpolicy: mark read-only parameters in policy define const
Make it more obvious which parameters are read-only and not being
modified and allow callers to pass const pointers.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:10 +02:00
Christian Göttsche
b306cd5b90
checkpolicy/test: mark file local functions static
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:09 +02:00
Christian Göttsche
47f4cbd357
checkpolicy: parse_util drop unused declaration
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:09 +02:00
Christian Göttsche
4e3d0990c6
checkpolicy: drop redundant cast to the same type
Found by clang-tidy.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:09 +02:00
Christian Göttsche
5218bf4b26
checkpolicy: avoid potential use of uninitialized variable
checkpolicy.c: In function ‘main’:
    checkpolicy.c:1000:25: error: ‘tsid’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
     1000 |                         printf("if_sid %d default_msg_sid %d\n", ssid, tsid);
          |                         ^

    checkpolicy.c: In function ‘main’:
    checkpolicy.c:971:25: error: ‘tsid’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
      971 |                         printf("fs_sid %d default_file_sid %d\n", ssid, tsid);
          |                         ^

Found by GCC 11 with LTO enabled.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:09 +02:00
Christian Göttsche
5a10f05f53
checkpolicy: check before potential NULL dereference
policy_define.c: In function ‘define_te_avtab_extended_perms’:
    policy_define.c:1946:17: error: potential null pointer dereference [-Werror=null-dereference]
     1946 |         r->omit = omit;
          |                 ^

In the case of `r` being NULL, avrule_read_ioctls() would return
with its parameter `rangehead` being a pointer to NULL, which is
considered a failure in its caller `avrule_ioctl_ranges`.
So it is not necessary to alter the return value.

Found by GCC 11 with LTO enabled.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:08 +02:00
Christian Göttsche
7723180fa0
checkpolicy: remove dead assignments
The variable `cladatum` is otherwise always assigned before used, so
these two assignments without a follow up usages are not needed.

Found by clang-analyzer.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:08 +02:00
Christian Göttsche
79e7724930
checkpolicy: follow declaration-after-statement
Follow the project style of no declaration after statement.

Found by the GCC warning -Wdeclaration-after-statement.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:07 +02:00
Christian Göttsche
babc3d5351
checkpolicy: use correct format specifier for unsigned
test/dispol.c:288:4: warning: %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'. [invalidPrintfArgType_sint]
       snprintf(buf, sizeof(buf), "unknown (%d)", i);
       ^
    test/dismod.c:830:4: warning: %d in format string (no. 1) requires 'int' but the argument type is 'unsigned int'. [invalidPrintfArgType_sint]
       snprintf(buf, sizeof(buf), "unknown (%d)", i);
       ^

Found by Cppcheck.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:06 +02:00
Christian Göttsche
db674bf218
checkpolicy: drop dead condition
The variable `id` is guaranteed to be non-NULL due to the preceding
while condition.

    policy_define.c:1171:7: style: Condition '!id' is always false [knownConditionTrueFalse]
      if (!id) {
          ^
    policy_define.c:1170:13: note: Assuming that condition 'id=queue_remove(id_queue)' is not redundant
     while ((id = queue_remove(id_queue))) {
                ^
    policy_define.c:1171:7: note: Condition '!id' is always false
      if (!id) {
          ^

Found by Cppcheck.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:05 +02:00
Christian Göttsche
7cdb2a8fd2
checkpolicy: simplify assignment
checkpolicy.c:504:20: style: The statement 'if (policyvers!=n) policyvers=n' is logically equivalent to 'policyvers=n'. [duplicateConditionalAssign]
    if (policyvers != n)
                   ^
checkpolicy.c:505:17: note: Assignment 'policyvers=n'
     policyvers = n;
                ^
checkpolicy.c:504:20: note: Condition 'policyvers!=n' is redundant
    if (policyvers != n)
                   ^

Found by Cppcheck

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:05 +02:00
Christian Göttsche
02678b9d40
checkpolicy: drop -pipe compile option
The compiler option -pipe does not affect the generated code; it affects
whether the compiler uses temporary files or pipes. As the benefit might
vary from system to system usually its up to the packager or build
framework to set it.
Also these are the only places where the flag is used.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-07-13 21:02:04 +02:00