Info: Version 1.8.x is available.

Japanese Page

Last modified: $Date: 2015-08-31 22:19:51 +0900 (Mon, 31 Aug 2015) $

The world of TOMOYO Linux
The third installment: "Let's master domain transitions."

Contents of this installment.

In the second installment, I explained access control modes and profiles in TOMOYO Linux and steps for restricting access using access control modes and profiles. You might felt that too quick to catch up on, but to your surprise, all basic usage of TOMOYO Linux is covered by now. From now on, I explain detailed and applicable usage of TOMOYO Linux with expanded information. Please stay with me. In this installment, I explain TOMOYO Linux's domain transitions.

Mastering domain transitions

General rule on TOMOYO Linux's domain transitions

As I explained in the first installment, TOMOYO Linux performs domain transition whenever a program is executed as a rule. (Fig. 1)

♦ Fig. 1  Domain transitions in TOMOYO Linux
(Transits to new domain by program execution)
fig-3-1.png

Thereby, each program has mutually independent domains. The name of domain is a string representation of concatenation of all program's pathnames ever executed by now starting from <kernel>. On the contrary, domains in SELinux do not have hierarchical structure and distributed in a flat manner. The relationship between programs and domains are defined by policy developer, but usually several programs corresponds to one domain. SELinux performs domain transition only if predefined programs are executed from specific domains. (Fig. 2. As a result, access control rules changes.)

♦ Fig. 2  Domain transitions in SELinux
fig-3-2.png

Exceptions for TOMOYO Linux's domain transition rules

You can reinitialize or suppress TOMOYO Linux's domain transition as you need.

♦Unconditionally reinitialize domain transition

When "program" specified by "initialize_domain program" is executed, the process unconditionally transits to the child domain of "<kernel>" domain. (Fig. 3)

♦ Fig. 3  Effect of initialize_domain keyword
(Unconditionally transits to "<kernel> /some/where/baz" domain when /some/where/baz is executed.)
fig-3-3.png

♦Conditionally reinitialize domain transition

As I noted above, if a "program" specified as "initialize_domain program" is executed, the process transits to "<kernel> program" domain. (Fig. 4)

♦ Fig. 4  Unconditionally reinitialize domain transition
fig-3-4.png

But if a "program" specified with a "domainname" as "initialize_domain program from domainname" is executed, the process transits to "<kernel> program" domain only when "program" is executed from "domainname" domain. (Fig. 5)

♦ Fig. 5  Reinitialize domain transition only when executed from specific domain
( The process transits to "<kernel> /usr/sbin/sshd" domain only when /usr/sbin/sshd is executed from "<kernel> /etc/rc.d/init.d/sshd" domain because of "initialize_domain /usr/sbin/sshd from <kernel> /etc/rc.d/init.d/sshd".)
fig-3-5.png

You may specify only the last part of domainname (e.g. /bin/bash ) instead of a complete domainname (e.g. "<kernel> /usr/sbin/sshd /bin/bash").

♦Conditionally not reinitialize domain transition

If a "program" specified with a "domainname" as "no_initialize_domain program from domainname" is executed, the process ignores "initialize_domain" keyword when "program" is executed from "domainname" domain.

For example, /bin/mail (which is used for sending mails) executes /usr/sbin/sendmail.sendmail for sending mails. But if you want to give different permissions to "/usr/sbin/sendmail.sendmail for sending mails" and "/usr/sbin/sendmail.sendmail for receiving mails", you can specify "no_initialize_domain /usr/sbin/sendmail.sendmail from /bin/mail" so that /usr/sbin/sendmail.sendmail executed by /bin/mail won't transit to "<kernel> /usr/sbin/sendmail.sendmail" domain. (Fig. 6) (Note that this works for only domains which domainname ends with /bin/mail . If /bin/mail is executed from a shell domain specified with "keep_domain" keyword, you need to specify domain of the shell rather than /bin/mail .)

♦ Fig. 6  Combination with no_initialize_domain keyword
fig-3-6.png

♦Unconditionally suppress domain transition

Any processes which belong to "domainname" specified by "keep_domain domainname" remains in the same domain unless programs specified by "initialize_domain" keyword is executed. (Fig. 7) This resembles SELinux's domain because multiple programs belong to the same domain.

♦ Fig. 7  Effect of keep_domain keyword
(Since "<kernel> /sbin/init ⋅⋅⋅ foo bar" domain is specified using "keep_domain" keyword, domain transition does not occur when programs are executed. Domain transition to "<kernel> /some/where/baz" occurs when /some/where/baz (which is specified using "initialize_domain" keyword) is executed.)
fig-3-7.png

You may specify only the last part of domainname (e.g. /bin/bash ) instead of a complete domainname (e.g. "<kernel> /usr/sbin/sshd /bin/bash"). For example, if you specify /bin/bash as a "domainname", "keep_domain" is applied to all domains which domainname ends with /bin/bash . (Fig. 8)

♦ Fig. 8  Effect of keep_domain keyword
fig-3-8.png

♦Conditionally suppress domain transition

As I noted above, if a "domainname" is specified as "keep_domain domainname" , the process once reached to "domainname" remains in the same domain unless programs specified by "initialize_domain" keyword is executed. (Fig. 9)

♦ Fig. 9  Unconditionally suppress domain transition
fig-3-9.png

But if a "domainname" is specified with a "program" as "keep_domain program from domainname", the process remains in the same domain only when "program" is executed from "domainname" domain. (Fig. 10)

♦ Fig. 10  Suppress domain transition only when specific programs are executed
fig-3-10.png

♦Conditionally resume domain transition

You can suppress domain transition for login session using "keep_domain" keyword because it is unlikely possible to understand what commands in what order users will execute from login session beforehand. But there are cases you want to resume domain transition, such as allowing access to password files for changing passwords and restarting applications that run as daemon processes.

By specifying "no_keep_domain program from domainname", "keep_domain" keyword is ignored when "program" is executed from "domainname" domain.

For example, by specifying "no_keep_domain /bin/cat from <kernel> /usr/sbin/sshd /bin/bash" when "keep_domain <kernel> /usr/sbin/sshd /bin/bash" is specified, the process transits to "<kernel> /usr/sbin/sshd /bin/bash /bin/cat" domain when /bin/cat is executed from "<kernel> /usr/sbin/sshd /bin/bash" domain while the process remains in the same domain when other programs are executed from "<kernel> /usr/sbin/sshd /bin/bash" domain. (Fig. 11)

♦ Fig. 11  Combination with no_keep_domain keyword
fig-3-11.png

♦Do domain transition without program execution

As a rule, domain transition is performed when a program is executed. But by calling procedure for domain transition from programs, you can perform domain transition without executing a program.

For example, Apache supports CGI programs. Some CGI programs are processed outside Apache (i.e. need program execution) and others are processed inside Apache (i.e. don't need program execution). By performing domain transition based on virtual host's name and requested CGI's pathnames before Apache processes the request, you can give different permissions for CGI programs which are processed inside Apache. Steps for doing this are explained in the tenth installment.

Grouping a series of operations

You can flexibly specify access control using "initialize_domain" keyword and "keep_domain" keyword. I explain how to use them using an example. Login as root user and run ccs-editpolicy command. Then, find the domain for /etc/rc.d/init.d/network (i.e. "<kernel> /etc/rc.d/init.d/network" domain). You will see that many programs such as /etc/sysconfig/network-scripts/ifup and /bin/touch are executed from /etc/rc.d/init.d/network . (Fig. 12)

♦ Fig. 12  Domain transition before specifying keep_domain keyword
fig-3-12.png

Press "Tab" key. You will see that the screen titled "<<< Domain Transition Editor >>>" changed to the screen titled "<<< Exception Policy Editor >>>". You can find lines starting with "initialize_domain" keyword by scrolling the screen. Scroll down to the bottom, and press "A" key and enter "keep_domain <kernel> /etc/rc.d/init.d/network" and press "Enter" key. Then, you will see what you entered. (Fig. 13)

♦ Fig. 13  Specify keep_domain keyword
fig-3-13.png

Press "Tab" key again. You will see that the screen titled "<<< Exception Policy Editor >>>" changed to the screen titled "<<< Domain Transition Editor >>>". Find "<kernel> /etc/rc.d/init.d/network" domain by scrolling the screen. (Fig. 14)

♦ Fig. 14  Domain transition after specifying keep_domain keyword
fig-3-14.png

The mark changed from "*" to "#*". The "#" mark indicates that "multiple programs may belong to this domain because this domain is specified by keep_domain keyword". The "*" mark indicates that "multiple domains may transit to this domain because this domain is specified by initialize_domain keyword". Now, since you specified /etc/rc.d/init.d/network domain using "keep_domain" keyword, you need to re-learn policy for this domain. Lines with the "!" mark (from 86 to 189 in Fig. 14) indicates that these domains became unreachable due to "keep_domain <kernel> /etc/rc.d/init.d/network", thus delete these lines. Move the cursor and press "Space" key, and you will see that "&" mark appeared. Then, press "D" key and a prompt like Fig. 15 will appear, thus press "Y" key.

♦ Fig. 15  Confirmation message for deleting domains
fig-3-15.png

Then, domains marked with "&" are deleted. Press "Q" key to quit ccs-editpolicy command. Execute "/etc/rc.d/init.d/network restart" to re-learn. Execute ccs-editpolicy command again and find "<kernel> /etc/rc.d/init.d/network" domain. This time, you won't see programs like /etc/sysconfig/network-scripts/ifup and /bin/touch . (Fig. 16)

♦ Fig. 16  Domain transition after re-learning
fig-3-16.png

TOMOYO Linux's automatic domain dividing feature is powerful. But if you want to restrict execution of programs and access by these programs but you don't know the order of program execution (login session is a typical case), it is difficult to define domains. By grouping domains for login session using keywords explained in this installment and assign profiles for enforcing mode, you can restrict execution of programs and access by these programs while you don't restrict the order of program execution. Also, by not assigning profiles for enforcing mode, you can let login session behave freely like normal Linux.

Trailer

In this installment, I explained TOMOYO Linux's domain transitions. In the next installment, I explain tuning TOMOYO Linux's policy. Don't miss it!

Go back to the second installment.  Proceed to the fourth installment.


Return to index page.

sflogo.php