danwalsh (danwalsh) wrote,

Understanding SELinux Process Transitions

When one process attempts to execute another application in an SELinux environment one of three things can happen.
  1. SELinux will deny the processes permission to execute the application. This will generate an execute AVC message. An apache CGI script executing "/sbin/insmod"  would get denied generating this AVC.
  2. SELinux will allow the application to be started and stay in the same context as the parent processes.  This is what happens in the vast majority of context.  Almost all executables run by a user running as unconfined_t will run as unconfined_t.  Similarly most applications run by an Apache cgi script will stay httpd_sys_script_t.
  3. SELinux will all the application to be started but will transition the child process to a new domain.  This is what happens when init runs /etc/init.d scripts for example.
Lets look further into these

Bullet 1 is easily understood,  Your domain is not allowed to execute this program.
Bullet 2 however, seems like it could be a security whole?

Lots of confined domains are allowed to execute bin_t files, and most executables on the system are labeled bin_t!

Isn't it a problem that an Apache cgi script can execute a file labeled bin_t, setenforce 0 for example?

Well no!  Just  because a confined process can execute an binary does not mean that it can do everything that binary is designed to do.  You are still governed in SELinux by the rules on your domain.  So if a httpd cgi script ran setenforce 0, it would get denied the ability to "setenforce" on the system and would fail.
Bullet 3 is the hardest to understand, and I often have to answer this question, when people are testing SELinux.

How come when I run the daemon directly it works but when it runs from init SELinux complains?

Most confined daemon domains use the interface init_daemon_domain which defines a transition from the initscript domain (initrc_t) to the confined domain ABC_t when running an executable labeled ABC_exec_t.

For example

init_daemon_domain(httpd_t, httpd_exec_t)

Defines a transition rule that says

Init Scripts executing apps labeled httpd_exec_t should transition to httpd_t.

initrc_t -> httpd_exec_t -> httpd_t

When the system boots, Apache runs as httpd_t as it should. 

The confusion comes when a logged in user runs the Apache daemon directly.  

Most users login to the system as unconfined_t.  unconfined_t processes have very few transitions defined, because a user expects SELinux allow all access for his unconfined processes.  If his unconfined process transitions to a confined domain and something does not work, SELinux has ruined this expectation.

When the unconfined_t process runs an application labeled httpd_exec_t there is no transition defined, so the httpd_exec_t applications runs as unconfined_t.

One transition that is defined for the unconfined user is over the init scripts (/etc/init.d).

unconfined_t -> initrc_exec_t -> initrc_t

Which says, when an unconfined_t process executes a file labeled initrc_exec_t the process will be transitioned to the domain  initrc_t.  If an unconfined user executes service httpd restart the /etc/init.d/httpd script will run as initrc_t.

(Note: initrc_t is an also an unconfined domain in targeted policy)

All scripts in /etc/init.d/ are defined with an initscript context (initrc_exec_t) which SELinux allows to transition.

An unconfined user (unconfined_t) executing system httpd restart would execute the init script as initrc_t and the initrc_t script would finally start the execuable labeled httpd_exec_t running in the correct domain httpd_t.

unconfined_t -> initrc_exec_t -> initrc_t -> httpd_exec_t -> httpd_t

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened