Difference between revisions of "PolicyStatements"

From SELinux Wiki
Jump to: navigation, search
(New page: = Policy Support Statements = This section contains language statements used to support policy. == module Statement == This statement is mandatory for loadable modules (non-base) and must...)
 
 
Line 1: Line 1:
= Policy Support Statements =
+
= Modular Policy Support Statements =
This section contains language statements used to support policy.
+
This section contains language statements used to support policy modules.
  
== module Statement ==
+
== module ==
 
This statement is mandatory for loadable modules (non-base) and must be the first line of any module policy source file. The identifier should not conflict with other module names within the overall policy, otherwise it will over-write an existing module when loaded via the semodule command. The semodule -l command can be used to list all active modules within the policy.
 
This statement is mandatory for loadable modules (non-base) and must be the first line of any module policy source file. The identifier should not conflict with other module names within the overall policy, otherwise it will over-write an existing module when loaded via the semodule command. The semodule -l command can be used to list all active modules within the policy.
  
Line 9: Line 9:
 
module module_name version_number;
 
module module_name version_number;
 
</pre>
 
</pre>
 
  
 
'''Where:'''
 
'''Where:'''
{|border="1"
+
 
|module
+
{| border="1"
|The module keyword.
+
| module
 +
| The module keyword.
  
 
|-
 
|-
|module_name
+
| module_name
|The module name.  
+
| The module name.  
  
 
|-
 
|-
|version_number
+
| version_number
|The module version number in M.m.m format (where M = major version number and m = minor version numbers).
+
| The module version number in M.m.m format (where M = major version number and m = minor version numbers).
  
 
|}
 
|}
Line 28: Line 28:
  
 
'''The statement is valid in:'''
 
'''The statement is valid in:'''
{|border="1"
+
 
 +
{| border="1"
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Base Policy'''</center>
 
|<center>'''Base Policy'''</center>
Line 34: Line 35:
  
 
|-
 
|-
|<center>No</center>
+
| <center>'''No'''</center>
|<center>No</center>
+
| <center>'''No'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
 +
|}
  
|-
+
 
|<center>'''Conditional Policy (if) Statement'''</center>
+
{| border="1"
|<center>'''optional Statement'''</center>
+
| <center>[[ConditionalStatements#if | if Statement]]</center>
|<center>'''require Statement'''</center>
+
| <center>[[PolicyStatements#optional | optional Statement]] </center>
 +
| <center>[[PolicyStatements#require | require Statement]] </center>
  
 
|-
 
|-
|<center>No</center>
+
| <center>'''No'''</center>
|<center>No</center>
+
| <center>'''No'''</center>
|<center>No</center>
+
| <center>'''No'''</center>
  
 
|}
 
|}
Line 53: Line 56:
 
'''Example:'''
 
'''Example:'''
 
<pre>
 
<pre>
<nowiki># Using the </nowiki>''module'' statement to define a loadable module called  
+
# Using the module statement to define a loadable module called  
<nowiki># </nowiki>''bind'' with a version ''1.0.0'':
+
# bind with a version 1.0.0:
  
 
module bind 1.8.0;
 
module bind 1.8.0;
 
</pre>
 
</pre>
  
== require Statement ==
+
== require ==
 
The require statement is used for two reasons:
 
The require statement is used for two reasons:
 
 
# Within loadable module policy source files to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in this module but elsewhere). The examples below show the usage.
 
# Within loadable module policy source files to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in this module but elsewhere). The examples below show the usage.
# Within a base policy source file, but only if preceded by the optional Statement to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in the base policy but elsewhere). The examples below show the usage.
+
# Within a base policy source file, but only if preceded by the [[#optional | optional]] statement to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in the base policy but elsewhere). The examples below show the usage.
  
 
'''The statement definition is:'''
 
'''The statement definition is:'''
Line 71: Line 73:
  
 
'''Where:'''
 
'''Where:'''
{|border="1"
+
 
|require
+
{| border="1"
|The require keyword.
+
| require
 +
| The require keyword.
  
 
|-
 
|-
|require_list
+
| require_list
|One or more specific statement keywords with their required identifiers in a semi-colon (<nowiki>;</nowiki>) separated list enclosed within braces ({}).  
+
| One or more specific statement keywords with their required identifiers in a semi-colon (<nowiki>;</nowiki>) separated list enclosed within braces ({}).  
  
 
The valid statement keywords are:
 
The valid statement keywords are:
 
 
* role, type, attribute, user, bool, sensitivity and category. The keyword is followed by one or more identifiers in a comma (,) separated list, with the last entry being terminated with a semi-colon (<nowiki>;</nowiki>).
 
* role, type, attribute, user, bool, sensitivity and category. The keyword is followed by one or more identifiers in a comma (,) separated list, with the last entry being terminated with a semi-colon (<nowiki>;</nowiki>).
 
* class. The class keyword is followed by a single object class identifier and one or more permissions. Multiple permissions consist of a space separated list enclosed within braces ({}). The list is then terminated with a semi-colon (<nowiki>;</nowiki>).
 
* class. The class keyword is followed by a single object class identifier and one or more permissions. Multiple permissions consist of a space separated list enclosed within braces ({}). The list is then terminated with a semi-colon (<nowiki>;</nowiki>).
Line 90: Line 92:
  
 
'''The statement is valid in:'''
 
'''The statement is valid in:'''
{|border="1"
+
 
 +
{| border="1"
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Base Policy'''</center>
 
|<center>'''Base Policy'''</center>
Line 96: Line 99:
  
 
|-
 
|-
|<center>No</center>
+
| <center>'''No'''</center>
|<center>Yes - But only if proceeded by the optional Statement.</center>
+
| <center>'''Yes - But only if proceeded by the [[#optional | optional]] Statement.'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
 +
|}
  
|-
 
|<center>'''Conditional Policy (if) Statement'''</center>
 
|<center>'''optional Statement'''</center>
 
|<center>'''require Statement'''</center>
 
  
|-
+
{| border="1"
|<center>Yes - But only if proceeded by the optional Statement.</center>
+
| <center>[[ConditionalStatements#if | if Statement]]</center>
|<center>Yes</center>
+
| <center>[[PolicyStatements#optional | optional Statement]] </center>
|<center>No</center>
+
| <center>[[PolicyStatements#require | require Statement]] </center>
  
 +
|-
 +
| <center>'''Yes - But only if proceeded by the [[#optional | optional]] Statement.'''</center>
 +
| <center>'''Yes'''</center>
 +
| <center>'''No'''</center>
 
|}
 
|}
  
Line 115: Line 119:
 
'''Examples:'''
 
'''Examples:'''
 
<pre>
 
<pre>
<nowiki># A series of require statements showing various entries:</nowiki>
+
# A series of require statements showing various entries:
  
 
require {
 
require {
      role system_r;
+
    role system_r;
      class security { compute_av compute_create compute_member check_context load_policy  
+
    class security { compute_av compute_create compute_member  
        compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot };
+
        check_context load_policy compute_relabel compute_user  
      class capability2 { mac_override mac_admin };
+
        setenforce setbool setsecparam setcheckreqprot };
 +
    class capability2 { mac_override mac_admin };
 
}
 
}
  
<nowiki>#</nowiki>
+
#
 
require {
 
require {
    attribute direct_run_init, direct_init, direct_init_entry;
+
    attribute direct_run_init, direct_init, direct_init_entry;
    type initrc_t;
+
    type initrc_t;
    role system_r;
+
    role system_r;
    attribute daemon;
+
    attribute daemon;
 
}
 
}
  
<nowiki>#</nowiki>
+
#
 
require {
 
require {
    type nscd_t, nscd_var_run_t;
+
    type nscd_t, nscd_var_run_t;
    class nscd { getserv getpwd getgrp gethost shmempwd shmemgrp  
+
    class nscd { getserv getpwd getgrp gethost shmempwd shmemgrp  
    shmemhost shmemserv };
+
    shmemhost shmemserv };
 
}
 
}
 
</pre>
 
</pre>
  
== optional Statement ==
+
== optional ==
The optional statement is used to indicate what policy statements may or may not be present in the final compiled policy. The statements will be included in the policy only if all statements within the optional { rule list } can be expanded successfully, this is generally achieved by using a require Statement at the start of the list.
+
The optional statement is used to indicate what policy statements may or may not be present in the final compiled policy. The statements will be included in the policy only if all statements within the optional { rule list } can be expanded successfully, this is generally achieved by using a [[#require | require]] Statement at the start of the list.
  
 
'''The statement definition is:'''
 
'''The statement definition is:'''
 
<pre>
 
<pre>
optional { rule_list }
+
optional { rule_list } [ else { rule_list } ]
</pre>
+
'''Or'''
+
<pre>
+
optional { rule_list } else { rule_list }
+
 
</pre>
 
</pre>
  
 
'''Where:'''
 
'''Where:'''
{|border="1"
 
|optional
 
|The optional keyword.
 
  
|-
+
{| border="1"
|rule_list
+
| optional
|One or more statements enclosed within braces ({}). The list of valid statements is given in a list I have somewhere !!.
+
| The optional keyword.
  
 
|-
 
|-
|else
+
| rule_list
|An optional else keyword.
+
| One or more statements enclosed within braces ({}).
 +
|-
 +
| else
 +
| An optional else keyword.
  
 
|-
 
|-
|rule_list
+
| rule_list
|As the rule_list above.
+
| As the rule_list above.
  
 
|}
 
|}
Line 173: Line 174:
  
 
'''The statement is valid in:'''
 
'''The statement is valid in:'''
{|border="1"
+
 
 +
{| border="1"
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Monolithic Policy'''</center>
 
|<center>'''Base Policy'''</center>
 
|<center>'''Base Policy'''</center>
Line 179: Line 181:
  
 
|-
 
|-
|<center>No</center>
+
| <center>'''No'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
 +
|}
  
|-
+
 
|<center>'''Conditional Policy (if) Statement'''</center>
+
{| border="1"
|<center>'''optional Statement'''</center>
+
| <center>[[ConditionalStatements#if | if Statement]]</center>
|<center>'''require Statement'''</center>
+
| <center>[[PolicyStatements#optional | optional Statement]] </center>
 +
| <center>[[PolicyStatements#require | require Statement]] </center>
  
 
|-
 
|-
|<center>Yes</center>
+
| <center>'''Yes'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
|<center>Yes</center>
+
| <center>'''Yes'''</center>
  
 
|}
 
|}
Line 198: Line 202:
 
'''Examples:'''
 
'''Examples:'''
 
<pre>
 
<pre>
<nowiki># Use of </nowiki>''optional'' block in a base policy source file.
+
# Use of optional block.
  
 
optional {
 
optional {
    require {
+
    require {
          type unconfined_t;
+
        type unconfined_t;
    } # end require
+
    } # end require
 
+
    allow acct_t unconfined_t:fd use;
    allow acct_t unconfined_t:fd use;
+
 
+
 
} # end optional
 
} # end optional
 
</pre>
 
</pre>
 
<pre>
 
<pre>
<nowiki># Use of </nowiki>''optional'' / ''else'' blocks in a base policy source file.
+
# Use of optional / else blocks.
  
 
optional {
 
optional {
    require {
+
    require {
          type ping_t, ping_exec_t;
+
        type ping_t, ping_exec_t;
    } # end require
+
    } # end require
 +
    allow dhcpc_t ping_exec_t:file { getattr read execute };
 +
    .....
  
    allow dhcpc_t ping_exec_t:file { getattr read execute };
+
    require {
    .....
+
        type netutils_t, netutils_exec_t;
 
+
    } # end require
    require {
+
    allow dhcpc_t netutils_exec_t:file { getattr read execute };
          type netutils_t, netutils_exec_t;
+
    .....
    } # end require
+
    type_transition dhcpc_t netutils_exec_t:process netutils_t;
 
+
    ...
    allow dhcpc_t netutils_exec_t:file { getattr read execute };
+
    .....
+
    type_transition dhcpc_t netutils_exec_t:process netutils_t;
+
    ...
+
  
 
} else {
 
} else {
 
+
    allow dhcpc_t self:capability setuid;
    allow dhcpc_t self:capability setuid;
+
    .....
    .....
+
} # end optional / else block
} # end optional
+
 
</pre>
 
</pre>
  
  
== policycap Statement ==
+
{| style="width: 100%;" border="0"
Policy database version 22 introduced the policycap statement to allow new capabilities to be enabled or disabled via the policy. In Fedora 10 there are two policy capabilities configured as shown in the SELinux Filesystem section, and are network_peer_controls and open_perms.
+
 
+
'''The statement definition is:'''
+
<pre>
+
policycap capability;
+
</pre>
+
 
+
'''Where:'''
+
{|border="1"
+
|policycap
+
|The policycap keyword.
+
 
+
 
|-
 
|-
|capability
+
| [[NetworkStatements | '''Previous''']]
|The capability identifier that needs to be enabled for this policy.
+
| <center>[[NewUsers | '''Home''']]</center>
 
+
| <center>[[XENStatements | '''Next''']]</center>
 
|}
 
|}
  
  
'''The statement is valid in:'''
+
----
{|border="1"
+
<references/>
|<center>'''Monolithic Policy'''</center>
+
|<center>'''Base Policy'''</center>
+
|<center>'''Module Policy'''</center>
+
  
|-
+
[[Category:Notebook]]
|<center>Yes</center>
+
|<center>Yes</center>
+
|<center>No</center>
+
 
+
|-
+
|<center>'''Conditional Policy (if) Statement'''</center>
+
|<center>'''optional Statement'''</center>
+
|<center>'''require Statement'''</center>
+
 
+
|-
+
|<center>No</center>
+
|<center>No</center>
+
|<center>No</center>
+
 
+
|}
+
 
+
 
+
'''Example:'''
+
<pre>
+
<nowiki># This statement enables the </nowiki>network_peer_controls to be enabled
+
<nowiki># for use by the policy</nowiki>.
+
<nowiki># </nowiki>
+
 
+
policycap network_peer_controls;
+
</pre>
+
 
+
== permissive Statement ==
+
Policy database version 23 introduced the permissive statement to allow the named domain to run in permissive mode instead of running all SELinux domains in permissive mode (that was the only option prior to version 23). Note that the permissive statement:
+
 
+
* Only tests the source context for any policy denial.
+
* Can be set by the semanage command as it supports a permissive option as follows:
+
 
+
** semanage supports enabling and disabling of permissive
+
** mode using the following command:
+
<pre>
+
<nowiki># semanage permissive -a|d type</nowiki>
+
<nowiki># This example will add a new module in /etc/selinux/</nowiki>
+
<nowiki># <policy_name>/modules/active/modules/ called</nowiki>
+
<nowiki># permissive_unconfined_t.pp and then reload the policy: </nowiki>
+
 
+
semanage permissive -a unconfined_t
+
</pre>
+
 
+
* Can be built into a loadable policy module so that permissive mode can be easily enabled or disabled by adding or removing the module. An example module is as follows:
+
<pre>
+
<nowiki># This is an example loadable module that would allow the</nowiki>
+
<nowiki># domain to be set to permissive mode.</nowiki>
+
<nowiki>#</nowiki>
+
 
+
module permissive_unconfined_t 1.0.0;
+
 
+
require {
+
    type unconfined_t;
+
}
+
 
+
permissive unconfined_t;
+
</pre>
+
 
+
'''The statement definition is:'''
+
<pre>
+
permissive type_id;
+
</pre>
+
 
+
'''Where:'''
+
{|border="1"
+
|permissive
+
|The permissive keyword.
+
 
+
|-
+
|type_id
+
|The type identifier of the domain that will be run in permissive mode.
+
 
+
|}
+
 
+
 
+
'''The statement is valid in:'''
+
{|border="1"
+
|<center>'''Monolithic Policy'''</center>
+
|<center>'''Base Policy'''</center>
+
|<center>'''Module Policy'''</center>
+
 
+
|-
+
|<center>Yes</center>
+
|<center>Yes</center>
+
|<center>Yes</center>
+
 
+
|-
+
|<center>'''Conditional Policy (if) Statement'''</center>
+
|<center>'''optional Statement'''</center>
+
|<center>'''require Statement'''</center>
+
 
+
|-
+
|<center>No</center>
+
|<center>Yes</center>
+
|<center>No</center>
+
 
+
|}
+
 
+
 
+
'''Example:'''
+
<pre>
+
<nowii># This is the simple statement that would allow permissive mode</nowiki>
+
<nowiki># to be set on the httpd_t domain, however this statement is</nowiki>
+
<nowiki># generally built into a loadable policy module so that the</nowiki>
+
<nowiki># permissive mode can be easily removed by removing the module.</nowiki>
+
<nowiki># </nowiki>
+
 
+
permissive httpd_t;
+
</pre>
+
 
+
'''semanage(8) Command example:'''
+
<pre>
+
semanage permissive -a unconfined_t
+
</pre>
+
 
+
This command will produce the following module in the default <nowiki><policy_name></nowiki> policy store and then activate the policy:
+
<pre>
+
<nowiki>/etc/selinux/<policy_name>/modules/active/modules/permissive_unconfined_t.pp</nowiki>
+
</pre>
+

Latest revision as of 15:12, 28 January 2015

Modular Policy Support Statements

This section contains language statements used to support policy modules.

module

This statement is mandatory for loadable modules (non-base) and must be the first line of any module policy source file. The identifier should not conflict with other module names within the overall policy, otherwise it will over-write an existing module when loaded via the semodule command. The semodule -l command can be used to list all active modules within the policy.

The statement definition is:

module module_name version_number;

Where:

module The module keyword.
module_name The module name.
version_number The module version number in M.m.m format (where M = major version number and m = minor version numbers).


The statement is valid in:

Monolithic Policy
Base Policy
Module Policy
No
No
Yes


if Statement
optional Statement
require Statement
No
No
No


Example:

# Using the module statement to define a loadable module called 
# bind with a version 1.0.0:

module bind 1.8.0;

require

The require statement is used for two reasons:

  1. Within loadable module policy source files to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in this module but elsewhere). The examples below show the usage.
  2. Within a base policy source file, but only if preceded by the optional statement to indicate what policy components are required from an external source file (i.e. they are not explicitly defined in the base policy but elsewhere). The examples below show the usage.

The statement definition is:

require { rule_list }

Where:

require The require keyword.
require_list One or more specific statement keywords with their required identifiers in a semi-colon (;) separated list enclosed within braces ({}).

The valid statement keywords are:

  • role, type, attribute, user, bool, sensitivity and category. The keyword is followed by one or more identifiers in a comma (,) separated list, with the last entry being terminated with a semi-colon (;).
  • class. The class keyword is followed by a single object class identifier and one or more permissions. Multiple permissions consist of a space separated list enclosed within braces ({}). The list is then terminated with a semi-colon (;).

The examples below show these in detail.


The statement is valid in:

Monolithic Policy
Base Policy
Module Policy
No
Yes - But only if proceeded by the optional Statement.
Yes


if Statement
optional Statement
require Statement
Yes - But only if proceeded by the optional Statement.
Yes
No


Examples:

# A series of require statements showing various entries:

require {
    role system_r;
    class security { compute_av compute_create compute_member 
        check_context load_policy compute_relabel compute_user 
        setenforce setbool setsecparam setcheckreqprot };
    class capability2 { mac_override mac_admin };
}

#
require {
    attribute direct_run_init, direct_init, direct_init_entry;
    type initrc_t;
    role system_r;
    attribute daemon;
}

#
require {
    type nscd_t, nscd_var_run_t;
    class nscd { getserv getpwd getgrp gethost shmempwd shmemgrp 
    shmemhost shmemserv };
}

optional

The optional statement is used to indicate what policy statements may or may not be present in the final compiled policy. The statements will be included in the policy only if all statements within the optional { rule list } can be expanded successfully, this is generally achieved by using a require Statement at the start of the list.

The statement definition is:

optional { rule_list } [ else { rule_list } ]

Where:

optional The optional keyword.
rule_list One or more statements enclosed within braces ({}).
else An optional else keyword.
rule_list As the rule_list above.


The statement is valid in:

Monolithic Policy
Base Policy
Module Policy
No
Yes
Yes


if Statement
optional Statement
require Statement
Yes
Yes
Yes


Examples:

# Use of optional block.

optional {
    require {
        type unconfined_t;
    } # end require
    allow acct_t unconfined_t:fd use;
} # end optional
# Use of optional / else blocks.

optional {
    require {
        type ping_t, ping_exec_t;
    } # end require
    allow dhcpc_t ping_exec_t:file { getattr read execute };
    .....

    require {
        type netutils_t, netutils_exec_t;
    } # end require
    allow dhcpc_t netutils_exec_t:file { getattr read execute };
    .....
    type_transition dhcpc_t netutils_exec_t:process netutils_t;
    ...

} else {
    allow dhcpc_t self:capability setuid;
    .....
} # end optional / else block


Previous
Home
Next