Cryptographic signatures on kernel modules
- Preventing the kernel from loading modules which have somehow been
corrupted.
- Making it harder for an attacker to install a rootkit on
a compromised system.
- Enabling vendors of enterprise Linux distributions to block the loading of unapproved modules into stock kernels. (It should be noted that, at this point, no vendor has indicated any plans to restrict module loading in this way.)
The code which handles signed modules was originally written by Greg Kroah-Hartman; it has subsequently been fixed up in various ways by David Howells. Greg wrote a Linux Journal article about his work back in January.
The signature code works by looking at the most interesting ELF sections within a module file: the .text (program code) and .data (initialized data) areas. When the module is built, a script uses the objdump utility to extract those sections; the result can be fed to gpg to generate a signature. That signature is then patched into the module as yet another section, called module_sig. Overall, adding signatures is a relatively small change to the module build process.
The signatures are not much use, however, if nobody checks them; implementing that check within the kernel is a somewhat larger business. The 2.6 kernel includes a whole cryptographic subsystem, but that code is oriented toward the needs of networking and encrypted filesystems. Verifying module signatures using public keys was not one of the objectives when the crypto API was added. To support this task, several thousand lines of code must be added to the kernel; they perform arbitrary-precision integer arithmetic (this code came directly from GnuPG), DSA signature verification (also from GnuPG), simple in-kernel key management, and the code to actually verify module data against signatures.
As things stand in the patch currently, any public keys used to verify modules are built directly into the kernel itself. Being able to add a site-specific key at run time would be a convenient feature, but it would also defeat the purpose of this whole exercise. Any attacker who is in a position to load malevolent modules could just load a new key first, thus circumventing the signature verification. Even as things stand, a kernel using signature verification should be set up to not allow overwriting of in-kernel key data by way of /dev/kmem and such.
With all that infrastructure in place, a relatively small set of patches makes the module loader actually verify signatures. Once again, the interesting sections are stripped out, and a checksum is generated with the SHA1 algorithm. If the signature in the module (1) can be decrypted with a public key contained within the kernel, and (2) contains the same checksum, the module checks out and can be loaded.
In the code, one can see the traces of a kernel developer encountering an interesting problem. In many systems, the SHA1 transform code is kept in a loadable module. The module loader, when it attempts to verify the signature of a different module, could well force the kernel to try loading the SHA1 module. The module code, however, takes the module_mutex semaphore very early in the process; the recursive attempt will thus simply deadlock the whole thing. To avoid this problem, the crypto API was enhanced with a crypto_alloc_tfm2() function which can be instructed to not load any modules while setting itself up. The SHA1 code will have to be linked directly into the kernel if it is used for module verification.
Rawhide kernels come configured to verify any signatures found in modules,
but they will also happily load modules with no signature at all. There is
a configuration option which tightens things up, however, so that only
signed modules will be accepted. One wonders how much a proprietary module
vendor might pay to have their public key included in a distributor's stock
kernels once that option is turned on.
Index entries for this article | |
---|---|
Kernel | Cryptography |
Kernel | Modules/Signed |
Kernel | Security/Security technologies |
Posted Jul 9, 2004 0:39 UTC (Fri)
by rusty (guest, #26)
[Link] (1 responses)
In particular, I had an implementation of the same thing which I felt is a better solution that Greg's, and wanted to compare. Thanks,
Posted Jul 15, 2004 8:44 UTC (Thu)
by xose (subscriber, #535)
[Link]
But get latest from http://fr2.rpmfind.net/linux/fedora/core/development/SRPMS/
bye,
Posted Jul 9, 2004 8:36 UTC (Fri)
by keroami (guest, #6921)
[Link] (1 responses)
That in turn means that `make modules` will have to rebuild the kernel I can live with that :) Similarly, distributions couldn't leave the private key on their systems; if they'd be compromised, many other systems could be loading malafide modules again. Checking (on the network?) for a revoked GPG key seems to defeat the purpose of network modules; moreover, your whole kernel would be useless after revoking such a key. Yet, if this can be used to prevent rootkits like adore to install themselves as invisibly as they can now, I'll start using it asap!
Posted Jul 15, 2004 9:25 UTC (Thu)
by and (guest, #2883)
[Link]
Posted Jul 15, 2004 14:47 UTC (Thu)
by spender (guest, #23067)
[Link] (1 responses)
Redhat: please stop releasing half-baked solutions and promoting them as complete ones. You're a mockery of real security researchers, who work much harder than you and provide the code that you "adapt" and repackage and gain all the fame for. I expect in the near future a small application to be written that uses DMA to remove the checks inserted into the code that handles reading/writing of /dev/mem and mmaping of /dev/mem and /dev/kmem (reading/writing /dev/kmem has a return -EPERM at the beginning of the function, so it couldn't be NOP'd out to reveal the clean function). This application will simply be run before the normal rootkit is installed, without modification. As an aside, where are the people asking about Redhat's attack model for their SELinux policies in Fedora? Before with "strict" policies, things broke, so they were replaced with "relaxed" policies. Now people are happy, because "it works." Is it really working, or are people just saying "it works" to mean "it's not breaking my system." It's amazing how they can tout these features without ever saying what it's supposed to protect against! Of course, Redhat would never tell you this.. ($$ and attention before real security)
Posted Jul 15, 2004 17:43 UTC (Thu)
by scripter (subscriber, #2654)
[Link]
Integrating SELinux (even if not enabled by default) was a first step toward people using the system, working out problems, writing rule sets, etc. Without reasonable first steps, we would NEVER get to a secure state of security. As for signed executables -- of course it's not a be-all end-all security solution. NOTHING IS. But it raises the bar, and that _is_ worthwhile.
I couldn't find this code; can someone point me to where I can download it? Not a RH aficionado, I'm afraid.Cryptographic signatures on kernel modules
Rusty.
Cryptographic signatures on kernel modules
_today kernel_ is http://fr2.rpmfind.net/linux/fedora/core/development/SRPMS/kernel-2.6.7-1.486.src.rpm
You would have to use a one-time GPG private key when building kernel+modules or the rootkit would use your private key, sign its module and load it.home-built kernels
> You would have to use a one-time GPG private key when building re: home-built kernels
> kernel+modules or the rootkit would use your private key, sign its
> module and load it.
not exactly: first of all the private key is normally protected by a
password (so the cracker has to circumvent this first) and second there is
no need to store the private key permanently on the system on which the
kernel is build.
the first point implies that you have to enter your password when running
'make modules' the second argument means that you burn your key on CD and
only mount it when you need to rebuild some modules.
This code won't stop rootkits. The protections it has set up for /dev/mem and /dev/kmem can be easily disabled by modifying the kernel through DMA. An attacker need only access some device on their system capable of DMA and (ab)use it to write to portions of kernel memory that are denied through /dev/mem and /dev/kmem.Won't stop rootkits
I think your criticism is misdirected. Users require that first, the system must be usable, and second, secure. SELinux made their systems unusable, and if RedHat had left it enabled by default, they would have alienated a lot of users.Won't stop rootkits