PolicyLanguage
Contents
SELinux Policy Languages
Introduction
This section is intended as a reference to give a basic understanding of the kernel policy language statements and rules with supporting examples taken from the Reference Policy sources. Also all of the language updates to Policy DB version 29 should have been captured. For a more detailed explanation of the policy language the "SELinux by Example" book is recommended.
There is currently a project underway called the Common Intermediate Language (CIL) project that defines a new policy definition language that has an overview of its motivation and design at: https://github.com/SELinuxProject/cil/wiki, however some of the language statement definitions out of date. The CIL compiler source and language reference guide can be found at: https://github.com/SELinuxProject/cil.git and cloned via:
git clone https://github.com/SELinuxProject/cil.git
The CIL compiler language reference guide has examples for each type of statement and can be built in pdf or html formats, therefore this Notebook will not cover the CIL policy language (there is a pdf copy of the CIL Reference Guide in the Notebook tarball). There is a migration programme underway that will convert the Reference Policy to CIL via a high level language module that is discussed in the Policy Store Migration section. Once migration is complete, the CIL compiler will be in available the libsepol library and CIL modules will be compiled with an updated semodule(8) command as follows:
# Compile and install an updated module written in CIL: semodule -s modular-test --priority 400 -i custom/int_gateway.cil
Note that any source policy file name with the '.cil' extension will automatically be built as a CIL module.
CIL Policy Language
While the CIL design web pages give the main objectives of CIL, from a language perspective it will:
- Apply name and usage consistancy to the current kernel language statements. For example the kernel language uses attribute and attribute_role to declare identifiers, whereas CIL uses typeattribute and roleattribute. Also statements to associate types or roles have been made consistant and enhanced to allow expressions to be defined.
Examples:
|
|
attribute | typeattribute |
typeattribute | typeattributeset |
attribute_role | roleattribute |
roleattribute | roleattributeset |
allow | allow |
allow (role) | roleallow |
dominance | sensitivityorder |
- Additional CIL statements have been defined to enhance functionality:
- classpermission - Declare a classpermissionset identifier.
- classpermissionset - Associate class / permissions also supporting expressions.
- classmap / classmapping - Statements to support declaration and association of multiple classpermissionset's. Useful when defining an allow rule with multiple class/permissions.
- context - Statement to declare security context.
- Allow named and anonymous definitions to be supported.
- Support namespace features allowing policy modules to be defined within blocks with inheritance and template features.
- Remove the order dependancy in that policy statements can be anywhere within the source (i.e. remove dependancy of class, sid etc. being within a base module).
- Able to define macros and calls that will remove any dependancy on M4 macro support.
- Directly generate the binary policy file and other configuration files - currently the file_contexts file.
- Support transformation services such as delete, transform and inherit with exceptions.
An simple CIL policy is as follows:
; These CIL statements declare a user, role, type and range of: ;unconfined.user:unconfined.role:unconfined.process:s0-s0 ; ; A CIL policy requires at least one 'allow' rule and sid to be declared ; before a policy will build. ; (handleunknown allow) (mls true) (policycap open_perms) (category c0) (categoryorder (c0)) (sensitivity s0) (sensitivityorder (s0)) (sensitivitycategory s0 (c0)) (level systemLow (s0)) (levelrange low_low (systemLow systemLow)) (sid kernel) (sidorder (kernel)) (sidcontext kernel unconfined.sid_context) (classorder (file)) (class file (read write open getattr)) ; Define object_r role. This must be assigned in CIL. (role object_r) ; The unconfined namespace: (block unconfined (user user) (userrange user (systemLow systemLow)) (userlevel user systemLow) (userrole user role) (role role) (type process) (roletype object_r process) (roletype role process) ; Define a SID context: (context sid_context (user role process low_low)) (type object) (roletype object_r object) ; An allow rule: (allow process object (file (read))) )
There are CIL examples in the Notebook source tarball with a utility that will produce a base policy in either the kernel policy language or CIL (notebook-tools/build-sepolicy). The only requirement is that the initial_sids, security_classes and access_vectors files from the Reference policy are required, although the F-20 versions are supplied in the basic-policy/policy-files/flask-files directory.
Usage: build-sepolicy [-k] [-M] [-c|-i|-p|-s] -d flask_directory -o output_file -k Output kernel classes only (exclude # userspace entries in the security_classes file). -M Output an MLS policy. -c Output a policy in CIL language (otherwise gererate a kernel policy language policy). -p Output a file containing class and classpermissionsets + their order for use by CIL policies. -s Output a file containing initial SIDs + their order for use by CIL policies. -i Output a header file containing class/permissions for use by selinux_set_mapping(3). -o The output file that will contain the policy source or header file. -d Directory containing the initial_sids, security_classes and access_vectors Flask files.
Kernel Policy Language
Policy Source Files
There are three basic types of policy source file[1] that can contain language statements and rules. The three types of policy source file[2] are:
- Monolithic Policy - This is a single policy source file that contains all statements. By convention this file is called policy.conf and is compiled using the checkpolicy(8) command that produces the binary policy file.
- Base Policy - This is the mandatory base policy source file that supports the loadable module infrastructure. The whole system policy could be fully contained within this file, however it is more usual for the base policy to hold the mandatory components of a policy, with the optional components contained in loadable module source files. By convention this file is called base.conf and is compiled using the checkpolicy(8) or checkmodule(8) command.
- Module (or Non-base) Policy - These are optional policy source files that when compiled, can be dynamically loaded or unloaded within the policy store. By convention these files are named after the module or application they represent, with the compiled binary having a '.pp' extension. These files are compiled using the checkmodule command.
Table 1 shows the order in which the statements should appear in source files with the mandatory statements that must be present.
Base Entries | |
Module Entries | |
---|---|---|---|
Security Classes (class) | |
module Statement | |
Initial SIDs | | ||
Access Vectors (permissions) | |
require Statement | |
MLS sensitivity, category and level Statements | | ||
MLS Constraints | | ||
Policy Capability Statements | | ||
Attributes | |
Attributes | |
Booleans | |
Booleans | |
Default user, role, type, range rules | |
||
Type / Type Alias | |
Type / Type Alias | |
Roles | |
Roles | |
Policy Rules | |
Policy Rules | |
Users | |
Users | |
Constraints | |
||
Default SID labeling | | ||
fs_use_xattr Statements | | ||
fs_use_task and fs_use_trans Statements | | ||
genfscon Statements | | ||
portcon, netifcon and nodecon Statements | |
The language grammar defines what statements and rules can be used within the different types of source file. To highlight these rules, the following table is included in each statement and rule section to show what circumstances each one is valid within a policy source file:
Where:
Monolithic Policy | Whether the statement is allowed within a monolithic policy source file or not. |
Base Policy | Whether the statement is allowed within a base (for loadable module support) policy source file or not. |
Module Policy | Whether the statement is allowed within the optional loadable module policy source file or not. |
Table 3 shows a cross reference matrix of statements and rules allowed in each type of policy source file.
Conditional, Optional and Require Statement Rules
The language grammar specifies what statements and rules can be included within Conditional Policy, Optional Policy statements and the require statement. To highlight these rules the following table is included in each statement and rule section to show what circumstances each one is valid within a policy source file:
Where:
Conditional Policy (if) Statement | Whether the statement is allowed within a conditional statement (IF / ELSE construct) as described in the if statement section. Conditional statements can be in all types of policy source file. |
optional Statement | Whether the statement is allowed within the optional { rule_list } construct as described in the optional statement section. |
require Statement | Whether the statement keyword is allowed within the require { rule_list } construct as described in the require statement section. |
Table 3 shows a cross reference matrix of statements and rules allowed in each of the above policy statements.
MLS Statements and Optional MLS Components
The MLS Statements section defines statements specifically for MLS support. However when MLS is enabled, there are other statements that require the MLS Security Context component as an argument, therefore these statements show an example taken from the Reference Policy MLS build.
General Statement Information
- Identifiers can generally be any length but should be restricted to the following characters: a-z, A-Z, 0-9 and _ (underscore).
- A '#' indicates the start of a comment in policy source files.
- All statements available to policy version 29 have been included.
- When multiple source and target entries are shown in a single statement or rule, the compiler (checkpolicy(8) or checkmodule(8)) will expand these to individual statements or rules as shown in the following example:
# This allow rule has two target entries console_device_t and tty_device_t: allow apm_t { console_device_t tty_device_t }:chr_file { getattr read write append ioctl lock }; # The compiler will expand this to become: allow apm_t console_device_t:chr_file { getattr read write append ioctl lock }; # and: allow apm_t tty_device_t:chr_file { getattr read write append ioctl lock };
- Therefore when comparing the actual source code with a compiled binary using (for example) apol(8), sedispol or sedismod, the results will differ (however the resulting policy rules will be the same).
- Some statements can be added to a policy via the policy store using the semanage(8) command. Examples of these are shown where applicable, however the semanage man page should be consulted for all the possible command line options.
- Table 2 lists words reserved for the SELinux policy language.
alias | allow | and |
attribute | attribute_role | auditallow |
auditdeny | bool | category |
cfalse | class | clone |
common | constrain | ctrue |
dom | domby | dominance |
dontaudit | else | equals |
false | filename | filesystem |
fscon | fs_use_task | fs_use_trans |
fs_use_xattr | genfscon | h1 |
h2 | identifier | if |
incomp | inherits | iomemcon |
ioportcon | ipv4_addr | ipv6_addr |
l1 | l2 | level |
mlsconstrain | mlsvalidatetrans | module |
netifcon | neverallow | nodecon |
not | notequal | number |
object_r | optional | or |
path | pcidevicecon | permissive |
pirqcon | policycap | portcon |
r1 | r2 | r3 |
range | range_transition | require |
role | roleattribute | roles |
role_transition | sameuser | sensitivity |
sid | source | t1 |
t2 | t3 | target |
true | type | typealias |
typeattribute | typebounds | type_change |
type_member | types | type_transition |
u1 | u2 | u3 |
user | validatetrans | version_identifier |
xor | default_user | default_role |
default_type | default_range | low |
high | low_high |
- Table 3 shows what policy language statements and rules are allowed within each type of policy source file, and whether the statement is valid within an if / else construct, optional {rule_list}, or require {rule_list} statement.
Statement / Rule | |
|
|
|
|
|
---|---|---|---|---|---|---|
allow | |
|
|
|
|
|
allow - Role | |
|
|
|
|
|
attribute | |
|
|
|
|
|
attribute_role | |
|
|
|
|
|
auditallow | |
|
|
|
|
|
auditdeny (Deprecated) | |
|
|
|
|
|
bool | |
|
|
|
|
|
category | |
|
|
|
|
|
class | |
|
|
|
|
|
common | |
|
|
|
|
|
constrain | |
|
|
|
|
|
default_user | |
|
|
|
|
|
default_role | |
|
|
|
|
|
default_type | |
|
|
|
|
|
default_range | |
|
|
|
|
|
dominance - MLS | |
|
|
|
|
|
dominance - Role (Deprecated) | |
|
|
|
|
|
dontaudit | |
|
|
|
|
|
fs_use_task | |
|
|
|
|
|
fs_use_trans | |
|
|
|
|
|
fs_use_xattr | |
|
|
|
|
|
genfscon | |
|
|
|
|
|
if | |
|
|
|
|
|
level | |
|
|
|
|
|
mlsconstrain | |
|
|
|
|
|
mlsvalidatetrans | |
|
|
|
|
|
module | |
|
|
|
|
|
netifcon | |
|
|
|
|
|
neverallow | |
|
|
|
|
|
nodecon | |
|
|
|
|
|
optional | |
|
|
|
|
|
permissive | |
|
|
|
|
|
policycap | |
|
|
|
|
|
portcon | |
|
|
|
|
|
range_transition | |
|
|
|
|
|
require | |
|
|
|
|
|
role | |
|
|
|
|
|
roleattribute | |
|
|
|
|
|
role_transition | |
|
|
|
|
|
sensitivity | |
|
|
|
|
|
sid | |
|
|
|
|
|
type | |
|
|
|
|
|
type_change | |
|
|
|
|
|
type_member | |
|
|
|
|
|
type_transition | |
|
|
|
|
|
typealias | |
|
|
|
|
|
typeattribute | |
|
|
|
|
|
typebounds | |
|
|
|
|
|
user | |
|
|
|
|
|
validatetrans | |
|
|
|
|
|
Kernel Policy Language Definition Links
The kernel policy language statement and rule sections are as follows:
- Policy Configuration Statements
- Default Rules
- User Statements
- Role Statements
- Type Statements
- Bounds Rules
- Access Vector Rules
- Object Class and Permission Statements
- Conditional Policy Statements
- Constraint Statements
- MLS Statements
- Security ID (SID) Statement
- File System Labeling Statements
- Network Labeling Statements
- Modular Policy Support Statements
- XEN Statements
Unused entries for edition 4 (to be removed):
Previous | |
|
- ↑ It is important to note that the Reference Policy builds policy using makefiles and m4 support macros within its own source file structure. However, the end result of the make process is that there can be three possible types of source file built (depending on the MONOLITHIC=Y/N build option). These files contain the policy language statements and rules that are finally complied into a binary policy.
- ↑ This does not include the 'file_contexts' file as it does not contain policy statements, only default security contexts (labels) that will be used to label files and directories.
- ↑ Only the statement keyword is allowed.
- ↑ neverallow statements are allowed in modules, however to detect these the semanage.conf file must have the expand-check=1 entry present.
- ↑ Only if preceded by the optional statement.
- ↑ Only if preceded by the optional statement.