Still waiting for stackable security modules
The challenge
The early thinking was that an LSM would enforce a security policy on the entire system, and that there would be only one of them. The fact that the only existing LSM for several years was SELinux helped to reinforce that belief, but developers quickly realized that there could be good reasons to run multiple LSMs on a system. A proper stacking scheme would, for example, make it possible to use a variety of small LSMs, each of which is aimed at a piece of the security policy. More recent developments, such as containers, have increased the number of settings where even having multiple full-system modules loaded might make sense.
There has been no shortage of attempts to solve this problem. Some of those that were covered here over the years include:
- Serge Hallyn may have made the first attempt in 2004.
- David Howells in 2011.
- Casey Schaufler in 2012.
- Schaufler again in 2015.
- Yet again in 2019.
Anybody who wants to solve this particular problem is going to have to face a number of challenges. One of those is deciding whether to allow an operation if there are multiple active LSMs and they disagree with each other. The simplest approach there is to give any LSM veto power; all modules that express an opinion on any specific operation must agree to allow it, or it will be denied. The hardest problems may well be elsewhere. Figuring out what the user-space interfaces should look like when multiple LSMs are active is not straightforward; tracking down policy problems can be painful even when there is only one module in the mix.
Another significant problem is giving LSMs the means to attach their own metadata to objects in the system. The original LSM patches handled this by adding pointers to various kernel data structures, but no provision was made for the problem of multiple modules needing to store data. Any solution has to allow LSMs to cooperate in this regard as well while, at the same time, not having a measurable effect on performance.
A viable solution?
Schaufler does not lack for persistence; ten years after starting on this project, he is still trying to get a solution for security-module stacking that addresses these problems into the mainline kernel. Version 38 of his stacking patch set was posted in late September; it does not solve the entire problem, but it does make it possible to stack the AppArmor LSM with any other module. After all those years and versions, it might not be surprising to learn that Schaufler is ready to see this work merged; back in August, he asked whether that could happen during the 6.1 kernel cycle:
I would like very much to get v38 or v39 of the LSM stacking for Apparmor patch set in the LSM next branch for 6.1. The audit changes have polished up nicely and I believe that all comments on the integrity code have been addressed. The interface_lsm mechanism has been beaten to a frothy peak.
This plan was complicated by an independent event, though: longtime LSM maintainer James Morris stepped aside and Paul Moore took over the maintainership of that subsystem. This change arguably had both positive and negative effects with regard to the stacking patches. On the positive side, Moore appears to have more time to engage with the stacking patch set and a stronger desire to see it merged into the mainline. Less positive, at least with regard to a quick merging of the patches, is that Moore felt the need to re-review the patch set from the beginning, which inevitably led to comments and requests for changes.
Specifically, Moore was unhappy with the user-space API, which is an
extension of the existing, /proc-based interface that even
Schaufler described as "hideous
". Moore suggested
that perhaps the time had come to add a set of LSM-specific system calls
instead:
We have avoided this in the past for several reasons, but over the past couple of decades the LSMs have established themselves as a core part of Linux with many (all?) major Linux distributions shipping and supporting at least one LSM; I think we can justify a handful of well designed syscalls, and with Landlock we have some precedence too.
Moore laid out a rough design for the system-call API that he had in mind as well. Schaufler was less than pleased with this idea, though:
I wish you'd suggested this three years ago, when I could have done something with it. If stacking has to go on a two year redesign because of this it is dead. We've spent years polishing the /proc interfaces. Changed the names, the content, even bent over backwards to accommodate the security module that refused to adopt an attr/subdir strategy.
User-space interfaces can be exceedingly difficult to change once they have been included in a kernel release; if significant changes are required, they usually need to happen before the code is merged. So it is not entirely surprising that Moore was insistent, saying that he could not accept the proposed interface; Schaufler eventually threw in the towel and started discussing what he needed to do:
OK, so what interfaces need to be redone? I have been polishing what's just become a turd for a %^&*(ing long time. I need to know whether it is something I can address, or whether I just toss the entire thing in the proverbial bit bucket.
The system-call API
Schaufler eventually came back with a proposal for two new system calls. The first of those is:
struct lsm_ctx { unsigned int id; unsigned int flags; __kernel_size_t ctx_len; unsigned char ctx[]; }; int lsm_self_attr(struct lsm_ctx *context, size_t *size, int flags);
Here, context is a buffer that is *size bytes in length; the flags argument must be zero. This call will return all of the attributes assigned to the calling process by the security module(s) currently in force, in the buffer pointed to by context; this patch describes the format of the returned data. The size parameter will be updated with the actual size of the returned data. The second system call can be used to determine which LSMs are currently active:
int lsm_module_list(unsigned int *ids, size_t *size, unsigned int flags);
This call will fill the ids array with the ID numbers assigned to each of the active modules. These ID numbers are defined in a new header file that is intended to be a part of the user-space API; Schaufler's Smack module, for example, is defined as:
#define LSM_ID_SMACK 34
Much of this design follow Moore's initial suggestions. It appears to be
mostly uncontroversial — with one significant exception.
Tetsuo Handa, a developer of the Tomoyo LSM, has vociferously and
repeatedly objected
to the use of integer module IDs assigned within the kernel code itself.
This practice will, he has argued, make it impossible to use run-time
loadable LSMs that are not currently part of the kernel source. As a
result, it will be hard for developers of LSMs to test them or (especially)
get others to work with them. That, in
turn, spells
a "death sentence
" for any new LSMs in the future, he said.
As others have pointed out, there are a few problems with this argument, starting with the fact that the kernel-development community has never gone out of its way to make life easier for out-of-tree code. Another is that LSMs, whether in-tree or not, cannot be loaded at run time now. That capability was removed many years ago and seems unlikely to return; among other things, it is too easy for LSMs to bypass the restrictions normally applied to kernel modules. For this reason, Handa's request to simply export the security_hook_heads variable to kernel modules is unlikely to be viewed favorably. Schaufler has also said repeatedly that any new mechanism for loadable LSMs would have to be treat those modules quite differently than built-in LSMs, since loadable LSMs would have to be more severely restricted. That is another big job that he personally has no intention of taking on.
For all of these reasons, Handa's objections seem unlikely to prevail in
the end. But this work, which has had such a turbulent history for so
long, may still not be merged immediately. New system calls require
extensive review, and that process has just begun; it wouldn't be
surprising if more changes were called for. Even so, the end of the
process for limited LSM stacking may be getting closer. Then all that is
left is "universal stacking", a prospect that, according
to Schaufler, is "at least a year off
". There is visible
progress, but this lengthy discussion is not yet finished.
Index entries for this article | |
---|---|
Kernel | Security/Security modules |
Security | Linux Security Modules (LSM) |
Posted Oct 31, 2022 20:39 UTC (Mon)
by jhoblitt (subscriber, #77733)
[Link]
Posted Oct 31, 2022 23:54 UTC (Mon)
by nickodell (subscriber, #125165)
[Link] (1 responses)
Posted Nov 10, 2022 18:23 UTC (Thu)
by flussence (guest, #85566)
[Link]
Posted Nov 1, 2022 18:41 UTC (Tue)
by jamesmorris (subscriber, #82698)
[Link] (7 responses)
- What are the use-cases for arbitrary stacking of AppArmor with SELinux or Smack (for example) ?
Posted Nov 1, 2022 22:38 UTC (Tue)
by cschaufler (subscriber, #126555)
[Link] (6 responses)
Posted Nov 1, 2022 23:12 UTC (Tue)
by Cyberax (✭ supporter ✭, #52523)
[Link]
I tried to use Smack a couple of times and I failed to find anything that is simplified compared to SELinux.
And both of them need the brain-dead "labeling".
Posted Nov 1, 2022 23:14 UTC (Tue)
by jhoblitt (subscriber, #77733)
[Link] (4 responses)
Posted Nov 3, 2022 3:59 UTC (Thu)
by jamesmorris (subscriber, #82698)
[Link] (3 responses)
Posted Nov 3, 2022 15:59 UTC (Thu)
by cschaufler (subscriber, #126555)
[Link]
Posted Nov 3, 2022 16:31 UTC (Thu)
by jhoblitt (subscriber, #77733)
[Link]
A secondary concern is that the current situation requires a flag day change between LSMs, which is a high burden.
Posted Nov 4, 2022 13:39 UTC (Fri)
by jrjohansen (subscriber, #75010)
[Link]
For the case of a system LXD style container running Ubuntu on an SELinux host minimal support needed. AppArmor needs to be enabled in the kernel, the LSM stack needs to be setup and the container manager needs access to the AppArmor interfaces (this may require some policy changes). The container manager sets up an apparmor policy namespace and the container loads its policy into that namespace and it only affects that container.
Application containers like Snap is doing can be made to work with minimal support like system style containers, but do need a little integration on the system for full confinement. In this use case AppArmor is only working to enforce container restrictions on the application, leaving host security to another LSM like SELinux.
Setting up AppArmor with a full system host policy + SELinux I don't see as being useful.
Posted Nov 7, 2022 0:49 UTC (Mon)
by jengelh (subscriber, #33263)
[Link] (2 responses)
The reality is that neither the user base nor commercial financial interest is present to add more detail in how local access is validated. Evidence of this is that practically $everyone is going in the direction of using virtualization/containers. (So like, less subdivision, more composition.) That container has a reduced fileset, and the task running inside is possibly the only UID in the container anyway, so Unix DAC is good enough.
Posted Nov 7, 2022 23:56 UTC (Mon)
by cschaufler (subscriber, #126555)
[Link] (1 responses)
So no, I don't think your parallel holds. There's no obsolete hardware involved, and even if $everone is going to virtualization/containers today (which I don't believe now any more than I believed it in 1980) they're going to go with something different in 2025.
Posted Nov 8, 2022 1:51 UTC (Tue)
by pabs (subscriber, #43278)
[Link]
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
- Do any such use-cases justify a large, invasive change to a core kernel security framework?
- Will this improve Linux security, and Linux security usability?
- Which distro or other major user will to commit to ship with all of this enabled in production, so that the code gets exercised at scale?
- Will they commit to fixing any bugs found and help with long term upstream maintenance?
- Is there consensus in the Linux kernel security community on any of these issues, and also the on the technical merit of all of the patches submitted?
- Has all the code been reviewed by maintainers and experts in all of the subsystems impacted?
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Look at how much the SELinux reference policy has "evolved" over the past 20 years before demanding that the AppArmor and Smack policies be "complete" on day one.
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules
Still waiting for stackable security modules