SELinux/Tutorials/What is this unconfined thingie and tell me about attributes

What is this unconfined thingie (and tell me about attributes)?
If you've been following along with previous tutorial on an SELinux-based system, you've probably already seen a type called unconfined_t popping up in the output of ps -Z and ls -Z. This type (or domain, when part of a process' security context) is important enough to be subject if this next tutorial. Additionally, we'll use this opportunity to discuss SELinux policy stores.

What is so special about the unconfined domain
So let's get back to an example that shows processes running in the unconfined_t domain.

Nothing specific about this, right? Just a domain like others we have seen... only, the difference is that within SELinux, unconfined domains are allowed to do almost anything they please (hence the name, unconfined).

Applications that are normally confined might also run in the unconfined_t domain if they are launched by a user whose processes are already in the unconfined_t domain: transitions away from unconfined_t are exceptional.

Why using unconfined domains
The idea behind unconfined domains is to support SELinux-enabled systems where the network-facing daemons (the services) are running in confined domains (like auditd_t, sshd_t, etc.) but where the users themselves run in a more unrestricted fashion: all commands they execute are trusted by the system.

When such configurations are used, SELinux is mainly set up to protect against remote attacks (and remotely exploitable vulerabilities). Local attacks (any exploitable vulnerability that requires local access) are thus not mitigated when using SELinux with unconfined domains.

The huge advantage in such setups is that the policy development is much easier, and users have little impact from SELinux to begin with. Systems that do not support unconfined domains require their users to have more knowledge about SELinux before they can truly work on their system.

Not only unconfined_t is unconfined
In most examples, seeing domains run with unconfined_t gives enough triggers for people to understand that this process runs in an unconfined domain. However, there are other domains that can be unconfined as well, depending on whether the system supports unconfined domains or not.

Or, differently put, if your system is configured to support unconfined domains, then some of the domains that you think are confined domains are still unconfined.

Doesn't help understanding it? Okay, let me first then introduce you to type attributes, and we'll get back to it then...

SELinux attributes
In the tutorial on controlling file contexts a note already referred to SELinux type attributes, so it's now time to dive deeper into those.

When dealing with access controls, it is sometimes nice to be able to group multiple contexts so that you can say something like All end user domains should be allowed to read the file. If the access control system doesn't support grouping, then you will need to iterate this for every user domain that exists: allow user_t etc_t:file read; allow staff_t etc_t:file read; allow sysadm_t etc_t:file read; allow unconfined_t etc_t:file read;

What SELinux does, is support SELinux type attributes that can be assigned on several types. If every type above also gets the attribute userdomain, then the policy can just say: allow userdomain etc_t:file read;

This attribute support is being used more and more to make the policies flexible, manageable and understandeable.

In the sesearch output, you will already have noticed that domains or types that do not end in _t are displayed. When this is the case, the shown domain or type is actually a type attribute (the convention is that these attributes do not get a suffix). You can query the type attributes currently in the policy using the seinfo tool. For instance, to get an overview of all types that have the userdomain attribute set:

The syntax here is -a (for attribute) immediately followed (without space in between) by the attribute name.

Vice versa, you can ask seinfo to show all attributes assigned to a particular type or domain. So for the user_t domain:

So, what about this unconfined then?
Back to the strange paragraphs on seemingly confined domains being unconfined...

Policy writers can mark a domain as being an unconfined domain, by assigning a specific attribute (called unconfined_domain_type) to the context. This attribute is available at all times, but when unconfined domains are supported, then this attribute (and thus all domains that have this attribute) will be granted the necessary privileges to become unconfined.

You can query which domains are unconfined through seinfo easily:

So even though the processes are shown running in different domains, because they still have the unconfined_domain_type attribute assigned to them, they still run as an unconfined domain if unconfined domains are supported.

So when are unconfined domains supported
Unconfined domains are supported when the unconfined SELinux module is loaded (we'll get to SELinux modules in a later article). As this module provides the unconfined_t type, all we need to do is check if this type is available or not. If it isn't, then the system does not support unconfined domains. If it is, then unconfined domains are supported.

In the above case, unconfined_t is not available on the system, so no unconfined domains.

In this case, the unconfined_t domain is available, so unconfined domains are supported.

What you need to remember
What you should remember from this tutorial is that
 * unconfined domains run virtually without SELinux protection
 * unconfined domains are meant to have users run with little SELinux interference, whereas the network-facing daemons still run in confined, SELinux-protected domains
 * SELinux has support for type attributes, which can group multiple different types and assign privileges to the entire group of types