Currently a constraint `t1 == t2` gets converted to the invalid cil syntax `(mlsconstrain (class_name (perm_name)) (eq t1 ))` and fails to be loaded into the kernel.
Fixes: 893851c0a1 ("policycoreutils: add a HLL compiler to convert policy packages (.pp) to CIL")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The iteration over the set ebitmap bits is not implemented very
efficiently in libsepol. It is slowing down the policy optimization
quite significantly, so convert the type_map from an array of ebitmaps
to an array of simple ordered vectors, which can be traveresed more
easily. The worse space efficiency of the vectors is less important than
the speed in this case.
After this change the duration of semodule -BN decreased from 6.4s to
5.5s on Fedora Rawhide x86_64 (and from 6.1s to 5.6s with the unconfined
module disabled).
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Only attributes can be a superset of another attribute, so we can skip
non-attributes right away.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
I copy-pasted it from a different part of the code, which had to deal
with policydb that isn't final yet. Since we only deal with the final
kernel policy here, we can skip the check for the type datum being NULL.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Add a simple test for secilc -O to make sure that it produces the
expected output. This might produce some false positives when the output
of secilc/checkpolicy changes slightly, in which case the expected CIL
will need to be updated along with the change.
The test should normally work even with a checkpolicy built from an
older tree, as long as it produces the same CIL output, so it uses the
checkpolicy it finds in PATH by default.
The test policy is taken from an e-mail from James Carter:
https://lore.kernel.org/selinux/CAP+JOzTQQx6aM81QyVe0yoiPJeDU+7xE6nn=0UMAB1EZ_c9ryA@mail.gmail.com/T/
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
With the old hidden_def and hidden_proto DSO infrastructure removed,
correctness of the map file becomes paramount, as it is what filters out
public API. Because of this, the wild cards should not be used, as it
lets some functions through that should not be made public API. Thus
remove the wild cards, and sort the list.
Additionally, verify that nothing changed in external symbols as well:
This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map
Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map
And diffing them:
diff old.map new.map
Fixes: #165Fixes: #204
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Add -fno-semantic-interposition to CFLAGS. This will restore
the DSO infrastructures protections to insure internal callers
of exported symbols call into libselinux and not something loading first
in the library list.
Clang has this enabled by default.
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
libsepol already has a linker script controlling it's exports, so this
patch has a net 0 affect, with the exception that internal callers of
external routines, which there could be 0 of, could potentially call a
non-libsepol routine depending on library load order.
NOTE A FEW SYMBOLS ARE EXPORTED THAT NORMALLY WOULDN'T BE
- sepol_context_to_sid
- sepol_ibendport_sid
- sepol_ibpkey_sid
- sepol_msg_default_handler
- sepol_node_sid
- sepol_port_sid
A subsequent map update will follow.
This list was generated by generating an old export map (from master):
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map
Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libsepol.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map
And diffing them:
diff old.map new.map
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: William Roberts <william.c.roberts@intel.com>
libsepol carried its own (outdated) copy of flask.h with the generated
security class and initial SID values for use by the policy
compiler and the forked copy of the security server code
leveraged by tools such as audit2why. Convert libsepol and
checkpolicy entirely to looking up class values from the policy,
remove the SECCLASS_* definitions from its flask.h header, and move
the header with its remaining initial SID definitions private to
libsepol. While we are here, fix the sepol_compute_sid() logic to
properly support features long since added to the policy and kernel,
although there are no users of it other than checkpolicy -d (debug)
and it is not exported to users of the shared library. There
are still some residual differences between the kernel logic and
libsepol.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
When the lexer encounters an unexpected character in a policy source file, it prints a warning, discards the character and moves on. In some build environments, these characters could be a symptom of an earlier problem, such as unintended results of expansion of preprocessor macros, and the ability to have the compiler halt on such issues would be helpful for diagnosis.
Signed-off-by: Daniel Burgener <Daniel.Burgener@microsoft.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
The value attrs_expand_size == 1 removes all empty attributes, but it
also makes sense to expand all attributes that have only one type. This
removes some redundant rules (there is sometimes the same rule for the
type and the attribute) and reduces the number of attributes that the
kernel has to go through when looking up rules.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
Previously the behavior was to warn, discard the character and proceed.
Now the build will halt upon encountering an unexpected character.
Signed-off-by: Daniel Burgener <dburgener@linux.microsoft.com>
Acked-by: James Carter <jwcart2@gmail.com>
A parameter of a macro was only considered to be a duplicate if it
matched both the name and flavor of another parameter. While it is
true that CIL is able to differentiate between those two parameters,
there is no reason to use the same name for two macro parameters and
it is better to return an error for what is probably an error.
Remove the check of the flavors when checking for duplicate parameters.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
Type transition file names are stored in a symbol table. Before the
name is added, the symbol table is searched to see if the name had
already been inserted. If it has, then the already existing datum is
returned. If it has not, then the name is added if either the
typetransition rule does not occur in a macro or the name is not one
of the macro parameters.
Checking for a previous insertion before checking if the name is a
macro parameter can cause a macro parameter to be treated as the
actual name if a previous type transition file name is the same as
the parameter.
Now check the name to see if it a macro paramter before checking for
its existence in the symbol table.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
This reverts commit 542e878690.
After 6968ea9775 ("libsepol: make ebitmap_cardinality() of linear
complexity"), the caching only saves ~0.06 % of total semodule -BN
running time (on x86_64 without using the POPCNT instruction), so it's
no longer worth the added complexity.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Previously, libselinux was exporting the following symbols:
- dir_xattr_list;
- map_class;
- map_decision;
- map_perm;
- myprintf_compat;
- unmap_class;
- unmap_perm;
However, these appear to be unused and can safely be dropped.
This is done as a seperate commit to so it can easily be reverted
seperately for any reasons.
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Add a linker script that exports only what was previosly exported by
libselinux.
This was checked by generating an old export map (from master):
nm --defined-only -g ./src/libselinux.so | cut -d' ' -f 3-3 | grep -v '^_' > old.map
Then creating a new one for this library after this patch is applied:
nm --defined-only -g ./src/libselinux.so | cut -d' ' -f 3-3 | grep -v '^_' > new.map
And diffing them:
diff old.map new.map
Fixes: #179
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Add -fno-semantic-interposition to CFLAGS. This will restore
the DSO infrastructures protections to insure internal callers
of exported symbols call into libselinux and not something laoding first
in the library list.
Clang has this enabled by default.
Signed-off-by: William Roberts <william.c.roberts@intel.com>
Create the macro ebitmap_is_empty() to check if an ebitmap is empty.
Use ebitmap_is_empty(), instead of ebitmap_cardinality() or
ebitmap_length(), to check whether or not an ebitmap is empty.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
As ebitmap_get_bit() complexity is linear in the size of the bitmap, the
complexity of ebitmap_cardinality() is quadratic. This can be optimized
by browsing the nodes of the bitmap directly in ebitmap_cardinality().
While at it, use built-in function __builtin_popcountll() to count the
ones in the 64-bit value n->map for each bitmap node. This seems better
suited than "count++". This seems to work on gcc and clang on x86,
x86_64, ARM and ARM64 but if it causes compatibility issues with some
compilers or architectures (or with older versions of gcc or clang),
the use of __builtin_popcountll() can be replaced by a C implementation
of a popcount algorithm.
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
commit 1f89c4e787 ("libselinux: Eliminate
use of security_compute_user()") eliminated the use of
security_compute_user() by get_ordered_context_list(). Deprecate
all use of security_compute_user() by updating the headers and man
pages and logging a warning message on any calls to it. Remove
the example utility that called the interface. While here, also
fix the documentation of correct usage of the user argument to these
interfaces.
Fixes: https://github.com/SELinuxProject/selinux/issues/70
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
Detect when the hashtab's load factor gets too high and try to grow it
and rehash it in such case. If the reallocation fails, just keep the
hashtab at its current size, since this is not a fatal error (it will
just be slower).
This speeds up semodule -BN on Fedora from ~8.9s to ~7.2s (1.7 seconds
saved).
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
hashtab_replace() and hashtab_map_remove_on_error() aren't used
anywhere, no need to keep them around...
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
From failsafe_context(5):
"The failsafe_context file allows SELinux-aware applications such as
PAM(8) to obtain a known valid login context for an administrator if
no valid default entries can be found elsewhere."
"Надёжный" means "reliable", "резервный" means "reserve",
the last variant is much closer to what "failsafe" really does.
Discussed with and approved by previous translators:
https://github.com/SELinuxProject/selinux/pull/203
Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
get_ordered_context_list() code used to ask the kernel to compute the complete
set of reachable contexts using /sys/fs/selinux/user aka
security_compute_user(). This set can be so huge so that it doesn't fit into a
kernel page and security_compute_user() fails. Even if it doesn't fail,
get_ordered_context_list() throws away the vast majority of the returned
contexts because they don't match anything in
/etc/selinux/targeted/contexts/default_contexts or
/etc/selinux/targeted/contexts/users/
get_ordered_context_list() is rewritten to compute set of contexts based on
/etc/selinux/targeted/contexts/users/ and
/etc/selinux/targeted/contexts/default_contexts files and to return only valid
contexts, using security_check_context(), from this set.
Fixes: https://github.com/SELinuxProject/selinux/issues/28
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Since commit e3cab998b4 ("libselinux
mountpoint changing patch.") for version 20120216 is_selinux_enabled()
does never return -1; drop mentions in the man-page and header file.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
According to profiling of semodule -BN, ebitmap_cardinality() is called
quite often and contributes a lot to the total runtime. Cache its result
in the ebitmap struct to reduce this overhead. The cached value is
invalidated on most modifying operations, but ebitmap_cardinality() is
usually called once the ebitmap doesn't change any more.
After this patch, the time to do 'semodule -BN' on Fedora Rawhide has
decreased from ~10.9s to ~8.9s (2s saved).
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
[sds@tycho.nsa.gov: correct times per follow-up on list]
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
The filename_- and range_trans_table ancillary hash tables in
cil_binary.c just duplicate the final policydb content and can be simply
removed.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
On Android, the label_file.c file is compiled for all platforms,
including OSX. OSX has a slightly different prototype for the
getxattr function.
ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options);
which causes a compile error when compiling libselinux on OSX.
```
external/selinux/libselinux/src/label_file.c:1038:37: error: too few arguments to function call, expected 6, have 4
read_digest, SHA1_HASH_SIZE);
^
/Applications/Xcode9.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/xattr.h:61:1: note: 'getxattr' declared here
ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options);
^
1 error generated.
```
On OSX builds, add the additional arguments so that the code compiles.
As both SELinux labels and the restorecon partial digest are stored in
extended attributes, it's theoretically possible that someone
could assign SELinux labels and hash digests on OSX filesystems.
Doing so would be extremely weird and completely untested, but
theoretically possible.
Signed-off-by: Nick Kralevich <nnk@google.com>
Do not override CFLAGS and LDFLAGS in libsemange Makefile under DEBUG=1,
to make it possible to build the whole tree using the root Makefile with
DEBUG=1.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
The classperms associated with each map class permission and with each
classpermissionset are verified in __cil_verify_classperms() which had
multiple problems with how it did the verification.
1) Verification was short-circuited when the first normal class is found.
The second classpermissionset statement below would not have been
verified.
(classpermission cp1)
(classpermissionset cp1 (CLASS (PERM)))
(classpermissionset cp1 cp2)
2) The classperms of a map class permission and classpermissionset were
not checked for being NULL before the function recursively called itself.
This would result in a segfault if the missing map or set was referred to
before the classmap or classpermission occured. This error was reported by
Dominick Grift (dominick.grift@defensec.nl).
These rules would cause a segfault.
(classmap cm1 (mp1))
(classmapping cm1 mp1 (cm2 (mp2)))
(classmap cm2 (mp2))
But an error would be produced for these rules.
(classmap cm1 (mp1))
(classmap cm2 (mp2))
(classmapping cm2 mp2 (cm1 (mp1)))
3) The loop detection logic was incomplete and could only detect a loop
with a certain statement ordering.
These rules would cause a stack overflow.
(classmap cm1 (mp1))
(classmapping cm1 mp1 (cm2 (mp2)))
(classmap cm2 (mp2))
(classmapping cm2 mp2 (cm3 (mp3)))
(classmap cm3 (mp3))
(classmapping cm3 mp3 (cm2 (mp2)))
Rewrote __cil_verify_classperms() to fix these errors.
Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Add support for new SELinux policy capability genfs_seclabel_symlinks.
With this capability enabled symlinks on kernel filesystems will receive
contexts based on genfscon statements, like directories and files,
and not be restricted to the respective filesystem root sid.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Remove restrictions in libsepol and checkpolicy that required all
declared initial SIDs to be assigned a context. With this patch,
it is possible to build and load a policy that drops the sid <sidname>
<context> declarations for the unused initial SIDs. It is still
required to retain the sid <sidname> declarations (in the flask
definitions) in order to preserve the initial SID ordering/values.
The unused initial SIDs can be renamed, e.g. to add an unused_
prefix or similar, if desired, since the names used in the policy
are not stored in the kernel binary policy.
In CIL policies, the (sid ...) and (sidorder (...)) statements
must be left intact for compatibility but the (sidcontext ...)
statements for the unused initial SIDs can be omitted after this change.
With current kernels, if one removes an unused initial SID context
from policy, builds policy with this change applied and loads the
policy into the kernel, cat /sys/fs/selinux/initial_contexts/<sidname>
will show the unlabeled context. With the kernel patch to remove unused
initial SIDs, the /sys/fs/selinux/initial_contexts/<sidname>
file will not be created for unused initial SIDs in the first place.
NB If an unused initial SID was assigned a context different from
the unlabeled context in existing policy, then it is not safe to
remove that initial SID context from policy and reload policy on
the running kernel that was booted with the original policy. This
is because that kernel may have assigned that SID to various kernel
objects already and those objects will then be treated as having
the unlabeled context after the removal. In refpolicy, examples
of such initial SIDs are the "fs" SID and the "sysctl" SID. Even
though these initial SIDs are not directly used (in code) by the current
kernel, their contexts are being applied to filesystems and sysctl files by
policy and therefore the SIDs are being assigned to objects.
NB The "sysctl" SID was in use by the kernel up until
commit 8e6c96935fcc1ed3dbebc96fddfef3f2f2395afc ("security/selinux:
fix /proc/sys/ labeling) circa v2.6.39. Removing its context from
policy will cause sysctl(2) or /proc/sys accesses to end up
performing permission checks against the unlabeled context and
likely encounter denials for kernels < 2.6.39.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
GCC 10 has it enabled by default and everything now builds OK with it,
so add it to CFLAGS to avoid breaking the build in the future.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
This variable is declared in a header file, but never defined or used.
The te_assert structure definition is only used in this declaration, so
remove both.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Commit 4459d635b8 ("libsepol: Remove cil_mem_error_handler() function
pointer") replaced cil_mem_error_handler usage with inline contents of
the default handler. However, it left over the header declaration and
two callers. Convert these as well and remove the header declaration.
This also fixes a build failure with -fno-common.
Fixes: 4459d635b8 ("libsepol: Remove cil_mem_error_handler() function pointer")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
GCC 10 comes with -fno-common enabled by default - fix the CIL_KEY_*
global variables to be defined only once in cil.c and declared in the
header file correctly with the 'extern' keyword, so that other units
including the file don't generate duplicate definitions.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
When copying an avrule with extended permissions (permx) in
cil_copy_avrule(), the check for a named permx checks the new permx
instead of the old one, so the check will always fail. This leads to a
segfault when trying to copy a named permx because there will be an
attempt to copy the nonexistent permx struct instead of the name of
the named permx.
Check whether the original is a named permx instead of the new one.
Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
Rename flush_class_cache() to selinux_flush_class_cache(), export it
for direct use by userspace policy enforcers, and call it on all policy
load notifications rather than only when using selinux_check_access().
This ensures that policy reloads that change a userspace class or
permission value will be reflected by subsequent string_to_security_class()
or string_to_av_perm() calls.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Despite deprecating use of flask.h and av_permissions.h back in 2014,
the man pages for avc_has_perm(3) and security_compute_av(3) were not
updated to provide instructions on how to dynamically map class/permission
names nor to encourage use of selinux_check_access(3) instead of these
interfaces. Also, while selinux_set_mapping(3) supports dynamic
class/perm mapping at initialization, it does not support changes to
the class/perm values at runtime upon a policy reload, and no
instructions were provided on how to set up a callback to support
this case. Update the man pages accordingly.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: William Roberts <bill.c.roberts@gmail.com>
The flask.h and av_permissions.h header files were deprecated and
all selinux userspace references to them were removed in
commit 76913d8adb ("Deprecate use of flask.h and av_permissions.h.")
back in 2014 and included in the 20150202 / 2.4 release.
All userspace object managers should have been updated
to use the dynamic class/perm mapping support since that time.
Remove these headers finally to ensure that no users remain and
that no future uses are ever introduced.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
While using Ansible's Selinux module to manage ports, I discovered
that numerical ports caused an unhandled exception in 'seobject.py'.
This appears to be a bug, and I am proposing a fix which checks the
type of the argument before operating on it. This maintains the
original functionality in the case of a string, and acts in the same
fashion if you supply an integer.
I did not find any open bug report against the SELinux project. The
downstream bug report is here:
https://github.com/ansible/ansible/issues/60968
Signed-off-by: Joshua Schmidlkofer <joshua@joshuainnovates.us>
As a result of Python 2 sunset - https://www.python.org/doc/sunset-python-2/ -
Python 2 code will not be supported in this project anymore and new Python code
should be written only for Python 3.
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
When starting restorecond without any option the following redundant
console log is outputed:
/dev/log 100.0%
/var/volatile/run/syslogd.pid 100.0%
...
This is caused by two global variables of same name r_opts. When
executes r_opts = opts in restore_init(), it originally intends
to assign the address of struct r_opts in "restorecond.c" to the
pointer *r_opts in "restore.c".
However, the address is assigned to the struct r_opts and covers
the value of low eight bytes in it. That causes unexpected value
of member varibale 'nochange' and 'verbose' in struct r_opts, thus
affects value of 'restorecon_flags' and executes unexpected operations
when restorecon the files such as the redundant console log output or
file label nochange.
Cause restorecond/restore.c is copied from policycoreutils/setfiles,
which share the same pattern. It also has potential risk to generate
same problems, So fix it in case.
Signed-off-by: Baichuan Kong <kongbaichuan@huawei.com>
Generating selinuxswig_python_exception.i and
semanageswig_python_exception.i requires gcc, which appears to be
unavailable on some platform. Work around this issue by adding the
generated files to the git repository.
While at it, remove a stray space in the generated
selinuxswig_python_exception.i.
Original thread: https://lore.kernel.org/selinux/20191012172357.GB19655@imap.altlinux.org/T/#ma78bd7fe71fb5784387a8c0cebd867d6c02ee6e4
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Cc: Michael Shigorin <mike@altlinux.org>