SELinux Policy Language

Introduction

This section is intended as a reference to give a basic understanding of the policy language statements and rules with supporting examples taken from the Reference Policy sources. Also all of the language updates to Policy DB version 28 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 will define a new policy definition language that could eventually replace the current policy language described in this section. Reference to CIL can be found at: http://userspace.selinuxproject.org/trac/wiki/CilDesign, however it is not yet complete although a simple compiler is available by:

git clone http://oss.tresys.com/git/cil.git

CIL Overview

While the CIL design web pages give the main objectives of CIL, from a language perspective it will:

Apply consistancy to the current language statements. For example the type_transition statement has been extended to allow an additional parameter to support object names. With CIL this becomes two separate statements typetransition and nametypetransition.

Examples:

CIL

Current

allow

allow

roleallow

allow (role)

dominance

dominance

roledominance

dominance (role)

roletransition

role_transition

Additional CIL statements have been defined to allow clarity, for example:

typeattributeset

classpermissionset

classmap

classmapping

Allow named an anonymous context definitions to be defined. This example shows the both context declarations and the supporting statements required to build them:

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 except.

Policy Statements and Rules

Policy Source Files

There are three basic types of policy source file that can contain language statements and rules. The three types of policy source file 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 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 or checkmodule 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 minimum (and therefore mandatory) statements that must be defined.

Base Entries

M/O

Security Classes (class)

m

Initial SIDs

m

Access Vectors (permissions)

m

MLS sensitivity, category and level Statements

o

MLS Constraints

o

Policy Capability Statements

o

Attributes

o

Booleans

o

Default user, role, type, range rules

o

Type / Type Alias

m

Roles

m

Policy Rules

o

Users

m

Constraints

o

Default SID labeling

m

fs_use_xattr Statements

o

fs_use_task and fs_use_trans Statements

o

genfscon Statements

o

portcon, netifcon and nodecon Statements

o

Module Entries

module Statement

o

require Statement

o

Attributes

o

Booleans

o

Type / Type Alias

o

Roles

o

Policy Rules

o

Users

o

Table 1: Base and Module Policy Statements - A Monolithic source file would contain the same statements as the Base Module. The Mandatory policy entries are noted (the type, role and user require at least one entry each).

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:

Monolithic Policy

Base Policy

Module Policy

Yes/No

Yes/No

Yes/No

Where:

Monolithic Policy - Whether the statement is allowed within a monolithic 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:

Conditional Policy (if) Statement

optional Statement

require Statement

Yes/No

Yes/No

Yes/No

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.

Statements that were defined in the older NSA documentation have been updated to capture changes such as to prohibit the use of * and ~ in type and role sets (other than in the neverallow statement). Note that some of these changes are not captured by the language grammar, but are managed within the policy_parse.y source code).

When multiple source and target entries are shown in a single statement or rule, the compiler (checkpolicy or checkmodule) will expand these to individual statements or rules as shown in the following example:

Therefore when comparing the actual source code with a compiled binary using (for example) apol, 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 2: Policy language reserved words.

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

Monolithic Policy

Base Policy

Module Policy

Conditional Statements

optional Statement

require Statement

allow

Yes

Yes

Yes

Yes

Yes

No

allow - Role

Yes

Yes

Yes

No

Yes

No

attribute

Yes

Yes

Yes

No

Yes

Yes

attribute_role

Yes

Yes

Yes

No

Yes

Yes

auditallow

Yes

Yes

Yes

Yes

Yes

No

auditdeny (Deprecated)

Yes

Yes

Yes

Yes

Yes

No

bool

Yes

Yes

Yes

No

Yes

Yes

category

Yes

Yes

No

No

No

Yes

class

Yes

Yes

No

No

No

Yes

common

Yes

Yes

No

No

No

No

constrain

Yes

Yes

No

No

No

No

default_user

Yes

Yes

No

No

No

No

default_role

Yes

Yes

No

No

No

No

default_type

Yes

Yes

No

No

No

No

default_range

Yes

Yes

No

No

No

No

dominance - MLS

Yes

Yes

No

No

No

No

dominance - Role (Deprecated)

Yes

Yes

Yes

No

Yes

No

dontaudit

Yes

Yes

Yes

Yes

Yes

No

fs_use_task

Yes

Yes

No

No

No

No

fs_use_trans

Yes

Yes

No

No

No

No

fs_use_xattr

Yes

Yes

No

No

No

No

genfscon

Yes

Yes

No

No

No

No

if

Yes

Yes

Yes

No

Yes

No

level

Yes

Yes

No

No

No

No

mlsconstrain

Yes

Yes

No

No

No

No

mlsvalidatetrans

Yes

Yes

No

No

No

No

module

No

No

Yes

No

No

No

netifcon

Yes

Yes

No

No

No

No

neverallow

Yes

Yes

Yes (1)

No

Yes

No

nodecon

Yes

Yes

No

No

No

No

optional

No

Yes

Yes

Yes

Yes

Yes

permissive

Yes

Yes

Yes

Yes

Yes

No

policycap

Yes

Yes

No

No

No

No

portcon

Yes

Yes

No

No

No

No

range_transition

Yes

Yes

Yes

No

Yes

No

require

No

Yes (2)

Yes

Yes (2)

Yes

No

role

Yes

Yes

Yes

No

Yes

Yes

roleattribute

Yes

Yes

Yes

No

Yes

No

role_transition

Yes

Yes

Yes

No

Yes

No

sensitivity

Yes

Yes

No

No

No

Yes

sid

Yes

Yes

No

No

No

No

type

Yes

Yes

Yes

No

No

Yes

type_change

Yes

Yes

Yes

Yes

Yes

No

type_member

Yes

Yes

Yes

Yes

Yes

No

type_transition

Yes

Yes

Yes

Yes (3)

Yes

No

typealias

Yes

Yes

Yes

No

Yes

No

typeattribute

Yes

Yes

Yes

No

Yes

No

typebounds

Yes

Yes

Yes

No

Yes

No

user

Yes

Yes

Yes

No

Yes

Yes

validatetrans

Yes

Yes

No

No

No

No

Table 3: The policy language statements and rules that are allowed within each type of policy source file - The left hand side of the table shows what Policy Language Statements and Rules are allowed within each type of policy source file. The right hand side of the table shows whether the statement is valid within the if / else construct, optional {rule_list}, or require {rule_list} statement.

(1) neverallow statements are allowed in modules, however to detect these the semanage.conf file must have the expand-check=1 entry present.
(2) Only if preceded by the optional statement.
(3) Excluding the 'file name transition' rule.