From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org,
linux-security-module@vger.kernel.org, kexec@lists.infradead.org
Cc: akpm@linux-foundation.org, zohar@linux.vnet.ibm.com,
d.kasatkin@samsung.com, ebiederm@xmission.com, hpa@zytor.com,
matthew.garrett@nebula.com, vgoyal@redhat.com
Subject: [PATCH 08/16] binfmt_elf: Elf executable signature verification
Date: Tue, 10 Sep 2013 17:44:23 -0400 [thread overview]
Message-ID: <1378849471-10521-9-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1378849471-10521-1-git-send-email-vgoyal@redhat.com>
Do elf executable signature verification (if one is present). If signature
is present, it should be valid. Validly signed executables are locked in
memory and a flag cred->proc_signed gets set to signify this process
executable contents are signed.
If file is unsigned, it can execute but it does not have the cred->proc_signed
set.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
fs/Kconfig.binfmt | 10 +++++++++
fs/binfmt_elf.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/cred.h | 2 ++
kernel/cred.c | 2 ++
4 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 370b24c..25ae6d3 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -23,6 +23,16 @@ config BINFMT_ELF
ld.so (check the file <file:Documentation/Changes> for location and
latest version).
+config BINFMT_ELF_SIG
+ bool "ELF binary signature verification"
+ depends on BINFMT_ELF
+ depends on INTEGRITY_ASYMMETRIC_KEYS
+ depends on IMA_APPRAISE
+ depends on SYSTEM_TRUSTED_KEYRING
+ default n
+ ---help---
+ Check ELF binary signature verfication.
+
config COMPAT_BINFMT_ELF
bool
depends on COMPAT && BINFMT_ELF
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 100edcc..22a8272 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -34,6 +34,8 @@
#include <linux/utsname.h>
#include <linux/coredump.h>
#include <linux/sched.h>
+#include <linux/ima.h>
+#include <keys/system_keyring.h>
#include <asm/uaccess.h>
#include <asm/param.h>
#include <asm/page.h>
@@ -584,6 +586,11 @@ static int load_elf_binary(struct linux_binprm *bprm)
int executable_stack = EXSTACK_DEFAULT;
unsigned long def_flags = 0;
struct pt_regs *regs = current_pt_regs();
+ char *signature = NULL;
+#ifdef CONFIG_BINFMT_ELF_SIG
+ unsigned int siglen = 0;
+ bool mlock_mappings = false;
+#endif
struct {
struct elfhdr elf_ex;
struct elfhdr interp_elf_ex;
@@ -725,6 +732,43 @@ static int load_elf_binary(struct linux_binprm *bprm)
/* OK, This is the point of no return */
current->mm->def_flags = def_flags;
+#ifdef CONFIG_BINFMT_ELF_SIG
+ /*
+ * If executable is digitally signed and ima memlock info present,
+ * Lock down in memory
+ */
+ retval = ima_file_signature_alloc(bprm->file, &signature);
+
+ /*
+ * If there is an error getting signature, bail out. Having
+ * no signature is fine though.
+ */
+ if (retval < 0 && retval != -ENODATA && retval != -EOPNOTSUPP)
+ goto out_free_dentry;
+
+ if (signature != NULL) {
+ siglen = retval;
+ retval = ima_signature_type(signature);
+ if (retval == EVM_IMA_XATTR_DIGSIG &&
+ ima_memlock_file(signature, siglen)) {
+ /*
+ * Verify signature before locking down file. We don't
+ * want to memlock executables with fake signatures
+ */
+ retval = ima_appraise_file_digsig(
+ system_trusted_keyring,
+ bprm->file, signature, siglen);
+ if (retval) {
+ send_sig(SIGKILL, current, 0);
+ goto out_free_dentry;
+ }
+
+ mlock_mappings = true;
+ current->mm->def_flags |= VM_LOCKED;
+ set_bit(MMF_VM_LOCKED, ¤t->mm->flags);
+ }
+ }
+#endif
/* Do this immediately, since STACK_TOP as used in setup_arg_pages
may depend on the personality. */
SET_PERSONALITY(loc->elf_ex);
@@ -895,6 +939,23 @@ static int load_elf_binary(struct linux_binprm *bprm)
goto out_free_dentry;
}
+#ifdef CONFIG_BINFMT_ELF_SIG
+ if (mlock_mappings) {
+ /*
+ * File locked down in memory. Now it is safe against any
+ * modifications on disk by raw disk writes. Verify signature.
+ */
+ retval = ima_appraise_file_digsig(system_trusted_keyring,
+ bprm->file, signature, siglen);
+ if (retval) {
+ send_sig(SIGKILL, current, 0);
+ goto out_free_dentry;
+ }
+ /* Signature verification successful */
+ bprm->cred->proc_signed = true;
+ }
+#endif
+
if (elf_interpreter) {
unsigned long interp_map_addr = 0;
@@ -988,11 +1049,11 @@ static int load_elf_binary(struct linux_binprm *bprm)
*/
ELF_PLAT_INIT(regs, reloc_func_desc);
#endif
-
start_thread(regs, elf_entry, bprm->p);
retval = 0;
out:
kfree(loc);
+ kfree(signature);
out_ret:
return retval;
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 04421e8..1f5f418 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -136,6 +136,8 @@ struct cred {
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
struct rcu_head rcu; /* RCU deletion hook */
+ bool proc_signed; /* Executable signature have been
+ * verified post load */
};
extern void __put_cred(struct cred *);
diff --git a/kernel/cred.c b/kernel/cred.c
index e0573a4..589f1fa 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -299,6 +299,8 @@ struct cred *prepare_exec_creds(void)
new->process_keyring = NULL;
#endif
+ /* proc_signed status will be evaluated again from executable file */
+ new->proc_signed = false;
return new;
}
--
1.8.3.1
next prev parent reply other threads:[~2013-09-10 21:46 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-10 21:44 [PATCH 00/16] [RFC PATCH] Signed kexec support Vivek Goyal
2013-09-10 21:44 ` [PATCH 01/16] mm: vm_brk(), align the length to page boundary Vivek Goyal
2013-09-10 21:44 ` [PATCH 02/16] integrity: Add a function to determine digital signature length Vivek Goyal
2013-09-10 21:44 ` [PATCH 03/16] ima: Allow adding more memory locking metadata after digital signature v2 Vivek Goyal
2013-09-10 21:44 ` [PATCH 04/16] integrity: Allow digital signature verification with a given keyring ptr Vivek Goyal
2013-09-11 17:34 ` Mimi Zohar
2013-09-10 21:44 ` [PATCH 05/16] integrity: Export a function to retrieve hash algo used in digital signature Vivek Goyal
2013-09-10 21:44 ` [PATCH 06/16] ima: export new IMA functions for signature verification Vivek Goyal
2013-09-10 21:44 ` [PATCH 07/16] mm: Define a task flag MMF_VM_LOCKED for memlocked tasks and don't allow munlock Vivek Goyal
2013-09-10 21:44 ` Vivek Goyal [this message]
2013-09-10 21:44 ` [PATCH 09/16] ima: define functions to appraise memory buffer contents Vivek Goyal
2013-09-10 21:44 ` [PATCH 10/16] keyctl: Introduce a new operation KEYCTL_VERIFY_SIGNATURE Vivek Goyal
2013-09-10 21:44 ` [PATCH 11/16] ptrace: Do not allow ptrace() from unsigned process to signed one Vivek Goyal
2013-09-10 21:44 ` [PATCH 12/16] binfmt_elf: Do not mark process signed if binary has elf interpreter Vivek Goyal
2013-09-10 21:44 ` [PATCH 13/16] kexec: Allow only signed processes to call sys_kexec() in secureboot mode Vivek Goyal
2013-09-10 21:44 ` [PATCH 14/16] kexec: Export sysfs attributes for secureboot and secure modules to user space Vivek Goyal
2013-09-10 22:40 ` Greg KH
2013-09-11 13:44 ` Vivek Goyal
2013-09-10 22:57 ` Josh Boyer
2013-09-11 13:51 ` Vivek Goyal
2013-09-10 21:44 ` [PATCH 15/16] bootparam: Pass acpi_rsdp pointer in bootparam Vivek Goyal
2013-09-10 22:52 ` H. Peter Anvin
2013-09-11 11:44 ` Borislav Petkov
2013-09-11 13:45 ` Vivek Goyal
2013-09-11 14:32 ` Borislav Petkov
2013-09-12 7:34 ` Dave Young
2013-09-12 12:53 ` Borislav Petkov
[not found] ` <20130912131930.GC28500@redhat.com>
2013-09-12 14:25 ` Borislav Petkov
2013-09-12 14:34 ` Matthew Garrett
2013-09-12 14:42 ` Borislav Petkov
2013-09-13 7:12 ` Dave Young
2013-09-13 11:26 ` Borislav Petkov
2013-09-10 21:44 ` [PATCH 16/16] mount: Add a flag to not follow symlink at the end of mount point Vivek Goyal
2013-09-12 3:40 ` [PATCH 00/16] [RFC PATCH] Signed kexec support Greg KH
2013-09-12 11:43 ` Vivek Goyal
2013-09-12 16:17 ` Greg KH
2013-09-12 18:24 ` Mimi Zohar
[not found] ` <20130916142852.GB20753@redhat.com>
2013-09-18 14:51 ` Andrea Adami
2013-09-23 17:15 ` Vivek Goyal
2013-09-16 14:24 ` Vivek Goyal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1378849471-10521-9-git-send-email-vgoyal@redhat.com \
--to=vgoyal@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=d.kasatkin@samsung.com \
--cc=ebiederm@xmission.com \
--cc=hpa@zytor.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=matthew.garrett@nebula.com \
--cc=zohar@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).