akarititle.png

Chapter 15: How do I manage policy namespace?

15.1. About policy namespace

The documentation so far has only shown domains that begin with "<kernel>". A new feature introduced in TOMOYO 1.8.2 introduces the concept of namespaces. Domains that start with "<kernel>" belong to the "<kernel>" namespace, but different namespaces can now be used with domains that start with "<$namespace>", where $namespace can be any arbitrary name.

Each policy namespace has its own set of domain policy, exception policy and profiles, which are all independent of other namespaces. This independency allows you (and those who want to develop and distribute policy for specific applications) to develop policy files without worrying interference among namespaces, except that directives for jumping to different namespaces need to be added to other namespaces.

15.2. How to specify namespaces?

The notation "<$namespace>" will be used hereafter, in which $namespace can be a any word (e.g. "/usr/sbin/sshd", "/usr/bin/httpd", "Apache") in TOMOYO's string representation rule. The "<kernel>" namespace is the built-in namespace. As long as you use only "<kernel>" namespace, policy files remain compatible with TOMOYO 1.8.1.

A domain name starts with "<$namespace>". For example, "<kernel>" domain and "<kernel> /sbin/init" domain belong to "<kernel>" namespace whereas "</usr/sbin/sshd>" domain and "</usr/sbin/sshd> /bin/bash" domain belong to "</usr/sbin/sshd>" namespace.

kernel_namespace.png sshd_namespace.png

Although each namespace has its own set of domain policy, exception policy and profiles, the policy for all namespaces are still contained within the same files within /proc/ccs/ and /etc/ccs/policy/ for simplicity and compatibility reasons. In other words, the policy for each namespace is not split into separate files.

To specify namespace in /proc/ccs/exception_policy and /proc/ccs/profile , add "<$namespace>" prefix to each line. An example of /proc/ccs/profile containing "<kernel>" and "</usr/sbin/httpd>" namespace looks like below:

<kernel> PROFILE_VERSION=20100903
<kernel> 0-COMMENT=-----Disabled Mode-----
<kernel> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
<kernel> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
<kernel> 1-COMMENT=-----Learning Mode-----
<kernel> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
<kernel> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
<kernel> 2-COMMENT=-----Permissive Mode-----
<kernel> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
<kernel> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
<kernel> 3-COMMENT=-----Enforcing Mode-----
<kernel> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
<kernel> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }
</usr/sbin/httpd> PROFILE_VERSION=20100903
</usr/sbin/httpd> 0-COMMENT=-----Disabled Mode-----
</usr/sbin/httpd> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
</usr/sbin/httpd> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
</usr/sbin/httpd> 1-COMMENT=-----Learning Mode-----
</usr/sbin/httpd> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
</usr/sbin/httpd> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
</usr/sbin/httpd> 2-COMMENT=-----Permissive Mode-----
</usr/sbin/httpd> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
</usr/sbin/httpd> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
</usr/sbin/httpd> 3-COMMENT=-----Enforcing Mode-----
</usr/sbin/httpd> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 enforcing_penalty=0 }
</usr/sbin/httpd> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }

For compatibility, "<kernel>" prefix can be omitted when specifying "<kernel>" namespace.

To specify namespace in /proc/ccs/domain_policy , no special care needs to be taken. This is because domain policy consists with blocks where a block starts with a domainname declaration line and the domain name contains namespace which the domain belongs to. An example of /proc/ccs/domain_policy containing "<kernel>" and "</usr/sbin/httpd>" namespace looks like this:

<kernel>
use_profile 0
use_group 0

<kernel> /sbin/init
use_profile 0
use_group 0

</usr/sbin/httpd>
use_profile 1
use_group 0

</usr/sbin/httpd> /var/www/cgi-bin/counter.cgi
use_profile 1
use_group 0

15.3. How to specify domain transition across namespaces?

As explained above, directives for jumping to different namespaces needs to be added to other namespaces. Two more directives are added.

The "reset_domain" directive causes programs to run in the namespace specified by this program. The syntax is same with initialize_domain directive. Below example causes all executions of /usr/sbin/sshd to be transit to "</usr/sbin/sshd>" domain:

reset_domain /usr/sbin/sshd from any

The "no_reset_domain" directive cancels the effect of "reset_domain" directive. The syntax is same with no_initialize_domain directive.

Also, "auto_domain_transition=" part in the conditional ACL allows transition to arbitrary namespaces upon permitted by policy (but use with caution because there is no guarantee that the access request that was permitted by policy never fails after the domain transition).

file pivot_root /usr/lxc/lxc1/ /usr/lxc/lxc1/oldroot/ auto_domain_transition="<lxc1>"
file pivot_root /usr/lxc/lxc2/ /usr/lxc/lxc2/oldroot/ auto_domain_transition="<lxc2>"

While "reset_domain" directive allows only transition to the domain where the name of the namespace is equals to the name of the program, "auto_domain_transition=" part in the conditional ACL allows transition to the domain where the name of the namespace is an arbitrary word. In other words, the former can transit to domains like "</usr/sbin/httpd>" whereas the latter can transit to domains like "</usr/sbin/httpd>" and "<Apache>".

Regarding "task auto_domain_transition" directive and "task manual_domain_transition" directive, there is no change because these directives receive a domainname which already contains the name of the namespace. Thus, you can specify like below:

task manual_domain_transition <Apache> /www.tomoyo00.com
task manual_domain_transition <Apache> /www.tomoyo01.com
task manual_domain_transition <Apache> /www.tomoyo02.com
task manual_domain_transition <Apache> /www.tomoyo03.com

While "reset_domain" directive and "auto_domain_transition=" part in the conditional ACL allow only transition to the domain where the name of the domain is equal to the name of the domain's namespace, "task auto_domain_transition" directive and "task manual_domain_transition" directive allow transition to arbitrary domains. In other words, the former can transit to domains like "</usr/sbin/httpd>" whereas the latter can transit to domains like "</usr/sbin/httpd>" and "</usr/sbin/httpd> /var/www/cgi-bin/counter.cgi".

15.4. How to use namespace from policy editor?

ccs-editpolicy supports new command line option <$namespace> which sets the initial namespace to edit to <$namespace> namespace. The default namespace is "<kernel>". Be careful not to typo the namespace. Entries will not be shown as you expect if you typo, for ccs-editpolicy filters entries based on the namespace currently editing.

Regarding <<< Exception Policy Editor >>> screen and <<< Profile Editor >>> screen, the name of namespace currently editing is shown on the third line of the screen as with the name of domainname currently selected is shown on the third line of the <<< Domain Transition Editor >>> screen. You can jump to <<< Namespace Selector >>> screen by pressing "n" key after pressing "w" key in order to select namespace to edit.

Although it is possible to create a new namespace and create profiles for the new namespace and add entries using ccs-editpolicy, it is recommended to use ccs-loadpolicy for your convenience. For example, to clone profile for "<kernel>" namespace in order to use for "</usr/sbin/httpd>" namespace, you can use an awk script like below:

# awk ' { print "</usr/sbin/httpd> " $0 } ' /etc/ccs/profile.conf | ccs-loadpolicy -p

If /etc/ccs/profile.conf already contains the "<kernel>" prefix, the script will look like below:

# grep '^<kernel> ' /etc/ccs/profile.conf | awk ' { $1 = "</usr/sbin/httpd> "; print $0 } ' | ccs-loadpolicy -p

Note that the purpose of namespace is to allow having independent set of domain policy, exception policy and profile. You don't have to clone from existing files.

15.5. Pitfalls when using namespaces

Namespace is convenient, but there are a few pitfalls that you need to take care.