|
|
Log in / Subscribe / Register

Writing your own security module

By Jonathan Corbet
February 10, 2016

linux.conf.au 2016
Casey Schaufler started off his linux.conf.au 2016 talk by noting that a prospective security-module author may be told that writing a new module is not necessarily a good idea. They'll hear that we already have a good selection of security modules, or it can all be done with SELinux anyway and, besides, kernel programming is hard. But, he said, there are indeed good reasons for wanting to write a new security module; he was there to discuss those reasons and give some guidance for those unfamiliar with this part of the kernel.

So why might one want to write a new security module? Our current modules, he said, are showing their age; they follow a design that dates from a time when users actually sat in a computer room to do their work. These modules are a poor fit to the concerns we have now; they were not designed with systems like smartphones in mind. We need to start working on ideas that don't date from the era of paper tape. And, in any case, there are things that cannot be done with SELinux.

It is important to understand what security modules can do. They are a way to add new restrictive controls to operations that a process might try to perform; they cannot replace the existing discretionary access control checks, which will be done anyway. Thus, they offer a new opportunity to say "no" to an operation, but they cannot authorize an action that the user would not have otherwise been able to perform.

There are a few basic rules to bear in mind when contemplating a new security module. The first of those is to avoid duplicating existing modules. If SELinux can do what you need, you're better off joining its community and pushing things in the direction that you need. Another rule is to not rely heavily on user-space helpers. There is a proprietary module out there, he said, that asks user space to make the actual security decisions. This solution is inefficient and provides a hook for proprietary code; either reason would be enough to keep it from ever going upstream. Remember that you're playing in kernel space, so try not to upset the kernel developers; he named Al Viro in particular as one not to inflame.

The most important rule, though, is to plagiarize freely from other security modules; don't reinvent things that already exist and work. When he wrote Smack, he took a lot of things from SELinux. That, he said, is how we do things in the Linux community.

How security modules work

Casey started into the mechanics of security modules by talking about the hooks that they rely on. There are function calls scattered around the kernel that exist to give security modules a chance to make a decision on a specific action; their names all start with "security_". Modules use these hooks to do access checks and perform general data management; it is only necessary to write the hooks that are relevant to the task at hand. Following normal kernel conventions, hooks return zero for success (generally allowing the requested operation); EACCES should be used to indicate a policy denial, while EPERM means that a necessary privilege is missing.

Many (or most) hooks are object-based, in that they relate to a specific object in kernel space. Hooks often deal with inode structures, for example, since those structures represent files within the kernel. Some hooks, though, work with pathnames instead. Paths are more human-friendly, since that's how people deal with files, but they may not uniquely identify the underlying object (files can have more than one name, for example).

"Security blobs" are data structures attached to objects by a security module. One will often see the terms secctx, which refers to a text string associated with a blob, and secid, a 32-bit ID number for a blob. There are two types of modules, called "major" and "minor," with the difference being that major modules use blobs. There can only be [Casey Schaufler] one major module active in the kernel, and it runs after any other module. There is no mechanism, yet, for sharing the security-blob pointers between modules; Casey allowed as to how fixing that is an ongoing crusade of his. Minor modules, thus, have no blobs and don't maintain any per-object state. They run after the discretionary checks, but before the major module, if one exists.

There are some questions that should be answered before attempting to design a new security module, starting with: what resource is to be protected by the module? If you can't answer that, Casey said, you're not thinking about security. Answers might be files created by a particular user, or specific paths within the filesystem, or one might want to protect specific processes from each other.

That leads to the second question: what is that resource to be protected from? Traditionally, security has been based around users, but now we think about things like malicious apps. So, rather than protecting users from each other, we're now concerned with protecting Facebook's data from Netflix.

Finally, a security-module developer needs to know how that protection will be done. The traditional answer is to simply deny access to unauthorized users, but other approaches are possible. Logging of such attempts is often done, of course. One could consider more wide-ranging changes, such as changing the ownership of a file to match the last user who wrote to it via group access.

Various details

Security modules can make information available under /proc. One should, however, resist the temptation to reuse the attribute names already used by SELinux; a new security module should make its own names.

Objects contain numerous attributes that can be used by a security module; these include ownership, access mode, object types and sizes, etc. Modules can use them any way they like, but they should not change their fundamental meaning. The user ID should not identify the application, as "a certain system" has done. Security modules can make decisions based on pathnames if that works best, though the interface to pathnames inside the kernel is not the most convenient.

With regard to networking, Casey said, there may not be much for a security-module developer to do. Linux has the netfilter subsystem that can make all kinds of access-control decisions; that approach should always be tried first. If a module must be written, there are hooks for various socket operations, and for packet delivery as well. The SO_PEERSEC socket operation can be used to pass security attributes to another process. Working with Unix-domain sockets is easy, he said, because the security module has access to both ends of the connection. Internet sockets are harder, since only one end is available. The CIPSO mechanism can be used to send attributes across a link; support for CALIPSO, which will make similar functionality available under IPv6, is coming.

Casey suggested that modules probably want to log access denials, to help with policy debugging if nothing else. Helpful stuff can be found in <linux/lsm_audit.h>. The actual data to be logged is up to the module author; various utilities are available for formatting that data in user space.

Non-trivial modules probably need control interfaces; administrators will want to be able to change access rules, look at statistics, and more. Casey advised against adding new ioctl() calls or system calls; instead, a virtual filesystem should be created. A call to sysfs_create_mount_point() makes that easy; he recommended borrowing the relevant code from an existing module.

Finally, what about stacking of security modules? At this point, stacking of minor modules is easy and supported, but there can only be one major module at a time, since there is only one security-blob pointer. There is, he said, a way to cheat on systems where the kernel is built from source: simply add the new security blob to the SELinux blob. Work is in progress to allow multiple major modules, but they cannot be supported now.

In the end, Casey said, anybody looking to write a security module should have a good reason for doing it. Some stuff, after all, really does belong in user space. If you write a module, do it properly: provide documentation and support the code. Don't reinvent the wheel; generic security has long since been done, show us something new instead. Nobody has done a good application resource-management security policy, for example. There is interesting potential around policies tied to the sensors found on current devices. Security, he said, does not have to be dull.

The video of this talk is available on the LCA site.

[Your editor thanks LCA for assisting with his travel expenses.]

Index entries for this article
KernelModules/Security modules
KernelSecurity/Security modules
SecurityLinux Security Modules (LSM)
Conferencelinux.conf.au/2016


to post comments

Writing your own security module

Posted Feb 11, 2016 5:16 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link] (4 responses)

> Thus, they offer a new opportunity to say "no" to an operation, but they cannot authorize an action that the user would not have otherwise been able to perform.
Every time I hear about this, I'm repeatedly amazed how people see this as a good thing.

To me it looks like the second most braindead decision in the LSM community, after SELinux.

Writing your own security module

Posted Feb 11, 2016 8:51 UTC (Thu) by eternaleye (guest, #67051) [Link] (3 responses)

I disagree - fundamentally, this is a design decision that the system as a whole *must* "fail closed", providing protection *no worse* than before it was enabled.

If one wishes to completely ignore DAC, then one may simply chmod -R a=rwX /remount/of/filesystem (modulo the work needed to patch software to allow itself to run in such a system without complaining about the insecure mode bits, and to make udev rules and the like not try to set ownership and access)

Writing your own security module

Posted Feb 11, 2016 9:08 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link] (2 responses)

> I disagree - fundamentally, this is a design decision that the system as a whole *must* "fail closed", providing protection *no worse* than before it was enabled.
Yet it does exactly the OPPOSITE!! Turning SELinux _off_ makes a system more permissive.

Maybe for some people it's tempting to do "chmod -R 777 /" and hope that SELinux will limit the damage. I would prefer to do the opposite: chmod -R 000 /" and then use LSMs to grant additional permissions on a need-to-know basis.

Consequently, since SELinux's only visible effect is for systems to fail in various interesting places, pretty much every troubleshooting guide starts with "turn SELinux off".

Writing your own security module

Posted Feb 25, 2016 1:10 UTC (Thu) by eternaleye (guest, #67051) [Link] (1 responses)

That is not what I meant by "fail closed"

I mean that a misconfiguration of the complex system (SELinux) must-not reduce the security of the system relative to the baseline (POSIX mode bits).

If they worked the way you are suggesting, turning on SELinux before a policy is set up would, instantly, have the same effect as chmod'ing everything 0777.

That is "failing open"

Writing your own security module

Posted Feb 25, 2016 1:45 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link]

> If they worked the way you are suggesting, turning on SELinux before a policy is set up would, instantly, have the same effect as chmod'ing everything 0777.
Incorrect. If SELinux could be used to grant access instead of restrict it, it would have been easy to design it to default to "disable".

Network firewalls are a good example. Firewall rules can grant access, but it's considered to be a good practice to start your rules with "deny any" and then add more specific "allow" rules.

Writing your own security module

Posted Mar 2, 2016 13:30 UTC (Wed) by nye (guest, #51576) [Link]

>The user ID should not identify the application, as "a certain system" has done.

Why not? Per-application UIDs seems like a reasonable way to isolate those applications using existing mechanisms without having to redesign the entire Unix security model from scratch, no?


Copyright © 2016, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds