Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

semodule utils #392

Closed
wants to merge 44 commits into from
Closed

Conversation

cgzones
Copy link
Contributor

@cgzones cgzones commented May 12, 2023

No description provided.

wanghuizhao and others added 29 commits June 5, 2023 15:15
To use hashtab in libselinux, migrate the existing hashtab template
from policycoreutils/newrole to libselinux.

Signed-off-by: wanghuizhao <[email protected]>
Acked-by: James Carter <[email protected]>
To adapt to the scenarios of libselinux, this patch does three things:

1. Add a new function hashtab_destroy_key. This function is used to
   reclaim memory using the customized key destruction method.

2. Changed the macro definition to _SELINUX_HASHTAB_H_.

3. Add a function declaration to the header file.

Signed-off-by: wanghuizhao <[email protected]>
Acked-by: James Carter <[email protected]>
When semodule -i some.pp to install a module package, duplicate items are
detected for the module. The detection function is nodups_specs in
libselinux/src/label_file.c. The algorithm complexity of implementing
this function is O(M*(N^2)). M is a symbol related to the length of a string.
N indicates the number of data->nspec. In scenarios where N is very large, the
efficiency is very low.

To solve this problem, I propose to use the hash table to detect duplicates.
The algorithm complexity of new implementing is O(M*N). The execution
efficiency will be greatly improved.

Comparison between the execution time of the nodups_specs function.

Old double-layer loop implementation O(M*(N^2)):

semodule -i myapp1.pp
nodups_specs data->nspec: 5002
nodups_specs start: 11785.242s
nodups_specs end:   11785.588s
nodups_specs consumes:  0.346s

semodule -i myapp2.pp
nodups_specs data->nspec: 10002
nodups_specs start: 11804.280s
nodups_specs end:   11806.546s
nodups_specs consumes:  2.266s

semodule -i myapp3.pp
nodups_specs data->nspec: 20002
nodups_specs start: 11819.106s
nodups_specs end:   11830.892s
nodups_specs consumes: 11.786s

New hash table implementation O(M*N):

semodule -i myapp1.pp
nodups_specs data->nspec: 5002
nodups_specs start: 11785.588s
nodups_specs end:   11785.590s
nodups_specs consumes:  0.002s

semodule -i myapp2.pp
nodups_specs data->nspec: 10002
nodups_specs start: 11806.546s
nodups_specs end:   11806.552s
nodups_specs consumes:  0.006s

semodule -i myapp3.pp
nodups_specs data->nspec: 20002
nodups_specs start: 11830.892s
nodups_specs end:   11830.905s
nodups_specs consumes:  0.013s

Signed-off-by: wanghuizhao <[email protected]>
Acked-by: James Carter <[email protected]>
The token CLONE is never used in the grammar; drop it.

As side effect `clone` and `CLONE` become available as identifier names.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
If tunables are not preserved (the mode unconditionally used by
checkpolicy) an expression must not consist of booleans and tunables,
since such expressions are not supported during expansion (see expand.c:
discard_tunables()).

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
When setting permission bits from a wildcard or complement only set the
bits for permissions actually declared for the associated class.  This
helps optimizing the policy later, since only rules are dropped with a
complete empty permission bitset.  Example policy:

    class CLASS1
    sid kernel
    class CLASS1 { PERM1 }
    type TYPE1;
    bool BOOL1 true;
    allow TYPE1 self : CLASS1 { PERM1 };
    role ROLE1;
    role ROLE1 types { TYPE1 };
    if ! BOOL1 { allow TYPE1 self: CLASS1 *; }
    user USER1 roles ROLE1;
    sid kernel USER1:ROLE1:TYPE1

Also emit a warning if a rule will have an empty permission bitset due
to an exhausting complement.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
The functions constraint_expr_to_str() prepare a string representation
for validatetrans and mlsvalidatetrans rules.  To decide what keyword to
use the type of expression is consulted.  Currently the extra target
type (CEXPR_XTARGET) is considered to be an MLS statement while its not,
e.g.:

    validatetrans CLASS1 t3 == ATTR1;

Actually check for MLS expression types only.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Ensure various object context entries have a name, since they are
duplicated via strdup(3), and the order for ports and memory regions is
valid.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
For old style range transition rules the class defaults to process.
However the policy might not declare the process class leading to
setting a wrong bit later on via:

    if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))

UBSAN report:

    policydb.c:3684:56: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int')

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
XEN policies with extended permissions are not supported, e.g. writing
them will fail (see write.c:avrule_write()).

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Bail out on expanding levels with invalid low category.

UBSAN report:

    expand.c:952:21: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'uint32_t' (aka 'unsigned int')

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Match surrounding code and the message were quite generic too.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
sepol_log_err() will already append a newline unconditionally.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Use the libsepol internal wrapper ERR() with a NULL handler to emit
error messages.  ERR() will besides adding a prefix of "libsepol" also
write to stderr.  One benefit is the option to suppress the messages via
sepol_debug(), although marked deprecated, e.g. in fuzzers.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Use the libsepol internal wrapper ERR() with a NULL handler to emit
error messages.  ERR() will besides adding a prefix of "libsepol" also
write to stderr.  One benefit is the option to suppress the messages via
sepol_debug(), although marked deprecated, e.g. in fuzzers.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
Example session:

    $ ./dismod --help
    Usage:
     ./dismod [OPTIONS] binary_pol_file

    Options:
     -h, --help              print this help message
     -a, --actions ACTIONS   run non-interactively

    Actions:
      1    display unconditional AVTAB
      2    display conditional AVTAB
      3    display users
      4    display bools
      5    display roles
      6    display types, attributes, and aliases
      7    display role transitions
      8    display role allows
      9    Display policycon
      0    Display initial SIDs
      a    Display avrule requirements
      b    Display avrule declarations
      c    Display policy capabilities
      u    Display the unknown handling setting
      F    Display filename_trans rules

    $ ./dismod --actions 16 input.mod
    Reading policy...
    libsepol.policydb_index_others: security:  0 users, 1 roles, 2 types, 0 bools
    libsepol.policydb_index_others: security: 0 sens, 0 cats
    libsepol.policydb_index_others: security:  1 classes, 0 rules, 0 cond rules
    libsepol.policydb_index_others: security:  0 users, 1 roles, 2 types, 0 bools
    libsepol.policydb_index_others: security: 0 sens, 0 cats
    libsepol.policydb_index_others: security:  1 classes, 0 rules, 0 cond rules
    Binary policy module file loaded.
    Module name: input
    Module version: 1.0.0
    Policy version: 21

    unconditional avtab:
    --- begin avrule block ---
    decl 1:
      allow [httpd_t] [http_port_t] : [tcp_socket] { name_bind };

     [http_port_t] [2]: type flags:0
     [httpd_t] [1]: type flags:0

Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
While at it, remove trailing whitespaces.

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
- Add missing options
- Add examples
- Emphasize keywords
- Remove trailing whitespaces

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
While at it, remove trailing whitespaces.

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Also fix some typos and remove trailing whitespaces.

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Expand the description to make it more clear what "interfaces" mean
here. They're different from network interfaces used by SELinux
command `semanage interface`.

Add a note that the information comes from on-disk file which has been
installed and it doesn't necessarily match the policy loaded to the
kernel.

Signed-off-by: Topi Miettinen <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
masatake and others added 15 commits June 8, 2023 15:13
Example session:

    $ ./dispol --help
    Usage:
     ./dismod [OPTIONS] binary_pol_file

    Options:
     -h, --help              print this help message
     -a, --actions ACTIONS   run non-interactively

    Actions:
      1    display unconditional AVTAB
      2    display conditional AVTAB (entirely)
      3    display conditional AVTAB (only ENABLED rules)
      4    display conditional AVTAB (only DISABLED rules)
      5    display conditional bools
      6    display conditional expressions
      8    display role transitions
      c    display policy capabilities
      b    display booleans
      C    display classes
      r    display roles
      t    display types
      a    display type attributes
      p    display the list of permissive types
      u    display unknown handling setting
      F    display filename_trans rules

    $ ./dispol --actions 1 /etc/selinux/targeted/policy/policy.33  | head
    Reading policy...
    libsepol.policydb_index_others: security:  8 users, 15 roles, 5408 types, 358 bools
    libsepol.policydb_index_others: security: 1 sens, 1024 cats
    libsepol.policydb_index_others: security:  134 classes, 86750 rules, 8818 cond rules
    binary policy file loaded

    allow abrt_dump_oops_t sssd_var_lib_t : sock_file { write getattr append open };
    type_transition authconfig_t entropyd_initrc_exec_t : process initrc_t;
    type_transition glusterd_t syslogd_initrc_exec_t : process initrc_t;xxxx

Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
The following commit
SELinuxProject/refpolicy@330b0fc
changed the userdom_base_user_template, which now requires a role
corresponding to the user being created to be defined outside of the
template.
Similar change was also done to fedora-selinux/selinux-policy
fedora-selinux/selinux-policy@e1e216b

Although I believe the template should define the role (just as it
defines the new user), that will require extensive changes to refpolicy.
In the meantime the role needs to be defined separately.

Fixes:
    # sepolicy generate --term_user -n newuser
    Created the following files:
    /root/a/test/newuser.te # Type Enforcement file
    /root/a/test/newuser.if # Interface file
    /root/a/test/newuser.fc # File Contexts file
    /root/a/test/newuser_selinux.spec # Spec file
    /root/a/test/newuser.sh # Setup Script

    # ./newuser.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile newuser.pp
    Compiling targeted newuser module
    Creating targeted newuser.pp policy package
    rm tmp/newuser.mod tmp/newuser.mod.fc
    + /usr/sbin/semodule -i newuser.pp
    Failed to resolve roleattributeset statement at /var/lib/selinux/targeted/tmp/modules/400/newuser/cil:8
    Failed to resolve AST
    /usr/sbin/semodule:  Failed!

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Use "semanage user -a/-d" in spec file generated by "sepolicy generate"
even when SELinux is disabled. The command works properly when SELinux
is disabled and with this change the user will be present once SELinux
is re-enabled.
Also, do not execute the command when the package is updated, only when
it is first installed.

Signed-off-by: Vit Mojzis <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Many of the initial SIDs are no longer used by the kernel, so
translating them to the legacy names doesn't bring much value. Clear the
legacy names from the table and let the code translate them to the
fallback "unknown" names instead.

Note that this only affects the generated text output when converting
policies from binary to text form. The text policy languages let the
policy define its own names for the initial SIDs based on the order in
which they are declared, so the table is never used to convert from name
to SID. Thus this is just a cosmetic change and has no functional
impact.

Signed-off-by: Ondrej Mosnacek <[email protected]>
Acked-by: James Carter <[email protected]>
Resurrect the naming of the "init" initial SID, as it has been
reintroduced in the kernel. Also add the new "userspace_initial_context"
policy capability that is used to enable the new semantics for this
initial SID.

Signed-off-by: Ondrej Mosnacek <[email protected]>
Add the command line argument `-N/--disable-neverallow`, similar to
secilc(8), to checkpolicy(8) and checkmodule(8) to skip the check of
neverallow rule violations.

This is mainly useful in development, e.g. to quickly add rules to a
policy without fulfilling all neverallow rules or build policies with
known violations.

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
* fix minus self formatting in neverallow rules, avoiding `~ - self`

* show neverallow and neverallowxperm rules

* whitespace improvements in output
  - avoid duplicate whitespaces before permission list, since
    sepol_av_to_string() already adds a trailing one
  - avoid duplicate whitespace after wildcard type
  - unify indentation for xperm rules

* drop unused global variables

Signed-off-by: Christian Göttsche <[email protected]>
Acked-by: James Carter <[email protected]>
Instead, a new action, 'v' for printing the policy (and/or
module) version in batch mode is added.

Signed-off-by: Masatake YAMATO <[email protected]>
Acked-by: James Carter <[email protected]>
A change in v2:
* pass `verbose' to sepol_module_package_read().

Signed-off-by: Masatake YAMATO <[email protected]>
Check the return value of calloc() to avoid null pointer reference.

Signed-off-by: Huaxin Lu <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
This adds more exceptions to be handled by the except clause in
`get_os_version()`:

* If the `distro` package is not installed, then `import distro` raises
  a `ModuleNotFoundError` exception.

* The distro documentation[1] lists `OSError` and `UnicodeError` as
  exceptions that can be raised.

* Older versions of distro (<= 1.6.0) may also raise
  `subprocessCalledProcessError`[2].

[1]: https://github.com/python-distro/distro/blob/v1.8.0/src/distro/distro.py#L749-L753
[2]: https://github.com/python-distro/distro/blob/v1.6.0/distro.py#L726-L728

Signed-off-by: Jeffery To <[email protected]>
Acked-by: Petr Lautrbach <[email protected]>
Drop unnecessary declarations.
Reduce scope of file global variable.
Mention -v argument in help usage message.
More strict integer conversion.
More strict argument count checking.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.
Add help argument option -h.
Set close-on-exec flag in case of any sibling threads.

Signed-off-by: Christian Göttsche <[email protected]>
---
v2:
  - address comments by Jim:
    * drop exit() calls
    * reduce to only one final return statement
  - add help argument option -h
  - set close-on-exec flag
Drop unnecessary declarations.
More verbose error messages and add missing trailing newline.
More strict argument count checking.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.
Add help argument option -h.
Set close-on-exec flag in case of any sibling thread.

Signed-off-by: Christian Göttsche <[email protected]>
---
v2:
  - address comment from Jim
    * avoid exit() calls
    * reduce to one final return statement
    * drop global variable progname
  - add help argument option
  - set close-on-exec flag
Drop unnecessary declarations.
Add missing error messages.
More strict command line argument parsing.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.
Set close-on-exec flag in case of any sibling thread.

Signed-off-by: Christian Göttsche <[email protected]>
---
v2:
  - address comment from Jim
    * drop exit() calls
    * reduce to one final return statement
    * drop unnecessary ? option handling
    * drop global variable progname
  - set close-on-exec flag
Drop unnecessary declarations.
Check closing file for incomplete write.
Rework resource cleanup, so that all files and allocated memory are
released in all branches, useful to minimize reports while debugging
libsepol under valgrind(8) or sanitizers.

Signed-off-by: Christian Göttsche <[email protected]>
---
v2:
address comments from Jim
  * drop exit() calls
  * reduce to one final return statement
  * drop global variable progname
Signed-off-by: Christian Göttsche <[email protected]>
@cgzones cgzones closed this Aug 5, 2023
@cgzones cgzones deleted the z36_patch_semodule-utils branch August 5, 2023 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants