Commit Graph

412 Commits

Author SHA1 Message Date
Nicolas Iooss
8ccd0db860 libsepol: do not free attr_name twice
When set_to_names() fails to allocate *names, it frees variable
attr_name even though it either came from attr_list or was newly created
and added to attr_list. By doing so, the name is freed a second time
when attr_list is destroyed (with "attr_list_destroy(&attr_list)").

Avoid this double free by not freeing attr_name when it belongs to
attr_list.

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-04-12 14:18:35 -04:00
Nicolas Iooss
3e7fd1daba libsepol: do not wrap integers when checking bound
Some invalid policies might have p->p_types.nprim = 0. When parsing
such a policy, "i > p->p_types.nprim - 1" is always false even though
reading p->type_val_to_struct[i] triggers a segmentation fault.

Make type_set_expand() return an error when parsing such a policy by
handling correctly when p->p_types.nprim is zero.

This issue has been found while fuzzing semodule_package with the
American Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-04-11 14:33:48 -04:00
Nicolas Iooss
42e32227da libsepol: refuse to load policies with no block
Some functions assumes that p->global is not NULL. For example
range_read() contains:

    p->global->enabled->range_tr_rules = rtr;

However p->global may currently be NULL when loading a policy module
with no avrule block. Avoid a NULL pointer dereference by making such a
policy invalid.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-04-11 14:33:04 -04:00
Stephen Smalley
e6edc42455 libsepol: do not seg fault on sepol_*_key_free(NULL)
sepol_*_key_free(NULL) should just be a no-op just like
free(NULL).  Fix several instances that did not handle this
correctly and would seg fault if called with NULL.

Test: setsebool -P zebra_write_config=1 while non-root

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2017-04-07 11:04:43 -04:00
James Carter
92f22e193a libsepol: In module_to_cil create one attribute for each unique set
CIL does not allow type or role sets in certain rules (such as allow
rules). It does, however, allow sets in typeattributeset and
roleattributeset statements. Because of this, when module_to_cil
translates a policy into CIL, it creates a new attribute for each
set that it encounters. But often the same set is used multiple times
which means that more attributes are created then necessary. As the
number of attributes increases the time required for the kernel to
make each policy decision increases which can be a problem.

To help reduce the number of attributes in a kernel policy,
when module_to_cil encounters a role or type set search to see if the
set was encountered already and, if it was, use the previously
generated attribute instead of creating a new one.

Testing on Android and Refpolicy policies show that this reduces the
number of attributes generated by about 40%.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-04-05 12:24:05 -04:00
James Carter
0a08fd1e69 libsepol: Add ability to convert binary policy to policy.conf file
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_conf(), that takes a
policydb created from a binary policy and writes a policy.conf file
to the provided FILE pointer.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-04-05 12:23:25 -04:00
James Carter
70a480bfcd libsepol: Add ability to convert binary policy to CIL
It would sometimes be helpful for debugging or verification purposes
to be able to convert a binary policy to a human-readable form.

Create new function, sepol_kernel_policydb_to_cil(), that takes a
policydb created from a binary policy and writes CIL policy to the
provided FILE pointer.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-04-05 12:23:05 -04:00
Nicolas Iooss
b251dbba98 libsepol: fix use-after-free in sepol_user_clone()
When sepol_user_add_role() fails to allocate memory for role_cp but
succeeds in reallocating user->roles memory, it frees this reallocated
memory, thus leaving user->roles referencing a free memory block. When
sepol_user_clone() calls sepol_user_free(new_user) because the
allocation failure made sepol_user_add_role() fail, the following code
is executed:

    for (i = 0; i < user->num_roles; i++)
        free(user->roles[i]);
    free(user->roles);

As user->roles has been freed, this code frees pointers which may be
invalid and then tries to free user->roles again.

Fix this flaw by returning right after strdup() failed in
sepol_user_add_role().

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-29 10:26:47 -04:00
Nicolas Iooss
b6579d262e libsepol: constify sepol_genbools()'s boolpath parameter
This allows removing an unnecessary cast to (char *) in libselinux.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-29 10:26:44 -04:00
Nicolas Iooss
76f8c04c19 libsepol: make process_boolean() fail on invalid lines
When load_booleans() calls process_boolean() to parse a boolean
definition, process_boolean() returns a successful value when it fails
to use strtok_r() (e.g. when there is no "=" in the parsed line). This
leads load_booleans() to use uninitialized name and/or val when setting
the boolean into the policy.

Rework process_boolean() in order to report errors when a boolean
definition is incorrect.

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-29 10:26:40 -04:00
Nicolas Iooss
a83f1cfd7e libsepol: do not dereference a NULL pointer when stack_init() fails
In cond_expr_to_cil() when stack_init(&stack) fails, stack is set to
NULL and the execution flow jumps to label "exit". This triggers a call
to stack_pop(stack) which dereferences a NULL pointer in "if (stack->pos
== -1)".

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-29 10:26:35 -04:00
Nicolas Iooss
6e3c3595b1 libsepol/cil: do not dereference a NULL pointer when calloc() fails
When list_init() fails to allocate a list with calloc(), it calls
list_destroy(&l) with l = NULL. This functions starts by dereferencing
its argument ("(*list)->head"), which does not work well when it is
NULL.

This bug can be fixed by returning directly in list_init() when calloc()
fails. Doing so allows making list_init() implementation shorter by
removing label "exit" and local variable "rc".

This issue has been found using clang's static analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-28 13:40:56 -04:00
James Carter
af0ce03ec7 libsepol/cil: Add hexadecimal support for Xen ioportcon statements
Add hexadecimal support for Xen ioportcon statements which was
left out of commit c408c70.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-03-28 13:33:05 -04:00
James Carter
da2f2316a3 libsepol/cil: Use hexadecimal numbers when writing Xen rules
When writing a policy.conf file from CIL source, use hexadecimal
numbers in ioportcon, iomemcon, and pcidevicecon rules.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-03-21 14:22:42 -04:00
James Carter
526d0dadb8 libsepol: Update module_to_cil to output hexadecimal for Xen rules
When generating CIL, use hexadecimal numbers in ioportcon,
iomemcon, and pcidevicecon statements.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-03-21 14:22:38 -04:00
James Carter
c408c70b0a libsepol/cil: Allow hexadecimal numbers in Xen context rules
Allow the use of hexadecimal numbers in iomemcon, ioportcon, and
pcidevicecon statements. The use of hexadecimal numbers is often
the natural choice for these rules.

A zero base is now passed to strtol() and strtoull() which will
assume base 16 if the string has a prefix of "0x", base 8 if the
string starts with "0", and base 10 otherwise.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-03-21 14:22:34 -04:00
Nicolas Iooss
6707526f1f libsepol/cil: avoid freeing uninitialized values
cil_resolve_ast() begins by checking whether one of its parameters is
NULL and "goto exit;" when it is the case. As extra_args has not been
initialized there, this leads to calling cil_destroy_tree_node_stack(),
__cil_ordered_lists_destroy()... on garbage values.

In practise this cannot happen because cil_resolve_ast() is only called
by cil_compile() after cil_build_ast() succeeded. As the if condition
exists nonetheless, fix the body of the if block in order to silence a
warning reported by clang Static Analyzer.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-21 14:20:22 -04:00
Nicolas Iooss
0864814583 libsepol/cil: make reporting conflicting type transitions work
When compiling a CIL policy which defines conflicting type transitions,
secilc crashes when trying to format an error message with uninitialized
values. This is caused by __cil_typetransition_to_avtab() not
initializing the ..._str fields of its local variable "struct
cil_type_rule trans" before calling __cil_type_rule_to_avtab().

While at it, make the error report clearer about what is wrong by
showing the types and classes which got expanded in
__cil_type_rule_to_avtab(). Here is an example of the result:

    Conflicting type rules (scontext=testuser_emacs.subj
    tcontext=fs.tmpfs.fs tclass=dir
    result=users.generic_tmpfs.user_tmpfs_file),
    existing=emacs.tmpfs.user_tmpfs_file

    Expanded from type rule (scontext=ARG1 tcontext=fs tclass=ARG3
    result=ARG2)

Reported-By: Dominick Grift <dac.override@gmail.com>
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-21 14:20:17 -04:00
Stephen Smalley
43b24f0132 libsepol: Define cgroup_seclabel policy capability
Define the new cgroup_seclabel policy capability used to
enable userspace setting of security labels on cgroup files
via setfscreatecon() aka /proc/self/attr/fscreate and/or
setfilecon() aka setxattr().

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2017-03-02 12:39:13 -05:00
Nicolas Iooss
ddaf0afec7 libsepol/cil: do not dereference args before checking it was not null
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-03-01 10:42:23 -05:00
James Carter
a2d40aaeba libsepol/cil: Move initialization of bitmap in __cil_permx_to_bitmap()
Nicolas Iooss reports:
  When __cil_permx_to_bitmap() calls __cil_permx_str_to_int() on an
  invalid number, local variablt "bitmap" is left initialized when
  the function returns and its memory is leaked.

  This memory leak has been found by running clang's Address Sanitizer
  on a set of policies generated by American Fuzzy Lop.

Move the initialization of bitmap to right before ebitmap_set_bit()
and after the call to __cil_permx_str_to_int().

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-02-21 13:11:15 -05:00
Nicolas Iooss
95e5c103f3 libsepol/cil: free bitmaps in cil_level_equals()
cil_level_equals() builds two bitmap and compare them but does not
destroy them before returning the result.

This memory leak has been found by running clang's Address Sanitizer on
a set of policies generated by American Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-21 13:09:49 -05:00
Nicolas Iooss
9feaf0380d libsepol/cil: do not leak left-hand side of an invalid constraint
__cil_fill_constraint_expr() does not destroy the list associated with
the first operand of a two-operand operation when the second operand is
invalid.

This memory leak can be reproduced with the following policy:

    (constrain (files (read))
        (not (or (and (eq t1 exec_t) (%q t2 bin_t)) (eq r1 r2))))

This memory leak has been found by running clang's Address Sanitizer on
a set of policies generated from secilc/test/policy.cil by American
Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-21 13:09:44 -05:00
Nicolas Iooss
602385d70c libsepol/cil: free the first operand if the second one is invalid
When __cil_expr_to_bitmap() fails to parse the second operand of an
operation with two operands, it returns an error without destroying the
bitmap which has been created for the first operand. Fix this memory
leak.

This has been tested with the following 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))))

    (permissionx ioctl_test (ioctl CLASS
        (and (range 0x1600 0x19FF) (.ot (range 0x1750 0x175F)))))

This memory leak has been found by running clang's Address Sanitizer on
a set of policies generated from secilc/test/policy.cil by American
Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-21 13:09:39 -05:00
Nicolas Iooss
7fe9a7be31 libsepol/cil: use __cil_ordered_lists_destroy() to free unordered_classorder_lists
In cil_resolve_ast, unordered_classorder_lists is a list of
cil_ordered_list. It needs to be destroyed with
__cil_ordered_lists_destroy() to free all associated memory.

This has been tested with the following policy:

    (class CLASS1 ())
    (class CLASS2 ())
    (classorder (unordered CLASS1))
    (classorder (CLASS2))

This memory leak has been found by running clang's Address Sanitizer on
a set of policies generated by American Fuzzy Lop.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-21 13:09:22 -05:00
James Carter
9edcf28a04 libsepol/cil: Destroy cil_tree_node stacks when finished resolving AST
CIL uses separate cil_tree_node stacks for optionals and blocks to
check for statements not allowed in optionals or blocks and to know
which optional to disable when necessary. But these stacks were not
being destroyed when exiting cil_resolve_ast(). This is not a problem
normally because the stacks will be empty, but this is not the case
when exiting with an error.

Destroy both tree node stacks when exiting to ensure that they are
empty.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-02-17 10:53:52 -05:00
Nicolas Iooss
eeafde1351 libsepol/cil: fix type confusion in cil_copy_ast
When running secilc on the following CIL file, the program tries to free
the data associated with type X using cil_destroy_typeattribute():

    (macro sys_obj_type ((user ARG1)) (typeattribute X))

    (block B
        (type X)
        (call sys_obj_type (Y))
    )

By adding some printf statements to cil_typeattribute_init(),
cil_type_init() and cil_destroy_typeattribute(), the error message I get
when using gcc's address sanitizer is:

$ secilc -o /dev/null -f /dev/null test.cil -vvvvvv
creating TYPE 0x60400000dfd0
Parsing 2017-02-02_crashing_nulptrderef_cil.cil
Building AST from Parse Tree
creating TYPEATTR 0x60600000e420
creating TYPE 0x60400000df50
Destroying Parse Tree
Resolving AST
Failed to resolve call statement at 2017-02-02_crashing_nulptrderef_cil.cil:5
Problem at 2017-02-02_crashing_nulptrderef_cil.cil:5
Pass 8 of resolution failed
Failed to resolve ast
Failed to compile cildb: -2
Destroying TYPEATTR 0x60600000e420, types (nil) name X
Destroying TYPEATTR 0x60400000df50, types 0xbebebebe00000000 name X
ASAN:DEADLYSIGNAL
=================================================================
==30684==ERROR: AddressSanitizer: SEGV on unknown address
0x000000000000 (pc 0x7fc0539d114a bp 0x7ffc1fbcb300 sp
0x7ffc1fbcb2f0 T0)
    #0 0x7fc0539d1149 in ebitmap_destroy /usr/src/selinux/libsepol/src/ebitmap.c:356
    #1 0x7fc053b96201 in cil_destroy_typeattribute ../cil/src/cil_build_ast.c:2370
    #2 0x7fc053b42ea4 in cil_destroy_data ../cil/src/cil.c:616
    #3 0x7fc053c595bf in cil_tree_node_destroy ../cil/src/cil_tree.c:235
    #4 0x7fc053c59819 in cil_tree_children_destroy ../cil/src/cil_tree.c:201
    #5 0x7fc053c59958 in cil_tree_subtree_destroy ../cil/src/cil_tree.c:172
    #6 0x7fc053c59a27 in cil_tree_destroy ../cil/src/cil_tree.c:165
    #7 0x7fc053b44fd7 in cil_db_destroy ../cil/src/cil.c:299
    #8 0x4026a1 in main /usr/src/selinux/secilc/secilc.c:335
    #9 0x7fc0535e5290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
    #10 0x403af9 in _start (/usr/src/selinux/DESTDIR/usr/bin/secilc+0x403af9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/src/selinux/libsepol/src/ebitmap.c:356 in ebitmap_destroy
==30684==ABORTING

When copying the AST tree in cil_resolve_call1(),
__cil_copy_node_helper() calls cil_copy_typeattribute() to grab type X
in the symbol table of block B, and creates a node with the data of X
but with CIL_TYPEATTRIBUTE flavor.

This example is a "type confusion" bug between cil_type and
cil_typeattribute structures. It can be generalized to any couple of
structures sharing the same symbol table (an easy way of finding other
couples is by reading the code of cil_flavor_to_symtab_index()).

Fix this issue in a "generic" way in __cil_copy_node_helper(), by
verifying that the flavor of the found data is the same as expected and
triggering an error when it is not.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-08 10:48:40 -05:00
Nicolas Iooss
c33fd02db5 libsepol/tests: fix -Wwrite-strings warnings
Since fd9e5ef7b7 ("libsepol: use constant keys in hashtab functions")
it is possible to call hashtab_search() with a const char* key value.
Doing so fixes compiler warnings about non-const char* string literals
(-Wwrite-strings flag).

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-06 11:06:04 -05:00
Nicolas Iooss
d6b5b037f9 libsepol: fix -Wwrite-strings warnings
When compiling with -Wwrite-strings, clang reports some warnings like:

    module_to_cil.c:784:13: error: assigning to 'char *' from 'const
    char [5]' discards qualifiers
    [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
                    statement = "type";
                              ^ ~~~~~~
    module_to_cil.c:787:13: error: assigning to 'char *' from 'const
    char [5]' discards qualifiers
    [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
                    statement = "role";
                              ^ ~~~~~~

Add a const type attribute to local variables which only handle constant
strings.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-02-06 11:05:33 -05:00
James Carter
8adbd615c1 libsepol: Return +1 when declaration is followed by a require
A check is made in symtab_insert() for the case when an identifier
had already been declared and was now being required. This meant
that a declaration followed by a require was treated differently
from a require followed by a declaration.

Remove that check and treat both cases the same (which means
returning +1).

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2017-02-03 14:02:32 -05:00
Steve Lawrence
1ef665cb92 libsepol: fix pp module to cil nodecon statement
Policy modules do not have the concept of named IP addresses like CIL
does. So when converting nodecode statements from pp policy modules to
CIL, we need to wrap the IP address and mask parameters in parentheses
so that the CIL compiler does not try to resolve them as named
addresses, but instead treats them as anonymous.

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
2017-01-25 14:47:16 -05:00
Karl MacMillan
4a05e95f19 libsepol compilation fixes for macOS.
ln on macOS doesn't support --relative, so use the gnu version by default.

Also document how to build on macOS.

Signed-off-by: Karl MacMillan <karlwmacmillan@gmail.com>
2017-01-20 13:19:57 -05:00
Nicolas Iooss
69ec21ce6a libsepol: remove useless assignments
There is no point in initializing a variable which gets
almost-immediately assigned an other value.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-19 08:48:36 -05:00
Nicolas Iooss
ebe24ad20b libsepol: verify the right variable after calling calloc()
After "otype = calloc(1, sizeof(*otype))", it is reasonable to check the
value of otype, not ft.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-19 08:47:52 -05:00
Nicolas Iooss
fd9e5ef7b7 libsepol: use constant keys in hashtab functions
Even though "hashtab_key_t" is an alias for "char *", "const
hashtab_key_t" is not an alias for "(const char) *" but means "(char *)
const".

Introduce const_hashtab_key_t to map "(const char) *" and use it in
hashtab_search() and hashtab key comparison functions.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-19 08:46:19 -05:00
Nicolas Iooss
d4923b49b4 libsepol: make capability index an unsigned int
When sepol_polcap_getname() is called with a negative capnum, it
dereferences polcap_names[capnum] which produces a segmentation fault
most of the time.

For information, here is a gdb session when hll/pp loads a policy module
which has been mutated by American Fuzzy Lop:

    Program received signal SIGSEGV, Segmentation fault.
    sepol_polcap_getname (capnum=capnum@entry=-4259840) at polcaps.c:34
    34      return polcap_names[capnum];
    => 0x00007ffff7a8da07 <sepol_polcap_getname+135>:   48 8b 04 f8 mov
    (%rax,%rdi,8),%rax

    (gdb) bt
    #0  sepol_polcap_getname (capnum=capnum@entry=-4259840) at
    polcaps.c:34
    #1  0x00007ffff7a7c440 in polcaps_to_cil (pdb=0x6042e0) at
    module_to_cil.c:2492
    #2  sepol_module_policydb_to_cil (fp=fp@entry=0x7ffff79c75e0
    <_IO_2_1_stdout_>, pdb=0x6042e0, linked=linked@entry=0) at
    module_to_cil.c:4039
    #3  0x00007ffff7a7e695 in sepol_module_package_to_cil
    (fp=fp@entry=0x7ffff79c75e0 <_IO_2_1_stdout_>, mod_pkg=0x604280) at
    module_to_cil.c:4087
    #4  0x0000000000401acc in main (argc=<optimized out>,
    argv=<optimized out>) at pp.c:150

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-09 16:00:14 -05:00
Nicolas Iooss
c39289c9b7 libsepol/tests: fix some memory leaks
When running "make test" with the Address Sanitizer (by adding
-fsanitize=address to compiler flags), a lot of memory leaks are
reported from checkpolicy. Anyway some leaks come from the tests and it
seems cleaner to start fixing these ones.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-06 13:04:09 -05:00
Nicolas Iooss
c3b8d4aa61 libsepol/tests: fix -Wsometimes-uninitialized clang warnings
When compiling libsepol tests, clang complains about some uninitialized
variables:

    test-common.c:171:14: error: variable 'my_primary' is used
    uninitialized whenever 'if' condition is false
    [-Werror,-Wsometimes-uninitialized]
                    } else if (my_flavor == TYPE_ALIAS) {
                               ^~~~~~~~~~~~~~~~~~~~~~~
    test-common.c:179:30: note: uninitialized use occurs here
                    CU_ASSERT(type->primary == my_primary);
                                               ^~~~~~~~~~
    /usr/include/CUnit/CUnit.h:123:30: note: expanded from macro
    'CU_ASSERT'
      { CU_assertImplementation((value), __LINE__, #value, __FILE__, "", CU_...
                                 ^
    test-common.c:171:10: note: remove the 'if' if its condition is
    always true
                    } else if (my_flavor == TYPE_ALIAS) {
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test-common.c:153:25: note: initialize the variable 'my_primary' to
    silence this warning
            unsigned int my_primary, my_flavor, my_value;
                                   ^
                                    = 0
    test-common.c:171:14: error: variable 'my_value' is used
    uninitialized whenever 'if' condition is false
    [-Werror,-Wsometimes-uninitialized]
                    } else if (my_flavor == TYPE_ALIAS) {
                               ^~~~~~~~~~~~~~~~~~~~~~~
    test-common.c:181:30: note: uninitialized use occurs here
                    CU_ASSERT(type->s.value == my_value);
                                               ^~~~~~~~
    /usr/include/CUnit/CUnit.h:123:30: note: expanded from macro
    'CU_ASSERT'
      { CU_assertImplementation((value), __LINE__, #value, __FILE__, "", CU_...
                                 ^
    test-common.c:171:10: note: remove the 'if' if its condition is
    always true
                    } else if (my_flavor == TYPE_ALIAS) {
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test-common.c:153:46: note: initialize the variable 'my_value' to
    silence this warning
            unsigned int my_primary, my_flavor, my_value;
                                                        ^
                                                         = 0

This is because the call to CU_FAIL("not an alias") is not fatal in
test_alias_datum(), and variables my_primary and my_value are indeed
used uninitialized in a CU_ASSERT statement later.

Silent the warning by moving the elseif condition to a CU_ASSERT
statement which replaces the CU_FAIL.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2017-01-06 12:59:01 -05:00
Gary Tierney
af18b86e0b libsepol/cil: remove avrules with no affected types
Adds a check for avrules with type attributes that have a bitmap cardinality
of 0 (i.e., no types in their set) before adding them to the libsepol policy in
__cil_avrule_to_avtab().  Also adds an exception for neverallow rules to
prevent breaking anything from AOSP mentioned in
f9927d9370.

Signed-off-by: Gary Tierney <gary.tierney@gmx.com>
2016-12-13 10:56:59 -05:00
Stephen Smalley
d479baa82d libsepol: Define extended_socket_class policy capability
Define the extended_socket_class policy capability used to enable
the use of separate socket security classes for all network address
families rather than the generic socket class. This also enables
separate security classes for ICMP and SCTP sockets, which were previously
mapped to the rawip_socket class.

The legacy redhat1 policy capability that was only ever used in testing
within Fedora for ptrace_child is reclaimed for this purpose; as far as
I can tell, this policy capability is not enabled in any supported distro
policy.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2016-12-08 09:17:17 -05:00
James Carter
9e81e611c7 libsepol: Fix neverallow checking to also check the other types when
self is included in a target type set.

When neverallow checking was refactored in commit 9e6840e, self
was not handled correctly. The assumption was made that self only
appeared by itself as a target type, when it may appear in a list of
types. Because of this, if self appears in a target type set of a
neverallow, the other types in the type set are not checked.

Example:

allow TYPE1 TYPE2:CLASS1 { PERM1 };
neverallow TYPE1 {TYPE2 self}:CLASS1 { PERM1 };

The old assertion checking would not find a violation in the rules
above because the target type TYPE2 would be ignored.

This fix will cause all of the types in a target list that includes
self to be checked.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2016-11-30 10:19:02 -05:00
James Carter
3fe4499f7d libsepol/cil: Add ability to write policy.conf file from CIL AST
The ability to create a policy.conf file from the CIL AST has been
a desire from the beginning to assist in debugging and for general
flexibility. Some work towards this end was started early in CIL's
history, but cil_policy.c has not been remotely functional in a long
time. Until now.

The function cil_write_policy_conf() will write a policy.conf file
from a CIL AST after cil_build_ast(), cil_resolve_ast(),
cil_fqn_qualify(), and cil_post_process() have been called.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
2016-11-30 10:18:12 -05:00
Stephen Smalley
7e09f584e1 libsepol,libselinux,audit2allow: teach audit2why about type bounds failures
Teach audit2why to recognize type bounds failures.  This required
updating libsepol sepol_compute_av_reason() to identify bounds
failures, and updating libsepol context_struct_compute_av() to
include the type bounds logic from the kernel.

This could potentially be further augmented to provide more detailed
reporting via the reason buffer to include information similar to
what security_dump_masked_av() reports in the kernel.  However, it
is unclear if this is needed.  It is already possible to get type
bounds checking at policy build time by enabling expand-check=1
in /etc/selinux/semanage.conf (or by default when compiling
monolithic policy).

Before:
type=AVC msg=audit(1480451925.038:3225): avc:  denied  { getattr } for  pid=7118 comm="chmod" path="/home/sds/selinux-testsuite/tests/bounds/bounds_file_blue" dev="dm-2" ino=23337697 scontext=unconfined_u:unconfined_r:test_bounds_child_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_bounds_file_blue_t:s0 tclass=file permissive=0

	Was caused by:
		Unknown - would be allowed by active policy
		Possible mismatch between this policy and the one under which the audit message was generated.

		Possible mismatch between current in-memory boolean settings vs. permanent ones.

After:
type=AVC msg=audit(1480451925.038:3225): avc:  denied  { getattr } for  pid=7118 comm="chmod" path="/home/sds/selinux-testsuite/tests/bounds/bounds_file_blue" dev="dm-2" ino=23337697 scontext=unconfined_u:unconfined_r:test_bounds_child_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_bounds_file_blue_t:s0 tclass=file permissive=0
        Was caused by:
                Typebounds violation.

                Add an allow rule for the parent type.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2016-11-29 15:53:59 -05:00
Stephen Smalley
fff90bd22b libsepol: sepol_av_to_string: clear static buffer
chenxiaolong reported this via
https://github.com/SELinuxProject/selinux/issues/23

A nicer fix would be to rework the interface to be more
like security_av_string() in libselinux, but that requires
updating all callers.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2016-11-29 11:20:43 -05:00
Stephen Smalley
cf8625be58 libsepol: do not #include <sys/cdefs.h>
ratbert90 submitted this patch via
https://github.com/SELinuxProject/selinux/issues/19.
Apparently musl does not provide sys/cdefs.h, see
http://wiki.musl-libc.org/wiki/FAQ#Q:_I.27m_trying_to_compile_something_against_musl_and_I_get_error_messages_about_sys.2Fcdefs.h.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2016-11-29 11:03:17 -05:00
Nicolas Iooss
ab27085099 libsepol,libsemanage: write file name in flex output
Tools like lcov (for code coverage) does not like files named
"<stdout>". For example it reports errors like:

    genhtml: ERROR: cannot read
    /usr/src/selinux/libsemanage/src/<stdout>

When using flex -o option, the output file name gets written in the
generated C code, which solves this issue.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2016-11-29 08:47:36 -05:00
Nicolas Iooss
527380a193 libsepol/tests: use LDFLAGS when linking
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2016-11-29 08:45:26 -05:00
Nicolas Iooss
fb237459c8 libsepol: detect duplicated symbol IDs
A valid policy would not have two symbols (classes, roles, users...)
sharing the same unique identifier. Make policydb_read() rejects such
policy files.

When ..._val_to_name translation tables were allocated with malloc(),
change to calloc() in order to initialize the tables with NULLs.

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2016-11-29 08:43:41 -05:00
Nicolas Iooss
9872b04a80 libsepol: check decl_id bounds before using it
When loading an invalid module which uses a declaration ID 0,
semodule_package crashes in policydb_index_decls():

    p->decl_val_to_struct[decl->decl_id - 1] = decl;

gdb shows the following stack trace:

    #0  0x00007ffff7aa1bbd in policydb_index_decls (p=p@entry=0x605360)
    at policydb.c:1034
    #1  0x00007ffff7aaa9fc in policydb_read (p=<optimized out>,
    fp=fp@entry=0x605090, verbose=verbose@entry=0) at policydb.c:3958
    #2  0x00007ffff7ab4764 in sepol_policydb_read (p=<optimized out>,
    pf=pf@entry=0x605090) at policydb_public.c:174
    #3  0x0000000000401d33 in main (argc=<optimized out>,
    argv=0x7fffffffdc88) at semodule_package.c:220

Change policydb_index_decls() to report an error instead:

    libsepol.policydb_index_decls: invalid decl ID 0

Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
2016-11-29 08:41:23 -05:00
Stephen Smalley
8fdb225521 libsepol,checkpolicy: convert rangetrans and filenametrans to hashtabs
range transition and name-based type transition rules were originally
simple unordered lists.  They were converted to hashtabs in the kernel
by commit 2f3e82d694d3d7a2db019db1bb63385fbc1066f3 ("selinux: convert range
transition list to a hashtab") and by commit
2463c26d50adc282d19317013ba0ff473823ca47 ("SELinux: put name based
create rules in a hashtable"), but left unchanged in libsepol and
checkpolicy. Convert libsepol and checkpolicy to use the same hashtabs
as the kernel for the range transitions and name-based type transitions.

With this change and the preceding one, it is possible to directly compare
a policy file generated by libsepol/checkpolicy and the kernel-generated
/sys/fs/selinux/policy pseudo file after normalizing them both through
checkpolicy.  To do so, you can run the following sequence of commands:

checkpolicy -M -b /etc/selinux/targeted/policy/policy.30 -o policy.1
checkpolicy -M -b /sys/fs/selinux/policy -o policy.2
cmp policy.1 policy.2

Normalizing the two files via checkpolicy is still necessary to ensure
consistent ordering of the avtab entries.  There may still be potential
for other areas of difference, e.g. xperms entries may lack a well-defined
order.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
2016-11-28 13:10:59 -05:00