LWN.net Logo

The module signing endgame

By Jake Edge
November 21, 2012

Inserting a loadable module into the running kernel is a potential security problem, so some administrators want to be able to restrict which modules are allowed. One way to do that is to cryptographically sign modules and have the kernel verify that signature before loading the module. Module signing isn't for everyone, and those who aren't interested probably don't want to pay much of a price for that new feature. Even those who are interested will want to minimize that price. While cryptographically signing kernel modules can provide a security benefit, that boon comes with a cost: slower kernel builds. When that cost is multiplied across a vast number of kernel builds, it draws some attention.

David Miller complained on Google+ about the cost of module signing in mid-October. Greg Kroah-Hartman agreed in the comments, noting that an allmodconfig build took more than 10% longer between 3.6 and 3.7-rc1. The problem is the addition of module signing to the build process. Allmodconfig builds the kernel with as many modules as possible, which has the effect of build-testing nearly all of the kernel. Maintainers like Miller and Kroah-Hartman do that kind of build frequently, typically after each patch they apply, in order to ensure that the kernel still builds. Module signing can, of course, be turned off using CONFIG_MODULE_SIG, but that adds a manual configuration step to the build process, which is annoying.

Linus Torvalds noted Miller's complaint and offered up a "*much* simpler" solution: defer module signing until install time. There is already a mechanism to strip modules during the make modules_install step. Torvalds's change adds module signing into that step, which means that you don't pay the signing price until you actually install the modules. There are some use cases that would not be supported by this change, but Torvalds essentially dismissed them:

Sure, it means that if you want to load modules directly from your kernel build tree (without installing them), you'd better be running a kernel that doesn't need the signing (or you need to sign things explicitly). But seriously, nobody cares. If you are building a module after booting the kernel with the intention of loading that modified module, you aren't going to be doing that whole module signing thing *anyway*. Signed modules make sense when building the kernel and module together, so signing them as we install the kernel and module is just sensible.

One of the main proponents behind the module signing feature over the years has been David Howells; his code was used as the basis for module maintainer Rusty Russell's signature infrastructure patch. But, Howells was not particularly happy with Torvalds's changes. He would like to be able to handle some of the use cases that Torvalds dismissed, including loading modules from the kernel build tree. He thinks that automatic signing should probably just be removed from the build process; a script could be provided to do signing manually.

Howells is looking at the signed modules problem from a distribution view. Currently, the keys used to sign modules can be auto-generated at build time, with the public key getting built into the kernel and the private portion being used for signing—and then likely deleted once the build finishes. That isn't how distributions will do things, so auto-generating keys concerns Howells:

It would also be nice to get rid of the key autogeneration stuff. I'm not keen on the idea of unparameterised key autogeneration - anyone signing their modules should really supply the appropriate address elements.

That may make sense for distributions or those who will be using long-lived keys, but it makes little sense for a more basic use case. With characteristic bluntness, Torvalds pointed that out:

You seem to dismiss the "people want to build their own kernel" people entirely.

One of the main sane use-cases for module signing is:

- CONFIG_CHECK_SIGNATURE=y
- randomly generated one-time key
- "make modules_install; make install"
- "make clean" to get rid of the keys.
- reboot.

and now you have a custom kernel that has the convenience of modules, yet is basically as safe as a non-modular build. The above makes it much harder for any kind of root-kit module to be loaded, and basically entirely avoids one fundamental security scare of modules.

Kroah-Hartman agreed with the need to support the use case Torvalds described, though he noted that keys are not removed by make clean, which he considered a bit worrisome. It turns out that make clean is documented to leave the files needed to build modules, so make distclean should be used to get rid of the key files.

Russell, who has always been a bit skeptical of module signing, pointed out that Torvalds's use case could be handled by just storing the hashes of the modules in the kernel—no cryptography necessary. While that's true, Russell's scheme would disallow some other use cases. Signing provides flexibility, Torvalds said, and is "technically the right thing to do". Russell countered:

It's 52k of extra text to get that 'nice flexible'; 1% of my kernel image. That's a lot of bug free code.

Russell's concerns notwithstanding, it is clear that module signing is here to stay. Torvalds's change was added for 3.7 (with some additions by Russell and Howells). For distributions, Josh Boyer has a patch that will add a "modules_sign" target. It will operate on the modules in their installed location (i.e. after a modules_install), and remove the signature, which will allow the distribution packaging system (e.g. RPM) to generate debuginfo for the modules before re-signing them. In that way, distributions can use Torvalds's solution at the cost of signing modules twice. Since that process should be far less frequent than developers building kernels (or build farms building kernels or ...), that tradeoff is likely to be well worth that small amount of pain.


(Log in to post comments)

Copyright © 2012, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds