Linux v4.10 was released this past weekend on Sunday, February 19th; this is a quick summary of the SELinux and audit changes.
Fix a GFS2/SELinux deadlock where one task is initializing an inode while another task is invalidating the SELinux label on the same inode. The fix involved changing the SELinux inode_security_struct lock from a mutex to a spinlock and introducing a new SELinux label state, "PENDING". These two changes allow SELinux to mark a pending inode initialization and detect if the inode's label was invalidated during the initialization process.
Add a build time check to catch the addition of new capabilities and force an update to the associated SELinux code. The simple fix was to compare the CAP_LAST_CAP sentinel value with the last known defined capability and cause a compilation failure, via the "#error" compiler directive, when there is a mismatch.
Normalize input to /sys/fs/selinux/enforce so that the stored value is only ever 1 (true) or 0 (false). This change should have no impact to the kernel, it only checks for non-zero (true) or 0 (false), but some userspace tools check for a value of 1 instead of a non-zero true value.
Fix a problem where clearing /proc/self/attr/fscreate could result in an unwanted kernel memory access (CVE-2017-2618).
A number of minor improvements and cleanups to the SELinux inode handling.
Major rework of the audit backlog queue which moves the audit multicast writes from the thread of the task which generates the event to a separate kernel thread, much like we do for the audit unicast/auditd messages. Moving the multicast writes had a ripple effect on the entire audit queuing mechanism which brought about a number of improvements which should reduce the per-task audit overhead when audit is enabled, and help make audit more robust under heavy load.
Add kernel support for audit filtering based on the session ID. See the GitHub feature page for more information.
Fix audit's use of fsnotify to prevent sleeping on a spinlock. The fix involved making sure that the proper lock ordering was followed, meaning that we took the fsnotify_group's mutex before taking the fsnotify_mark's spinlock.
Fix a problem where audit was needlessly duplicating fsnotify_mark structures and leaking a reference to the associated fsnotify group.
Fix a problem where the kernel wasn't properly holding a reference for the auditd communication socket which could result in a race condition when resetting the connection with auditd.
Ensure consistent logging of the CONFIG_CHANGE audit record. The record's "op" field is not encoded so the value should not be surrounded with double quotes.
I attended DevConf.cz again this year and once again really enjoyed myself. I didn't present at last year's conference but I made up for it this year by giving two presentations: one presentation on the Core Infrastructure Initiative's Best Practices Badge Program and the other a reprise of Richard Guy Briggs' audit and namespace talk from the 2016 Linux Security Summit. Richard had planned on giving the talk himself at DevConf.cz this year, but unfortunately wasn't able to make the trip so I agreed to give the talk in his place. Slides and videos of the presentations can be found below.
With the release of Linux v4.8 and NetLabel Tools v0.30.0 we now have a working implementation of RFC5570, aka CALIPSO, on Linux. This post will demonstrate how to configure NetLabel/CALIPSO on a SELinux based system through the use of a simple example which should be easy to duplicate on any single system. The example is based on Fedora Rawhide, but the basic commands should apply to other distributions as well.
I'm going to focus on the CALIPSO configuration in this post, and not the NetLabel and SELinux per-packet access control basics. If you need a refresher, please see the posts below:
You can download and build the tool with the following commands; although you may also need to install some additional packages to build the getpeercon_server tool, the libselinux-devel package is one likely example.
Once you have verified the necessary packages, and built getpeercon_server, it is time to start configuring NetLabel/CALIPSO in the kernel. The first step is to define a CALIPSO Domain Of Interpretation (DOI). The CALIPSO DOI provides a context in which the CALIPSO labels can be interpreted by all the nodes in the network, in this example we are using a DOI value of 2, but if you are deploying your Linux system in an existing CALIPSO network, you will need to contact your network/security administrator to determine which CALIPSO DOI is appropriate (NOTE: Linux supports multiple CALIPSO DOIs).
After we have defined the CALIPSO DOI, we need to instruct the kernel to use this DOI to label outgoing traffic. In this example we are going to assign CALIPSO labels to all of our IPv6 localhost traffic (::1). You will note that the commands below assume a default NetLabel mapping configuration.
We do not need to worry about incoming traffic, once the Linux Kernel knows about a CALIPSO DOI it will automatically interpret the CALIPSO labels on any traffic that enters the system.
That completes the configuration steps for this example, the next step is to verify a basic unlabeled IPv4 connection:
We can see that we were able to connect to the getpeercon_server over IPv4 localhost (127.0.0.1) and that our test tool registered it as an unlabeled connection (NO_CONTEXT). Let's try this again, this time using IPv6's localhost address (::1):
Here we see CALIPSO in action as it labeled our IPv6 localhost connection with our effective MLS/MCS label (s0). We can play with this a bit more using the runcon command to connect to the getpeercon_server with different MLS/MCS labels (NOTE: I'm using the SELinux "targeted" policy so I'm restricted to a single sensitivity level in this example (s0), the SELinux "mls" policy supports multiple sensitivity levels).
That's all there is to configuring NetLabel/CALIPSO on Linux. If you have any questions you know how to contact me. Good luck!