Security Enhanced Linux

Security Enhanced Linux

Oliver Kunz
by Oliver Kunz
time to read: 12 minutes

This week’s topic is Security Enhanced Linux (SELinux). First, I will outline some general aspects of SELinux, followed by the use of SELinux in Android OS. The topic is huge, and true SELinux is one of the most complicated technologies available. The latter may be one of the reasons why it is often disabled and ignored.

Various Linux distributions have detailed tutorials and how-to articles on SELinux. The following articles are the foundation of this article:The collection of articles for Gentoo Linux and the Guide for RHEL6.


Apart from the complex concept, the origin of SELinux may be a further reason for critics not to have a closer look at it. Considering the events that unraveled after May 2013 and the NSA leaks, some people wont like to hear that the kernel module written to enhance security on their systems originated in a National Security Agency (NSA) research project. Together with the Secure Computing Corporation (SCC), the NSA conducted research into the usage of a type enforcement based access control.

Additionally step, in co-operation with the University of Utah, the system architecture Flask was developed. Flask was then ported to Linux, Solaris, and some BSD projects and the distribution of the concept went on.

SELinux’ NSA-related origins are a reoccurring argument for the critics. Up to date, no backdoor in the SELinux code is known. The source code is publicly available, and has been part of the Linux kernel from 2003 onward. Since then, it has been analysed by many a researchers. The fear of a backdoor in SELinux is older than the PRISM leakage and the person able to find evidence of a backdoor or other unwanted behaviour, would make headlines.

What is SELinux

SELinux is a kernel implementation of a Mandatory Access Control (MAC) mechanism. Both, Unix and Linux were developed in a time, as security didn’t have the status and importance it has today. Different security concepts were developed and one of the most used is the Discretionary Access Control (DAC). In DAC, access control to an object (e.g. a file) is granted on the identity of a subject (this could be a user or process). In Linux, the implementation of DAC is known as the permission mask (e.g. rwxrw-r--). In the DAC concept, an object typically has an owner assigned.

In a MAC based access control, more factors than the identity of a subject are considered prior to granting access. In contrast to DAC rules, the owner is not allowed to manage those by himself, resulting in loss of flexibility, but improving protection against accidentally granting access. Having SELinux in place as MAC does not remove the classic DAC mechanics. On the contrary, the DAC builds the foundation of the first round of access control: If access is denied during that first round, SELinux is not consulted. If a subject is granted access to the requested object, the next access checking round consults the SELinux policies.

SELinux modes

SELinux has three different modes. Depending on the distribution, the configuration may differ. Red Hat for example (and related distributions like Fedora and CentOS as well) run SELinux in enforcing mode after the installation.

The current mode of SELinux could be displayed by the command sestatus on a Linux system or read in the file /etc/selinux/config.

Generally, the permissive mode is recommended during the set-up of a system and debugging. The functionality of the system is not affected and potential problems due to access restrictions based on SELinux are written to a log file. By consulting the logs, a system administrator is able to customise and refine the ruleset. As a result, no desired access requests should be logged, or blocked. There are no obstacles left for the productive use of SELinux in enforcing mode.

SELinux Context

The access decision is based on policy rules. Those rules are in turn applied to a SELinux context of a file or process. This context has the format SELinux_User:SELinux_Role:SELinux_Type:SELinux_Level. Below an example:

[root@localhost ~]# ls -Z
-rwxr--r--. root root unconfined_u:object_r:admin_home_t:s0
SELinux_User unconfined_u
SELinux_Role object_r
SELinux_Type admin_home_t
SELinux_Level s0


Each user on a system has an SELinux_User assigned. The SELinux_User is not necessarily uniquely assigned to a system user account, as seen in the example below, default entries may exist. The command semanage login -l lists the current default mapping.

[root@localhost ~]# semanage login -l
Login Name                SELinux User              MLS/MCS Range

default unconfined_u s0-s0:c0.c1023 root unconfined_u s0-s0:c0.c1023 system_u system_u s0-s0:c0.c1023


The relationship between the system user and a SELinux_Role is defined via the SELinux_User. It is an n:n mapping. The command semanage user -l displays the relation between SELinux_User and roles.

[root@localhost ~]# semanage user -l

Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Roles

git_shell_u user s0 s0 git_shell_r guest_u user s0 s0 guest_r root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r sysadm_u user s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r unconfined_r unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r xguest_u user s0 s0 xguest_r

With SELinux_Roles a system administrator is able to refine, to what domains – and thus to what object types (SELinux_Type) a subject has access to. Seen in the console output above, the default SELinux_User (unconfined_u) has access to two SELinux_Roles (system_r/unconfined_r). This is an important detail and often the reason for confusion. Assume that, a user is able to execute a program based on DAC, but the program is not executed. The reason for this might be that the SELinux_Role is prevented from accessing that SELinux_Type. To list the SELinux_Types to a specific SELinux_Role, run the command seinfo.

[root@localhost ~]# seinfo -runconfined_r -x
      Dominated Roles:

SELinux Type

SELinux groups different types in so called classes. Probably the most important classes are file_type and domain. Note, not every SELinux_Type can be used for every object, as Dan Walsh explains in his blog. If a type is applied to a process, we speak about a domain. The process is limited to a sandbox. If a type is applied to a file, it defines the access rights for a SELinux_User.

SELinux Level

The attribute SELinux_Level (sometimes also called range) is optional. It consists of two values, sensitivity and category-set:

Android and SELinux

The Android OS is based on a Linux kernel. SELinux has been integrated to the Linux kernel many years ago. Some Linux distributions have it activated by default, others require manual activation. Since Android 4.3 – Jelly-Bean SELinux has been part of the Android OS as Mandatory Access Control (MAC). The dedicated project SEforAndroid deals with porting SELinux to Android.

Jelly-Bean introduced SELinux, however it only runs in permissive mode, logging the policy violations, but not restricting access. The goal was to gain experience and activate the enforcement mode (logging and blocking) in a later release.

A closer look at the new features of Android 4.4 – KitKat revealed, that that has happened. For the first time, SELinux was rolled out in enforce mode. However it is only enforcing the policy on some single domains. To be more specific: it is enforced on the root domain and the root-level processes (initd, installd and vold). Each application has its own domain and the identification is based on the App signature key. The domains of regular applications are currently running in permissive mode. Developers are now able to have SELinux in focus and analyse the blocked access requests, during normal operations of the application. The only known major issue thus far is that if an application is interacting with one of the domains running enforcing mode, the application might crash if SELinux registers a policy violation.

Prior to the use of SELinux, Android had an application sandboxing. This approach is now taken one step further. The earlier application-sandbox was based on the automatic distribution of dedicated UID for a single process. No two processes shared the same UID. This means that no two processes existed that ran under the same user.


SELinux offers the possibility to implement access control on kernel level. This article gave only a basic overview of some of the aspects. A complete implementation of SELinux requires a lot of effort. is Android, using a Linux-Kernel, is already running SELinux (or rather SEforAndroid) for some functions in enforcing mode. Google urges application developers to utilize the functionality of SEforAndroid for newer versions of their applications. SEforAndroid is another element in the Android architecture to establish a solid sandboxing.

About the Author

Oliver Kunz

Oliver Kunz has been in information security since 2010. Mainly, he deals with incident response, forensics and the security of mobile devices.


You want to bring your logging and monitoring to the next level?

Our experts will get in contact with you!

Password Leak Analysis

Password Leak Analysis

Marc Ruef



Michael Schneider

Online Tracking

Online Tracking

Ralph Meier

Deepfake Audio Text to Speech

Deepfake Audio Text to Speech

Andrea Hauser

You want more?

Further articles available here

You need support in such a project?

Our experts will get in contact with you!

You want more?

Further articles available here