Skip to content

SELinux Security Policy: Part 3 – Labels in action!

December 13, 2016

SELinux is all about labels. Do you remember from the previous blog post?

We know that SELinux decisions are based on labels and made by the kernel according to the loaded policy. Access is granted (action is permitted) if and only if there is a rule allowing it. You can see it in picture 2 featured in the first part of this blog series. We also know how these labels look and where they are stored from the second part of these blogs.

Now lets put the pieces together and demonstrate real SELinux decisions between real system entities – between the system and service manager

$ ps -eZ | grep systemd
system_u:system_r:init_t:s0         1 ?        00:00:02 systemd

which is trying to read a picture file in your home directory.

$ ls -Z /home/mgrepl/Pictures/picture 
unconfined_u:object_r:user_home_t:s0 /home/mgrepl/Pictures/picture

We use Fedora Targeted policy so we already know that we care only about types (the 3rd part of above mentioned labels). Together with the class (file) and  with the permission (read) we get the following tuple.

(init_t, user_home_t, file, read)

which is used for the decision made by the kernel, whether the policy permits a process with source type to access object of given class and target type with the requested action.

We can demonstrate this kernel decision using the security_compute_av() function with SELinux python module.

$ python
Python 2.7.12 (default, Oct 12 2016, 14:31:21) 
[GCC 6.2.1 20160916 (Red Hat 6.2.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import selinux 
>>> avd=selinux.av_decision()
>>> slabel="system_u:system_r:init_t:s0"
>>> tlabel="unconfined_u:object_r:user_home_t:s0"
>>> selinux_class=selinux.string_to_security_class("file")
>>> selinux_permission=selinux.string_to_av_perm(selinux_class,"read")
>>> 
>>> selinux.security_compute_av(slabel,tlabel,selinux_class,selinux_permission,avd)
0
>>> 
>>> if (selinux_permission&avd.allowed == selinux_permission): print("The access is granted.")
... else: print("The access is not granted.")
... 

The access is not granted.

As we can see the access is not granted by the kernel because there is no rule for our (init_t, user_home_t, file, read) tuple. If you want to test a different tuple then you can simply replace bold values in the code above. As I said, there was no rule for tested tuple.

Do we have a way to check if a rule exists?

Yes, we do. We can use the sesearch tool to query existing SELinux rules in the SELinux security policy . For our example, the query has the following form

$ sesearch -A -s init_t -t user_home_t -c file -p read

and will return an empty output because there is no rule as we already know.

What will happen if  the type of the /home/mgrepl/Pictures/picture file will be different and readable by the init_t process type?

We can demonstrate the kernel decision again using the security_compute_av() function.

$ python
Python 2.7.12 (default, Oct 12 2016, 14:31:21) 
[GCC 6.2.1 20160916 (Red Hat 6.2.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import selinux 
>>> avd=selinux.av_decision()
>>> slabel="system_u:system_r:init_t:s0"
>>> tlabel="unconfined_u:object_r:systemd_home_t:s0"
>>> selinux_class=selinux.string_to_security_class("file")
>>> selinux_permission=selinux.string_to_av_perm(selinux_class,"read")
>>> 
>>> selinux.security_compute_av(slabel,tlabel,selinux_class,selinux_permission,avd)
0
>>> 
>>> if (selinux_permission&avd.allowed == selinux_permission): print("The access is granted.")
... else: print("The access is not granted.")
... 
The access is granted.

We can again query the rule using setools as previously.

$ sesearch -A -s init_t -t systemd_home_t -c file -p read
Found 1 semantic av rules:
   allow init_t systemd_home_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;

So as we can see SELinux is really all about labels. You can define hundreds, thousands types, assign them to system entities and write rules between them as you wish. SELinux gives you fine-grained control over your system.

If systemd is exploited and an attacker now has permissions of the main systemd process, which is running with root permissions, he could access any files on your system.

With SELinux he could access only files with specific labels for which we define SELinux policy rules. He could access files with the systemd_home_t type but he would not able to access user’s  home files with the user_home_t type.

Is your system protected by SELinux? Do you know how to check it? Do you know how to get more details about decisions performed by SELinux?

I will give you answers on these questions in the next part of this blog series 😉

Thank you.

From → Uncategorized

Leave a Comment

Leave a comment