There are tools out there that help in developing SELinux policies, and if needed we can build our own support tools as well. Let’s see what support environments we can use.
Verifying code with selint
One of the tools that support validating SELinux policy code is
selint, as offered from https://github.com/TresysTechnology/selint. Once built and installed,
selint offers insights into four main areas:
- Convention checks validate whether the SELinux policy follows the reference policy convention on how code should be structured and documented.
- Style checks give hints for code style that might be wrong, and where the developer might have intended a different behavior.
- Warnings are triggered when the code has bad calls that might trigger runtime issues or security issues.
- Errors catch construction faults that will result in compile issues or runtime issues.
$ selint minecraft.te minecraft.te: 31: (C): Permissions in av rule not ordered (signull before execmem) (C-005) minecraft.te: 118: (C): Require block used in te file (use an interface call instead) (S-001)
In this case, two convention malpractices were detected. One is in the ordering of permissions, while another has an explicit require block mentioned for a domain that is not part of that policy module.
Querying the interfaces and macros locally
The functions are provided as code together with this book. You might want to change the path that the
POLICY_LOCATION variable points to at the beginning of the script. By default, it points to the system-installed interface and macros, but you can point it to repository checkouts as well:
Source the file to have access to the helper functions:
$ source ./localfuncs
The helper functions you can use are the following:
sefindifyou can search for an SELinux interface that has a specific SELinux rule inside. You can use regular expressions to find the appropriate one.
For instance, to find the interface that grants a domain the privileges to manage certificate files (for readability, we only show the interface code; it will be prefixed with the location where it found it):
$ sefindif "manage.* cert_t" interface(`miscfiles_manage_all_certs',` manage_files_pattern($1, cert_type, cert_type) manage_lnk_files_pattern($1, cert_type, cert_type) interface(`miscfiles_manage_generic_cert_dirs',` manage_dirs_pattern($1, cert_t, cert_t) interface(`miscfiles_manage_generic_cert_files',` manage_files_pattern($1, cert_t, cert_t) manage_lnk_files_pattern($1, cert_t, cert_t)
$ seshowif miscfiles_manage_all_certs interface(`miscfiles_manage_all_certs',` gen_require(` attribute cert_type; ') allow $1 cert_type:dir list_dir_perms; manage_files_pattern($1, cert_type, cert_type) manage_lnk_files_pattern($1, cert_type, cert_type) ')
$ seshowdef admin_pattern define(`admin_pattern',` manage_dirs_pattern($1,$2,$2) manage_files_pattern($1,$2,$2) manage_lnk_files_pattern($1,$2,$2) manage_fifo_files_pattern($1,$2,$2) manage_sock_files_pattern($1,$2,$2) relabel_dirs_pattern($1,$2,$2) relabel_files_pattern($1,$2,$2) relabel_lnk_files_pattern($1,$2,$2) relabel_fifo_files_pattern($1,$2,$2) relabel_sock_files_pattern($1,$2,$2) ')
While such functions do not offer the same versatility as a full-fledged policy editor suite would, they can help in quickly finding the right interface or macro.