Commit Graph

2884 Commits

Author SHA1 Message Date
Petr Lautrbach
142826a38e libselinux: fix segfault in add_xattr_entry()
When selabel_get_digests_all_partial_matches(), resp
get_digests_all_partial_matches() doesn't find a match,
calculated_digest is not initialized and followup memcmp() could
segfault. Given that calculated_digest and xattr_digest are already
compared in get_digests_all_partial_matches() and the function returns
true or false based on this comparison, it's not necessary to compare
these values again.

Fixes:
    # cd /root
    # mkdir tmp
    # restorecon -D -Rv tmp  # create security.sehash attribute
    # restorecon_xattr -d -v tmp
    specfiles SHA1 digest: afc752f47d489f3e82ac1da8fd247a2e1a6af5f8
    calculated using the following specfile(s):
    /etc/selinux/targeted/contexts/files/file_contexts.subs_dist
    /etc/selinux/targeted/contexts/files/file_contexts.subs
    /etc/selinux/targeted/contexts/files/file_contexts.bin
    /etc/selinux/targeted/contexts/files/file_contexts.homedirs.bin
    /etc/selinux/targeted/contexts/files/file_contexts.local.bin

    Segmentation fault (core dumped)

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-24 10:52:52 +01:00
James Carter
0861c659b5 libsepol: Validate policydb values when reading binary policy
Nicolas Iooss reports that fuzzing /usr/libexec/hll/pp with the
American Fuzzy Lop revealed that inconsistent policy modules could be
created that caused NULL dereferences and other problems.

When reading in a binary modular or kernel policy, check values in the
policydb to verify consistency. When reading in the data for commons,
classes, roles, types, users, booleans, sensitivities, and categories
verify that their value is between 1 and the number of primary
identifiers (value-1 is used to index the sym_val_to_name array for
all of these and the val_to_struct array for classes, roles, users,
and types.) Next all references in policy rules are checked to ensure
that they refer to a valid value.

It is possible for the type and role struct and name arrays to have
gaps in them. For roles, there will be gaps in the case of a kernel
policy created from a policy with role attributes, but nothing in the
policy will refer to any of the gaps. For types, there will be gaps
for any kernel policy with a version from 20 to 23, but, unfortunately,
there will be references to the gaps. This is because, while attributes
exist in these policies, they only exist in the type_attr_map. For
policies with versions between 20 and 23, it must be assumed that all
of the gaps and any references to them are valid. To check for
references to gaps, bitmaps are created to map where the gaps are and
all values are verified to be within the proper range and not within a
gap.

Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: James Carter <jwcart2@gmail.com>
2021-02-19 16:34:47 +01:00
James Carter
8f5409cf4c libsepol: Create function ebitmap_highest_set_bit()
Create the function ebitmap_highest_set_bit() which returns the position
of the highest bit set in the ebitmap.

The return value is valid only if the ebitmap is not empty. An empty
ebitmap will return 0.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-02-19 16:30:11 +01:00
Dominick Grift
49ff851c98 secilc: fixes cil_role_statements.md example
Signed-off-by: Dominick Grift <dominick.grift@defensec.nl>
Acked-by: James Carter <jwcart2@gmail.com>
2021-02-19 15:19:50 +01:00
Nicolas Iooss
398d2ceef9 libselinux: rename gettid() to something which never conflicts with the libc
Musl recently added a wrapper for gettid() syscall. There is no way to
detect this new version in a reliable way, so rename our gettid()
wrapper to a non-conflicting name.

Introduce a new function which, when using a libc known to provide a
wrapper for gettid(), calls it, and which, otherwise, performs the
syscall directly.

Anyway this function is only used on systems where /proc/thread-self
does not exist, which are therefore running Linux<3.17.

Fixes: https://github.com/SELinuxProject/selinux/issues/282
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-19 15:19:31 +01:00
Vit Mojzis
8f0f0a28aa selinux(8,5): Describe fcontext regular expressions
Describe which type of regular expression is used in file context
definitions and which flags are in effect.

Explain how local file context modifications are processed.

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-19 15:18:05 +01:00
Christian Göttsche
5682c0d5f6 policycoreutils/fixfiles.8: add missing file systems and merge check and verify
Mention the supported file systems ext4, gfs2 and btrfs.

The options check and verify are interchangeable, merge their
description.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-19 15:15:37 +01:00
Christian Göttsche
9cc6b5cf40 libselinux/getconlist: report failures
Check the given context a priori, to print a more user friendly message,
opposed to a generic following get_ordered_context_list/_with_level
failure.

Notify the user about failures of get_ordered_context_list/_with_level,
so no-context-found and a failure results are distinguishable.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-02-19 15:15:11 +01:00
James Carter
0451adebdf libsepol/cil: Destroy disabled optional blocks after pass is complete
Nicolas Iooss reports:
  I am continuing to investigate OSS-Fuzz crashes and the following one
  is quite complex. Here is a CIL policy which triggers a
  heap-use-after-free error in the CIL compiler:

  (class CLASS (PERM2))
  (classorder (CLASS))
  (classpermission CLSPRM)
  (optional o
      (mlsvalidatetrans x (domby l1 h1))
      (common CLSCOMMON (PERM1))
      (classcommon CLASS CLSCOMMON)
  )
  (classpermissionset CLSPRM (CLASS (PERM1)))

  The issue is that the mlsvalidatetrans fails to resolve in pass
  CIL_PASS_MISC3, which comes after the resolution of classcommon (in
  pass CIL_PASS_MISC2). So:

  * In pass CIL_PASS_MISC2, the optional block still exists, the
  classcommon is resolved and class CLASS is linked with common
  CLSCOMMON.
  * In pass CIL_PASS_MISC3, the optional block is destroyed, including
  the common CLSCOMMON.
  * When classpermissionset is resolved, function cil_resolve_classperms
  uses "common_symtab = &class->common->perms;", which has been freed.
  The use-after-free issue occurs in __cil_resolve_perms (in
  libsepol/cil/src/cil_resolve_ast.c):

    // common_symtab was freed
    rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum);

The fundamental problem here is that when the optional block is
disabled it is immediately destroyed in the middle of the pass, so
the class has not been reset and still refers to the now destroyed
common when the classpermissionset is resolved later in the same pass.

Added a list, disabled_optionals, to struct cil_args_resolve which is
passed when resolving the tree. When optionals are disabled, they are
now added to this list and then are destroyed after the tree has been
reset between passes.

Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-17 18:27:39 +01:00
bauen1
038817036f secilc/docs: add custom color theme
Since the default pandoc themes either don't highlight everything or
don't fit the black/white color style of the html / pdf I've created my
own.

Signed-off-by: Jonathan Hettwer <j2468h@gmail.com>
2021-02-16 09:32:36 -05:00
bauen1
4c8d609498 secilc/docs: add syntax highlighting for secil
This is done by creating a somewhat rudimentary KDE syntax xml for
pandoc.

The default styles provided by pandoc don't look very good and don't
highlight e.g. the strings marked as builtin.

Signed-off-by: Jonathan Hettwer <j2468h@gmail.com>
2021-02-16 09:32:32 -05:00
bauen1
057d72af2d secilc/docs: use fenced code blocks for cil examples
Also fixes the occasional missing brackets as higlighted by my editor,
however the individual examples where not reviewed much closer.

secilc was chosen as language name because the compiler is named secilc
and outside of SELinux the name cil is less searchable and could lead to
confusion.

Signed-off-by: Jonathan Hettwer <j2468h@gmail.com>
2021-02-16 09:32:29 -05:00
Nicolas Iooss
32f8ed3d6b libsepol/cil: introduce intermediate cast to silence -Wvoid-pointer-to-enum-cast
clang 11.0.0 reports the following warning several times (when building
with "make CC=clang" from libsepol directory, in the default
configuration of the git repository):

    ../cil/src/cil_binary.c:1980:8: error: cast to smaller integer type
    'enum cil_flavor' from 'void *' [-Werror,-Wvoid-pointer-to-enum-cast]
                    op = (enum cil_flavor)curr->data;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Silence this warning by casting the pointer to an integer the cast to
enum cil_flavor.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-16 09:30:57 -05:00
Nicolas Iooss
4662bdc11c libsepol/cil: be more robust when encountering <src_info>
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
to compile the following policy:

    (<src_info>)

In cil_gen_src_info(), parse_current->next is NULL even though the code
expects that both parse_current->next and parse_current->next->next
exists.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28457
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-16 09:30:53 -05:00
Nicolas Iooss
6b56105858 libsepol/cil: fix NULL pointer dereference with empty macro argument
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
to compile the following policy:

    (macro m((name n))) (call m(()))

When calling the macro, the name (in variable "pc") is NULL, which
triggers a NULL pointer dereference when using it as a key in
__cil_insert_name(). The stack trace is:

    #0 0x7f4662655a85 in __strlen_avx2 (/usr/lib/libc.so.6+0x162a85)
    #1 0x556d0b6d150c in __interceptor_strlen.part.0 (/selinux/libsepol/fuzz/fuzz-secilc+0x44850c)
    #2 0x556d0ba74ed6 in symhash /selinux/libsepol/src/symtab.c:22:9
    #3 0x556d0b9ef50d in hashtab_search /selinux/libsepol/src/hashtab.c:186:11
    #4 0x556d0b928e1f in cil_symtab_get_datum /selinux/libsepol/src/../cil/src/cil_symtab.c:121:37
    #5 0x556d0b8f28f4 in __cil_insert_name /selinux/libsepol/src/../cil/src/cil_resolve_ast.c:96:2
    #6 0x556d0b908184 in cil_resolve_call1 /selinux/libsepol/src/../cil/src/cil_resolve_ast.c:2835:12
    #7 0x556d0b91b404 in __cil_resolve_ast_node /selinux/libsepol/src/../cil/src/cil_resolve_ast.c
    #8 0x556d0b91380f in __cil_resolve_ast_node_helper /selinux/libsepol/src/../cil/src/cil_resolve_ast.c:3773:7
    #9 0x556d0b932230 in cil_tree_walk_core /selinux/libsepol/src/../cil/src/cil_tree.c:263:9
    #10 0x556d0b932230 in cil_tree_walk /selinux/libsepol/src/../cil/src/cil_tree.c:307:7
    #11 0x556d0b932326 in cil_tree_walk_core /selinux/libsepol/src/../cil/src/cil_tree.c:275:9
    #12 0x556d0b932326 in cil_tree_walk /selinux/libsepol/src/../cil/src/cil_tree.c:307:7
    #13 0x556d0b911189 in cil_resolve_ast /selinux/libsepol/src/../cil/src/cil_resolve_ast.c:3941:8
    #14 0x556d0b798729 in cil_compile /selinux/libsepol/src/../cil/src/cil.c:550:7

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28544
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-16 09:30:49 -05:00
James Carter
0d0e47c7eb libsepol/cil: Fix integer overflow in the handling of hll line marks
Nicolas Iooss reports:
  OSS-Fuzz found an integer overflow when compiling the following
  (empty) CIL policy:

  ;;*lms 2147483647 a
  ; (empty line)

Change hll_lineno to uint32_t which is the type of the field hll_line
in struct cil_tree_node where the line number will be stored eventually.
Read the line number into an unsigned long variable using strtoul()
instead of strtol(). On systems where ULONG_MAX > UINT32_MAX, return
an error if the value is larger than UINT32_MAX.

Also change hll_expand to uint32_t, since its value will be either
0 or 1 and there is no need for it to be signed.

Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: James Carter <jwcart2@gmail.com>
2021-02-10 08:06:10 -05:00
Nicolas Iooss
1b36ace21b
libsepol: include header files in source files when matching declarations
It is good practise in C to include the header file that specifies the
prototype of functions which are defined in the source file. Otherwise,
the function prototypes which be different, which could cause unexpected
issues.

Add the include directives to do this.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-05 10:19:34 +01:00
Nicolas Iooss
1f1fa9d47e
libsepol: uniformize prototypes of sepol_mls_contains and sepol_mls_check
In libsepol/src/mls.c, functions sepol_mls_contains and sepol_mls_check
used "sepol_policydb_t * policydb" even though
libsepol/include/sepol/context.h used "const sepol_policydb_t *
policydb".

Add const qualifiers in mls.c in order to match the header file. Detect
such mismatching error at compile time by including the header file in
mls.c.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-05 10:19:34 +01:00
Nicolas Iooss
72a88d753d
libsepol: remove unused files
libsepol/src/roles.c contains functions which do not match its header
file libsepol/include/sepol/roles.h:

    // In roles.c
    int sepol_role_exists(sepol_handle_t * handle __attribute__ ((unused)),
                          sepol_policydb_t * p, const char *role, int *response)
    // In roles.h
    extern int sepol_role_exists(const sepol_policydb_t * policydb,
                                 const char *role, int *response);

and:

    // In roles.c
    int sepol_role_list(sepol_handle_t * handle,
                        sepol_policydb_t * p, char ***roles, unsigned int *nroles)
    // In roles.h
    extern int sepol_role_list(const sepol_policydb_t * policydb,
                               char ***roles, unsigned int *nroles);

Instead of fixing the parameter type (using sepol_handle_t or
sepol_policydb_t but not different ones), remove these functions, as
they appear not to be used. They are not exported in libsepol.so.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-05 10:19:30 +01:00
Petr Lautrbach
2c7c4a84c3
Update VERSIONs to 3.2-rc2 for release.
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-03 11:26:28 +01:00
Nicolas Iooss
108c8edd95 scripts/release: make the script more robust, and release a source repository snapshot
Following Petr Lautrbach's suggestion, release a snapshot of the source
repository next to the individual archives which constitute a release.

While at it, make scripts/release more robust:

- Fix many warnings reported by shellcheck, by quoting strings.
- Use bash arrays for DIRS and DIRS_NEED_PREFIX
- Merge DIRS and DIRS_NEED_PREFIX into a single array, in order to
  produce SHA256 digests that are directly in alphabetical order, for
  https://github.com/SELinuxProject/selinux/wiki/Releases
- Use "set -e" in order to fail as soon as a command fails
- Change to the top-level directory at the start of the script, in order
  to be able to run it from anywhere.
- Use `cat $DIR/VERSION` and `git -C $DIR` instead of `cd $i ; cat VERSION`
  in order to prevent unexpected issues from directory change.

Finally, if version tags already exists, re-use them. This enables using
this script to re-generate the release archive (and check that they
really match the git repository). Currently, running scripts/release
will produce the same archives as the ones published in the 3.2-rc1
release (with the same SHA256 digests as the ones on the release page,
https://github.com/SELinuxProject/selinux/wiki/Releases). This helps to
ensure that the behaviour of the script is still fine.

Suggested-by: Petr Lautrbach <plautrba@redhat.com>
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-03 11:26:07 +01:00
James Carter
eba0ffee01 libsepol/cil: Fix heap-use-after-free when using optional blockinherit
This is based on a patch by Nicolas Iooss. He writes:
    When secilc compiles the following policy:

        (block b1
            (optional o1
                (blockinherit b1)
                (blockinherit x)
            )
        )

    it disables the optional block at pass 3 (CIL_PASS_BLKIN_LINK)
    because the block "x" does not exist.
    __cil_resolve_ast_last_child_helper() calls
    cil_tree_children_destroy() on the optional block, which destroys
    the two blockinherit statements. But the (blockinherit b1) node
    was referenced inside (block b1) node, in its block->bi_nodes list.
    Therefore, when this list is used at pass 4 (CIL_PASS_BLKIN_COPY),
    it contains a node which was freed: this triggers a use-after-free
    issue

    Fix this issue by removing blockinherit nodes from their lists of
    nodes block->bi_nodes when they are being destroyed. As
    cil_destroy_blockinherit() does not have a reference to the node
    containing the blockinherit data, implement this new logic in
    cil_tree_node_destroy().

    This issue was found while investigating a testcase from an OSS-Fuzz
    issue which seems unrelated (a Null-dereference READ in
    cil_symtab_get_datum,
    https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29861).

Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-03 10:44:01 +01:00
Nicolas Iooss
1048f8d329 libsepol/cil: unlink blockinherit->block link when destroying a block
The following CIL policy triggers a heap use-after-free in secilc
because when the blockinherit node is destroyed, the block node was
already destroyed:

    (block b2a)
    (blockinherit b2a)

Fix this by setting blockinherit->block to NULL when destroying block.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: James Carter <jwcart2@gmail.com>
2021-02-03 09:30:22 +01:00
Petr Lautrbach
57dd1f6520 policycoreutils/setfiles: Drop unused nerr variable
Suggested-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-03 09:29:28 +01:00
Nicolas Iooss
b320291888 libsepol/cil: fix memory leak when a constraint expression is too deep
When __cil_validate_constrain_expr() fails,
cil_constrain_to_policydb_helper() does not destroy the constraint
expression. This leads to a memory leak reported by OSS-Fuzz with the
following CIL policy:

    (class CLASS (PERM))
    (classorder (CLASS))
    (sid SID)
    (sidorder (SID))
    (user USER)
    (role ROLE)
    (type TYPE)
    (category CAT)
    (categoryorder (CAT))
    (sensitivity SENS)
    (sensitivityorder (SENS))
    (sensitivitycategory SENS (CAT))
    (allow TYPE self (CLASS (PERM)))
    (roletype ROLE TYPE)
    (userrole USER ROLE)
    (userlevel USER (SENS))
    (userrange USER ((SENS)(SENS (CAT))))
    (sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))

    (constrain
        (CLASS (PERM))
        (or
            (eq t1 TYPE)
            (or
                (eq t1 TYPE)
                (or
                    (eq t1 TYPE)
                    (or
                        (eq t1 TYPE)
                        (or
                            (eq t1 TYPE)
                            (eq t1 TYPE)
                        )
                    )
                )
            )
        )
    )

Add constraint_expr_destroy(sepol_expr) to destroy the expression.

Moreover constraint_expr_destroy() was not freeing all items of an
expression. Code in libsepol/src and checkpolicy contained while loop to
free all the items of a constraint expression, but not the one in
libsepol/cil. As freeing only the first item of an expression is
misleading, change the semantic of constraint_expr_destroy() to iterate
the list of constraint_expr_t and to free all items.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28938
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: James Carter <jwcart2@gmail.com>
2021-02-03 09:28:39 +01:00
Petr Lautrbach
c35919a703 libsemanage: sync filesystem with sandbox
Commit 331a109f91 ("libsemanage: fsync final files before rename")
added fsync() for policy files and improved situation when something
unexpected happens right after rename(). However the module store could
be affected as well. After the following steps module files could be 0
size:

1. Run `semanage fcontext -a -t var_t "/tmp/abc"`
2. Force shutdown the server during the command is run, or right after
   it's finished
3. Boot the system and look for empty files:
    # find /var/lib/selinux/targeted/ -type f -size 0 | wc -l
    1266

It looks like this situation can be avoided if the filesystem with the
sandbox is sync()ed before we start to rename() directories in the
store.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-02-01 15:11:40 +01:00
Petr Lautrbach
be7f54cb1f setfiles: drop ABORT_ON_ERRORS and related code
`setfiles -d` doesn't have any impact on number of errors before it
aborts. It always aborts on first invalid context in spec file.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-01 15:02:42 +01:00
Petr Lautrbach
9207823c8f setfiles: Do not abort on labeling error
Commit 602347c742 ("policycoreutils: setfiles - Modify to use
selinux_restorecon") changed behavior of setfiles. Original
implementation skipped files which it couldn't set context to while the
new implementation aborts on them. setfiles should abort only if it
can't validate a context from spec_file.

Reproducer:

    # mkdir -p r/1 r/2 r/3
    # touch r/1/1 r/2/1
    # chattr +i r/2/1
    # touch r/3/1
    # setfiles -r r -v /etc/selinux/targeted/contexts/files/file_contexts r
    Relabeled r from unconfined_u:object_r:mnt_t:s0 to unconfined_u:object_r:root_t:s0
    Relabeled r/2 from unconfined_u:object_r:mnt_t:s0 to unconfined_u:object_r:default_t:s0
    setfiles: Could not set context for r/2/1:  Operation not permitted

r/3 and r/1 are not relabeled.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-02-01 15:02:16 +01:00
Vit Mojzis
e12f71e82f python/sepolgen: allow any policy statement in if(n)def
"ifdef/ifndef" statements can be used to conditionally define
an interface, but this syntax is not recognised by sepolgen-ifgen.
Fix sepolgen-ifgen to allow any policy statement inside an
"ifdef/ifndef" statement.

Fixes:
        $ cat <<EOF > i.if
ifndef(`apache_manage_pid_files',`
        interface(`apache_manage_pid_files',`
                manage_files_pattern($1, httpd_var_run_t, httpd_var_run_t)
        ')
')

        #sepolgen-ifgen --interface=i.if
        i.if: Syntax error on line 2 interface [type=INTERFACE]
        i.if: Syntax error on line 4 ' [type=SQUOTE]

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
[OM: s/fidef/ifdef/]
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
2021-01-27 17:02:45 +01:00
James Carter
f0d98f83d2
libsepol/cil: Fix heap-use-after-free in __class_reset_perm_values()
Nicolas Iooss reports:
  A few weeks ago, OSS-Fuzz got configured in order to fuzz the CIL
  policy compiler (cf.
  https://github.com/SELinuxProject/selinux/issues/215 and
  https://github.com/google/oss-fuzz/pull/4790). It reported a bunch of
  simple issues, for which I will submit patches. There are also more
  subtle bugs, like the one triggered by this CIL policy:

  (class CLASS (PERM))
  (classorder (CLASS))
  (sid SID)
  (sidorder (SID))
  (sensitivity SENS)
  (sensitivityorder (SENS))
  (type TYPE)
  (allow TYPE self (CLASS (PERM)))

  (block b
      (optional o
          (sensitivitycategory SENS (C)) ; Non-existing category
  triggers disabling the optional
          (common COMMON (PERM1))
          (classcommon CLASS COMMON)
          (allow TYPE self (CLASS (PERM1)))
      )
  )

  On my computer, secilc manages to build this policy fine, but when
  clang's Address Sanitizer is enabled, running secilc leads to the
  following report:

  $ make -C libsepol/src CC=clang CFLAGS='-g -fsanitize=address' libsepol.a
  $ clang -g -fsanitize=address secilc/secilc.c libsepol/src/libsepol.a
  -o my_secilc
  $ ./my_secilc -vv testcase.cil
  Parsing testcase.cil
  Building AST from Parse Tree
  Destroying Parse Tree
  Resolving AST
  Failed to resolve sensitivitycategory statement at testcase.cil:12
  Disabling optional 'o' at testcase.cil:11
  Resetting declarations
  =================================================================
  ==181743==ERROR: AddressSanitizer: heap-use-after-free on address
  0x6070000000c0 at pc 0x55ff7e445d24 bp 0x7ffe7eecfba0 sp
  0x7ffe7eecfb98
  READ of size 4 at 0x6070000000c0 thread T0
      #0 0x55ff7e445d23 in __class_reset_perm_values
  /git/selinux-userspace/libsepol/src/../cil/src/cil_reset_ast.c:17:17

The problem is that the optional branch is destroyed when it is disabled,
so the common has already been destroyed when the reset code tries to
access the number of common permissions, so that it can change the
value of the class permissions back to their original values.

The solution is to count the number of class permissions and then
calculate the number of common permissions.

Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Signed-off-by: James Carter <jwcart2@gmail.com>
2021-01-20 16:53:39 +01:00
James Carter
5d021d6604
libsepol/cil: Update symtab nprim field when adding or removing datums
This field is suppose to be used to track the number of primary names in
the symtab. It was not being updated or used.

Increment the nprim field when a new datum is added to the symtab and
decrement the field when a datum is removed.

Signed-off-by: James Carter <jwcart2@gmail.com>
2021-01-20 16:53:38 +01:00
Christian Göttsche
156dd0de5c
libselinux: update getseuser
- Bail out if not running on a SELinux enabled system
- Check whether the passed context is valid
- Do not report a get_ordered_context_list_with_level failure on zero
  found contexts

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-01-20 16:53:37 +01:00
Christian Göttsche
e2dca5df40
libselinux: accept const fromcon in get_context API
Rework the APIs in <selinux/get_context_list.h> to take a constant
string as from context.

The passed string is not modified currently but not declared const,
which restricting callers (who care about const-correctness).

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
2021-01-20 16:53:34 +01:00
Nicolas Iooss
316a4f89dd
GitHub Actions: run SELinux testsuite in Fedora virtual machine
Use the Vagrant configuration in scripts/ci in a workflow for GitHub
Actions.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-20 16:45:12 +01:00
Petr Lautrbach
c534d4e2ce
Update VERSIONs and Python bindings version to 3.2-rc1 for release
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-01-20 12:40:14 +01:00
Petr Lautrbach
da4829d0be libselinux: Always close status page fd
According to mmap(2) after the mmap() call has returned, the file
descriptor, fd, can be closed immediately without invalidating the
mapping.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2021-01-18 07:37:28 -06:00
Vit Mojzis
b15dff0feb python/semanage: Sort imports in alphabetical order
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
2021-01-13 23:48:24 +01:00
Vit Mojzis
92e01969d0 python/semanage: empty stdout before exiting on BrokenPipeError
Empty stdout buffer before exiting when BrokenPipeError is
encountered. Otherwise python will flush the bufer during exit, which
may trigger the exception again.
https://docs.python.org/3/library/signal.html#note-on-sigpipe

Fixes:
   #semanage fcontext -l | egrep -q -e '^/home'
   BrokenPipeError: [Errno 32] Broken pipe
   Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
   BrokenPipeError: [Errno 32] Broken pipe

Note that the error above only appears occasionally (usually only the
first line is printed).

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-13 23:46:57 +01:00
Nicolas Iooss
34bd9a9d19 libsepol: destroy filename_trans list properly
OSS-Fuzz found a direct memory leak in policydb_filetrans_insert()
because filenametr_destroy() does not fully destroy the list associated
with a typetransition.

More precisely, let's consider this (minimized) CIL policy:

    (class CLASS (PERM))
    (classorder (CLASS))
    (sid SID)
    (sidorder (SID))
    (user USER)
    (role ROLE)
    (type TYPE) ; "type 1" in libsepol internal structures
    (type TYPE2) ; "type 2" in libsepol internal structures
    (type TYPE3) ; "type 3" in libsepol internal structures
    (category CAT)
    (categoryorder (CAT))
    (sensitivity SENS)
    (sensitivityorder (SENS))
    (sensitivitycategory SENS (CAT))
    (allow TYPE self (CLASS (PERM)))
    (roletype ROLE TYPE)
    (userrole USER ROLE)
    (userlevel USER (SENS))
    (userrange USER ((SENS)(SENS (CAT))))
    (sidcontext SID (USER ROLE TYPE ((SENS)(SENS))))

    (typetransition TYPE2 TYPE CLASS "some_file" TYPE2)
    (typetransition TYPE3 TYPE CLASS "some_file" TYPE3)

The two typetransition statements make policydb_filetrans_insert()
insert an item with key {ttype=1, tclass=1, name="some_file"} in the
hashmap p->filename_trans. This item contains a linked list of two
filename_trans_datum_t elements:

* The first one uses {otype=2, stypes=bitmap containing 2}
* The second one uses {otype=3, stypes=bitmap containing 3}

Nevertheless filenametr_destroy() (called by
hashtab_map(p->filename_trans, filenametr_destroy, NULL);) only frees
the first element. Fix this memory leak by freeing all elements.

This issue was introduced by commit 42ae834a74 ("libsepol,checkpolicy:
optimize storage of filename transitions") and was never present in the
kernel, as filenametr_destroy() was modified appropriately in commit
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c3a276111ea2572399281988b3129683e2a6b60b

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29138
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
2021-01-13 23:23:48 +01:00
Nicolas Iooss
bdf4e332b4 libsepol/cil: fix NULL pointer dereference when parsing an improper integer
OSS-Fuzz found a NULL pointer dereference when the CIL compiler tries to
compile a policy with an invalid integer:

    $ echo '(ioportcon(2())n)' > tmp.cil
    $ secilc tmp.cil
    Segmentation fault (core dumped)

This is because strtol() is called with a NULL pointer, in
cil_fill_integer().

Fix this by checking that int_node->data is not NULL. While at it, use
strtoul() instead of strtol() to parse an unsigned integer.

When using "val > UINT32_MAX" with "unsigned long val;", it is expected
that some compilers emit a warning when the size of "unsigned long" is
32 bits. In theory gcc could be such a compiler (with warning
-Wtype-limits, which is included in -Wextra). Nevertheless this is
currently broken, according to
https://gcc.gnu.org/pipermail/gcc-help/2021-January/139755.html and
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89126 (this bug was
opened in January 2019).

In order to prevent this warning from appearing, introduce some
preprocessor macros around the bound check.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28456
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Acked-by: James Carter <jwcart2@gmail.com>
2021-01-13 23:22:37 +01:00
Nicolas Iooss
b7ea65f547 libsepol/cil: destroy perm_datums when __cil_resolve_perms fails
When __cil_resolve_perms fails, it does not destroy perm_datums, which
leads to a memory leak reported by OSS-Fuzz with the following CIL
policy:

    (class cl01())
    (classorder(cl01))
    (type at02)
    (type tpr3)
    (allow at02 tpr3(cl01((s))))

Calling cil_list_destroy() fixes the issue.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28466
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-05 10:34:13 -05:00
Nicolas Iooss
228c06d97a libsepol/cil: fix out-of-bound read in cil_print_recursive_blockinherit
OSS-Fuzz found a heap buffer overflow (out-of-bound reads) when the CIL
compiler tries to report a recursive blockinherit with an optional
block:

    $ echo '(block b (optional o (blockinherit b)))' > tmp.cil
    $ secilc tmp.cil
    Segmentation fault (core dumped)

This is because cil_print_recursive_blockinherit() assumes that all
nodes are either CIL_BLOCK or CIL_BLOCKINHERIT. Add support for other
block kinds, using cil_node_to_string() to show them.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28462
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-05 10:33:55 -05:00
Nicolas Iooss
a25d9104ef libsepol/cil: constify some strings
Function cil_add_file() copies its input into a newly-allocated buffer,
and does not modify "name". State these properties in the types of
parameters by adding "const" qualifiers.

This enables using LibFuzzer directly on cil_add_file(), without a
warning about discarding "const" qualifier:

    fuzz-secilc.c: In function ‘LLVMFuzzerTestOneInput’:
    fuzz-secilc.c:57:31: warning: passing argument 3 of ‘cil_add_file’
    discards ‘const’ qualifier from pointer target type
    [-Wdiscarded-qualifiers]
       57 |  if (cil_add_file(db, "fuzz", data, size) != SEPOL_OK)
          |                               ^~~~
    In file included from fuzz-secilc.c:26:
    /usr/include/sepol/cil/cil.h:45:57: note: expected ‘char *’ but
    argument is of type ‘const uint8_t *’ {aka ‘const unsigned char *’}
       45 | extern int cil_add_file(cil_db_t *db, char *name, char *data, size_t size);
          |                                                   ~~~~~~^~~~

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-05 10:33:24 -05:00
Nicolas Iooss
e2d018423d libsepol/cil: propagate failure of cil_fill_list()
OSS-Fuzz found a Null-dereference READ in the CIL compiler when trying
to compile the following policy:

    (optional o (validatetrans x (eq t3 (a ()))))

With some logs, secilc reports:

    Invalid syntax
    Destroying Parse Tree
    Resolving AST
    Failed to resolve validatetrans statement at fuzz:1
    Disabling optional 'o' at tmp.cil:1

So there is an "Invalid syntax" error, but the compilation continues.
Fix this issue by stopping the compilation when cil_fill_list() reports
an error:

    Invalid syntax
    Bad expression tree for constraint
    Bad validatetrans declaration at tmp.cil:1

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29061
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-04 13:34:38 -05:00
Nicolas Iooss
6c8fca1045 libsepol/cil: do not add a stack variable to a list
OSS-Fuzz found a heap use-after-free when the CIL compiler destroys its
database after failing to compile the following policy:

    (validatetrans x (eq t3 (a)))

This is caused by the fact that the validatetrans AST object references
a stack variable local to __cil_fill_constraint_leaf_expr, when parsing
the list "(a)":

    struct cil_list *sub_list;
    cil_fill_list(current->next->next->cl_head, leaf_expr_flavor, &sub_list);
    cil_list_append(*leaf_expr, CIL_LIST, &sub_list);

Drop the & sign to really add the list like it is supposed to be.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28507
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-04 13:34:38 -05:00
Nicolas Iooss
38a09b7402 libsepol/cil: fix NULL pointer dereference when using an unused alias
OSS-Fuzz found a NULL pointer dereference when the CIL compiler tries to
compile a policy where a categoryalias references an unused
categoryalias:

    $ echo '(categoryalias c0)(categoryalias c1)(categoryaliasactual c0 c1)' > tmp.cil
    $ secil tmp.cil
    Segmentation fault (core dumped)

In such a case, a1 can become NULL in cil_resolve_alias_to_actual().
Add a check to report an error when this occurs. Now the error message
is:

    Alias c0 references an unused alias c1 at tmp.cil:1

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28471
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-04 13:34:38 -05:00
Nicolas Iooss
3c35728542 libsepol/cil: remove useless print statement
cil_copy_expandtypeattribute prints "cil_copy_expandtypeattribute 656"
which is quite annoying. Remove the fprintf statement responsible for
this.

While at it, remove another one in cil_tree_print_node()

Fixes: https://lore.kernel.org/selinux/3c2ab876-b0b7-42eb-573d-e5b450a7125a@gmail.com/T/#u
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2021-01-04 13:34:38 -05:00
Petr Lautrbach
5b05e829da
Revert "libsemanage/genhomedircon: check usepasswd"
This reverts commit ce46daab7c.

The behavior described in the reverted commit is correct. `useradd -Z`
creates new mapping between new created user and *unconfined_u*,
`genhomedircon` then uses this new mapping, not /etc/passwd entries, for
generating new homedir contexts.

Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
2020-12-27 11:27:57 +01:00
Jakub Hrozek
edae9275f6
libsemanage: Free contents of modkey in semanage_direct_remove
semanage_direct_remove allocates struct semanage_module_key_t on
stack, then calls semanage_module_key_set_name which allocates
modkey->name on heap, but modkey->name wasn't free()-d anywhere,
creating a small leak.

Signed-off-by: Jakub Hrozek <jhrozek@redhat.com>
2020-12-27 11:23:32 +01:00
Nicolas Iooss
af3e6789f0
GitHub Actions: drop Ruby 2.4 from matrix
When migrating to Ubuntu 20.04, Ruby 2.4 is no longer available, and
this migration is coming soon, according to
https://github.com/actions/virtual-environments/issues/1816.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2020-12-09 22:34:33 +01:00