|| ||Vivek Goyal <email@example.com> |
|| ||firstname.lastname@example.org |
|| ||[PATCH 0/3] ELF executable signing and verification |
|| ||Tue, 15 Jan 2013 16:34:52 -0500|
|| ||email@example.com, firstname.lastname@example.org, email@example.com,
firstname.lastname@example.org, email@example.com, firstname.lastname@example.org,
|| ||Article, Thread
This is a very crude RFC for ELF executable signing and verification. This
has been done along the lines of module signature verification.
Why do we need it
With arrival of secureboot, sys_kexec() is deemed dangerous. One can
effectively bypass the secureboot feature and run its own kernel. So
matthew garret proposed disabling sys_kexec() in secureboot mode.
Later in a separate thread it was discussed how to handle the issue
of sys_kexec() with secureboot.
My takeaway from discussion was that we need to sign /sbin/kexec. Signed
executable can get extra capability and we can allow/disallow access to
sys_kexec() based on that capability (Thanks to Eric Biederman for the
So that's my motivation to make user space signing work so that I can
get kdump working with secureboot enabled. There might be other people
who might find it useful in general.
What does it do
I have written a utility "signelf" which can take a private key and
an x509 certificate and sign an ELF executable. This is very much done
along the lines of module signing. There are two major differences.
Signature are put in a section ".signature" instead of being appended
to executable. And we calculate digest of only PT_LOAD segments and not
the whole executable file.
Upon exec(), we determine if executable is signed. If it is, then locks
down the pages in memory (using MAP_LOCKED) and verfies the signature.
If signature does not match, process is killed. Unsigned processes
don't get affected at all.
Currently it is expected to use these patches only for statically linked
executables. No dynamic linking. In fact patches specifically disable
calling interpreter. This does not prevent against somebody using dlopen()
sutff. So don't sign binaries which do that.
Currently module signing keys are automatically loaded in module keyring
so it is easiest to sign executable using the keys generated for module
- Compile and boot into kernel with following options enabled.
- Compile "signelf" utility (Attached in a patch)
- Install glibc-static
- Compile a test program (say hello-world.c). Link statically with glibc
gcc hello-world.c -o hello-world -static
- Sign hello_world using keys generated during kernel build.
signelf -i hello-world -o hello-world.signed -p linux-2.6/signing_key.priv -c linux-2.6/signing_key.x509
- Run signed executable
This should run successfully. Now one can generate another pair of keys
and certificate and sign same binary using new keys. This new binary should
fail to execute as corresponding keys are not loaded in kernel.
openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 -config linux-2.6/x509.genkey -outform DER -out new_signing_key.x509 -keyout new_signing_key.priv
signelf -i hello-world -o hello-world.signed.new -p new_signing_key.priv -c new_signing_key.x509
- Run this signed executable
- kexec related patches are yet to be done.
- Disable ptrace to signed processes so that one can not modify code/data
of signed process.
- Sort out issues related to how key used for user space signing is loaded
in kernel keyring.
- Sort out issues related to sharing keyring with modules.
Vivek Goyal (3):
module: export couple of functions for use in process signature
binfmt_elf: Verify signature of signed elf binary
binfmt_elf: Do not allow exec() if signed binary has intepreter
fs/Kconfig.binfmt | 7 +
fs/binfmt_elf.c | 465 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/module.h | 8 +
kernel/module_signing.c | 4 +-
4 files changed, 482 insertions(+), 2 deletions(-)