A Brief Introduction to Multi-Category Security (MCS)

If you update to the current Fedora rawhide now, you’ll be able to start using a new security mechanism called Multi-Category Security (MCS).

MCS is something we’ve been working on to help make SELinux more user-oriented, as well as adapt some of the Multi-Level Security (MLS) infrastructure for more general use. An important aspect of SELinux is that it implements Mandatory Access Control (MAC), where security policy is managed by a system or security administrator and is not overridable by users or applications. MAC is important for dealing with security threats arising from software flaws, malware, user error and some classes of malicious users.

Unfortunately, a fine-grained, flexible MAC system is also likely to be complicated, reflecting the complexity of the underlying operating system. Currently, the idea is that a vendor (such as Fedora) ships the SELinux security policy, which may then be modified in a controlled and limited way by a system administrator via ‘booleans’. These are a set of high level abstractions which may be enabled or disabled as required, such as ‘httpd_enable_cgi’.

The vendor and the sysadmin thus have some say in the way security is imposed on this MAC system, but users have no real say over things. Which is generally what we want with MAC security, although as a technology, it doesn’t really empower or engage users. How can a MAC system allow users to have more direct control over security? The answer is pretty simple: provide a mechanism which allows users to further restrict the security of their own resources. This is what MCS does.

In a nutshell, MCS is an enhancement to SELinux which allows users to label files with categories. These categories are used to further constrain DAC and TE logic. They may also be used when displaying or printing files. An example of a category is “Company_Confidential”. Only users with access to this category can access files labeled with the category — assuming the existing DAC and TE rules also permit access.

The term categories here refers to the same non-hierarchical categories as used by MLS. I recently provided an overview of MLS and related concepts including categories here — it may be useful as a reference in understanding MCS. To briefly recap, under MLS, objects and subjects are labeled with Security Levels. These Security Levels consist of an hierarchical sensitivity value (such as “Top Secret”) and zero or more non-hierarchical categories (such as “Crypto”). Categories provide compartments within sensitivity levels and enforce the need to know security principle.

MCS is in fact an adaptation of MLS. It re-uses much of the MLS framework in SELinux, including the MLS label field, MLS kernel code, MLS policy constructs, labeled printing and label encoding/translation. From a technical point of view, MCS is a policy change, along with a few userland hacks to hide some of the unwanted MLS stuff. There are a couple of kernel changes, but only relating to making it easy to upgrade to MCS (or MLS) without invoking a full filesystem relabel.

Another important justification for MCS is that it will provide a way to more widely deploy, test and even shape the concurrent MLS development effort. Legacy MLS systems have often been an old, heavily modified fork of the main OS product. These ‘trusted’ systems tend to fall behind their general purpose counterparts by at least a release or two, and could be described as a series of evolutionary dead ends accompanied by expensive certificates. The userbase for these systems is likely to be very small and narrow, and the QA burden must be enormous (read: expensive, and passed on to the user). With MCS, we ‘re trying to avoid these problems to a large extent by including MLS technology in the current version of the OS and enabling a generally useful subset of it by default. We want this technology to be mainstream, as far as possible.

The hope is to improve the quality of the system as a whole, reduce costs, leverage the open source process, increase transparency, and make the technology base useful to more than a handful of extremely special case users.

There are a few major differences between MCS and MLS:

1) MCS ignores sensitivity levels. Everything is labeled with the same sensitivity, ‘s0’, which makes the idea of sensitivity levels effectively disappear. Hierarchical security designations generally do not map well outside of Military and similar environments, which are rigidly defined and controlled.

2) MCS discards the Bell La-Padula (BLP) security model. BLP properties such as No-Write-Down, which is designed to prevent leakage from high security levels to low security levels, are often confusing and break many assumptions of existing software . Consider root not being able to write to /tmp, as one of many possible problems relating to shared data.

3) MCS is discretionary, similar to standard Unix DAC logic. The current implementation provide users with MCS control over their own files. This should map more readily to more general cases, reflecting the typical discretionary nature of real-world security outside of the Mil/Gov etc. environment. It is possible to adjust MCS to make it less discretionary, but really, that’s what MLS is for.

4) MCS always runs at a single level. The current level of all subjects running on the system is ‘s0’. When a subject is granted access to categories (remember: a security level is a combination of sensitivity and categories), this is done by adding categories to the high range clearance of the subject. The high range clearance refers to the maximum security level that the subject can run at. Under MCS, the subject will never run at anything other than ‘s0’, so the high range clearance is merely used to determine which categories the subject has access to when performing an access control decision. This is similar to Unix supplementary groups: a process can have access to several supplementary groups but not be running in any of them. Similarly, under MCS, a process can have access to a set of categories, but not be running at a security level which includes them. Having everything running at the same level vastly simplifies things.

MCS uses MLS technology, but is not MLS. This should be made very clear: MCS does not provide any inherent protection against flawed or malicious software, user error or malicious users. However, keep in mind that it sits on top of standard Type Enforcement (TE), which is a MAC scheme. Both traditional DAC and TE rules are consulted before MCS rules.

So, a user might create a file and label it with the category “Company_Confidential”. Only processes with access to that category will then be able to access the file. Apache, for example, would not be able to read the labeled file, unless it was itself cleared to access the “Company_Confidential” category.

The names of the categories are set by the sysadmin, who also determines which users have access to which categories. Internally, SELinux sees all categories in the form Cn (C0…C127). A translation file, /etc/mcs.conf, may be edited by the sysadmin to assign locally meaningful values to categories. The intent here is to allow maximum flexibility when deploying systems.

Categories could be names of departments, such as “Finance” and “Payroll”; they might refer to the nature of the information and be linked to business rules for information handling, such as “Patient_Data” or “Credit_Card_Details”; they could also indicate that the information is associated with specific NDAs like “NDA-GOV-12338310A”. It’s really up to users how they make use of MCS and integrate it with their business rules.

You may realize by now that MCS seems like ACLs. MCS is similar, but not equivalent to ACLs. For detailed discussion on the subject, refer to this thread on the SELinux mailing list.

Beyond access control, one planned use of MCS is to re-use MLS labeled printing, so that the MCS categories can be displayed at the top and bottom of each page being printed, and/or on a cover sheet which may also indicate handling procedures for the document. It should also be possible to integrate MCS with future developments in SELinux, such as Security Enhanced X. If integrated with a directory server, it may be possible to add MCS support to email, so that outgoing emails can be labeled by the sender and also through the act of attaching labeled files. The mailer can then determine whether the recipients are known to be cleared to access the categories assocated with the emails.

Currently, MCS is in an early but useable and seemingly stable stage of development. As mentioned, upgrading to the latest Fedora rawhide will install the updated policy and userland components. If you want to activate MCS, you will need to reboot your system (sorry). This is absolutely required as SELinux has to be restarted with MLS subsystem active, which can only be done securely during early kernel initialization. You should not need to relabel your filesystem, even though the label format on disk has changed. Pre-MCS files contexts will be interpreted automatically by the kernel as MCS contexts. Newly created files under MCS will, however, be labeled with the extra ‘MLS’ field:

$ touch foo
$ ls -Z
-rw-r--r--  fred     fred     user_u:object_r:tmp_t:s0           foo

Note the ‘s0’ on the end. This is the dummy sensitivity level with which everything is labeled under MCS. Normally, this component will be hidden, as it is not useful under MCS. In this case, the field was un-hidden by editing /etc/mcs.conf and adding a line:


Setting that to zero again will enable the label translation library.

$ ls -Z
rw-r--r--  fred     fred     user_u:object_r:tmp_t               foo

With the dummy sensitivity level hidden, the system, by default will act as if nothing has changed. Only when categories are added to files should behavior change.

Currently, it is always still possible to see the ‘real’ label on the file with getfattr(1), which calls getxattr(2) directly without using the label translation library.

$ getfattr -n security.selinux foo
# file: foo

This is expected to change in the 2.6.15 kernel (and already has in the latest -mm kernels), so that getxattr(2) always returns the kernel’s canonicalized version of the label. This is to simplify the userland code, which is currently jumping through some flaming hoops to manage different label formats.

Adding a category to a file is currently performed via chcon(1):

$ chcon -l Moonbase_Plans foo

$ ls -Z foo
-rw-r--r--  fred     fred     user_u:object_r:tmp_t:Moonbase_Plans foo

Note that the category label is in the MLS field of the security context. The value of the label was configured in /etc/mcs.conf for this example.


Which means: c10 is to be translated to “Moonbase_Plans”, where c10 is one of the generic categories used internally by SELinux. Now, domains without access to this category will not be able to access the file.

Note that you can view the internal category value (c10) as part of the raw MLS field using gefattr(1) or disabling label translation (as mentioned above).

$ getfattr -n security.selinux foo
# file: foo

In this initial release, by default, all SELinux users are provided with access to all categories (c0 through c127). This can of course be locally customized by the sysadmin, but the primary intention at this stage is to enable the technology and get people using it.

Work is being done on a flexible user management scheme, where individual users at the Unix level are assigned a set of categories during login. This is to prevent the need for manipulating SELinux user policy and policy reloads.

Join the NSA SELinux mailing list if you’re interested in discussing and/or using MCS as we develop it further.

A special thanks to Dan Walsh who did a lot of heavy lifting getting some of the tricky userland MCS stuff working. It’s quite a feat to enable a new security model in a mainstream general purpose operating system without causing a great deal of disruption.