50a9ff6df4
The kernel is moved ahead to version 3.10.0-693.21.1.el7 To summarize: CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1' This is fixed by load fences and is "baked in" and cannot be turned off. CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2' This is fixed by a combination of retpolines and IBPB, or IBRS+IBPB if on skylake. This requires a microcode change in the processors. This feature, if on, has a significant performance impact. It is assumed on unless turned off via the "nospectre_v2" bootarg. CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3' This is fixed by page table isolation using the Kaiser patches. This feature is assumed on unless turned off via the "nopti" bootarg. As of the commit date, we have changed the installer kickstarts to issue both "nopti nospectre_v2" bootargs to minimize realtime impacts by default. The customer will be able to optionally sacrifice performance for extra security at datafill time. Change-Id: Id7c99923f2ee2ee91f77c7bd9940e684eff8b476 Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
247 lines
8.2 KiB
Diff
247 lines
8.2 KiB
Diff
From 811dcb52aa4a005980b3705a47f711160563e25d Mon Sep 17 00:00:00 2001
|
|
Message-Id: <811dcb52aa4a005980b3705a47f711160563e25d.1522097754.git.Jim.Somerville@windriver.com>
|
|
In-Reply-To: <f4706beaf86081b0890ea616082913f8f51823ff.1522097754.git.Jim.Somerville@windriver.com>
|
|
References: <f4706beaf86081b0890ea616082913f8f51823ff.1522097754.git.Jim.Somerville@windriver.com>
|
|
From: Kam Nasim <kam.nasim@windriver.com>
|
|
Date: Wed, 4 Oct 2017 14:02:10 -0400
|
|
Subject: [PATCH 24/27] US103091: IMA: System Configuration
|
|
|
|
Normally (if trusted integrity keyring is disabled), the _ima keyring
|
|
needs to be created by user space (specifically systemd), but that has
|
|
the added disadvantage of requiring the IMA public key to reside on the
|
|
file system as opposed to being compiled in. Somebody could render some
|
|
serious Grade A damage by corrupting this public key on the FS.
|
|
Crippling the system if IMA 'enforce' action is enabled.
|
|
|
|
We will therefore create the IMA keyring inside the kernel and load the
|
|
IMA public key as a compiled data blob, similar to how the Kernel loads
|
|
trusted X509 keys into the system truststore (.system_keyring)
|
|
|
|
Signed-off-by: Jim Somerville <Jim.Somerville@windriver.com>
|
|
---
|
|
.gitignore | 1 +
|
|
include/keys/system_keyring.h | 2 ++
|
|
kernel/Makefile | 42 ++++++++++++++++++++--
|
|
kernel/ima_certificate.S | 20 +++++++++++
|
|
kernel/system_keyring.c | 82 +++++++++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 145 insertions(+), 2 deletions(-)
|
|
create mode 100644 kernel/ima_certificate.S
|
|
|
|
diff --git a/.gitignore b/.gitignore
|
|
index f73f35f..7148219 100644
|
|
--- a/.gitignore
|
|
+++ b/.gitignore
|
|
@@ -106,3 +106,4 @@ localversion
|
|
|
|
# Red Hat key security
|
|
kernel/x509_certificate_list
|
|
+kernel/ima_x509_certificate
|
|
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
|
|
index 0e49b3c..6b2da90 100644
|
|
--- a/include/keys/system_keyring.h
|
|
+++ b/include/keys/system_keyring.h
|
|
@@ -34,4 +34,6 @@ static inline struct key *get_system_trusted_keyring(void)
|
|
|
|
#endif /* CONFIG_SYSTEM_TRUSTED_KEYRING */
|
|
|
|
+extern struct key *ima_keyring;
|
|
+
|
|
#endif /* _KEYS_SYSTEM_KEYRING_H */
|
|
diff --git a/kernel/Makefile b/kernel/Makefile
|
|
index 5701720..9c50e4b 100644
|
|
--- a/kernel/Makefile
|
|
+++ b/kernel/Makefile
|
|
@@ -56,7 +56,7 @@ obj-$(CONFIG_QUEUED_SPINLOCKS) += qspinlock.o
|
|
obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o qrwlock_gen.o
|
|
obj-$(CONFIG_LOCK_SPIN_ON_OWNER) += osq_lock.o
|
|
obj-$(CONFIG_UID16) += uid16.o
|
|
-obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
|
|
+obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o ima_certificate.o
|
|
obj-$(CONFIG_MODULES) += module.o
|
|
obj-$(CONFIG_MODULE_SIG) += module_signing.o
|
|
obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
|
|
@@ -196,7 +196,45 @@ targets += $(obj)/.x509.list
|
|
$(obj)/.x509.list:
|
|
@echo $(X509_CERTIFICATES) >$@
|
|
|
|
-clean-files := x509_certificate_list .x509.list
|
|
+
|
|
+###############################################################################
|
|
+#
|
|
+# We will roll in the IMA X.509 certificate and pull it in the the kernel
|
|
+# so that it gets loaded into the _ima keyring during boot.
|
|
+#
|
|
+# Ideally, this should have been treated similar to other .x509 certificates
|
|
+# (X509_CERTIFICATES), but those all get loaded into the system trusted keyring
|
|
+# and since the canonical pathnames are not available in the x509_certificate_list
|
|
+# compiled data blob, there is no way to isolate the IMA certificate from the
|
|
+# rest. Therefore we treat the IMA certificate as a seperate blob all together.
|
|
+#
|
|
+# We look in the source root for the IMA certificate, of name "ima_signing_key.pub"
|
|
+#
|
|
+###############################################################################
|
|
+IMA_X509_CERTIFICATE := $(srctree)/ima_signing_key.pub
|
|
+
|
|
+ifneq ($(wildcard $(obj)/.x509.ima),)
|
|
+ifneq ($(shell cat $(obj)/.x509.ima),$(IMA_X509_CERTIFICATE))
|
|
+$(info IMA: X.509 certificate changed)
|
|
+$(shell rm $(obj)/.x509.ima)
|
|
+endif
|
|
+endif
|
|
+
|
|
+kernel/ima_certificate.o: $(obj)/ima_x509_certificate
|
|
+
|
|
+quiet_cmd_imacert = CERTS $@
|
|
+ cmd_imacert = cat $(IMA_X509_CERTIFICATE) >$@ $(foreach IMA_X509,$(IMA_X509_CERTIFICATE),; echo " - Including cert $(IMA_X509)")
|
|
+
|
|
+targets += $(obj)/ima_x509_certificate
|
|
+$(obj)/ima_x509_certificate: $(IMA_X509_CERTIFICATE) $(obj)/.x509.ima
|
|
+ $(call if_changed,imacert)
|
|
+
|
|
+targets += $(obj)/.x509.ima
|
|
+$(obj)/.x509.ima:
|
|
+ @echo $(IMA_X509_CERTIFICATE) >$@
|
|
+
|
|
+
|
|
+clean-files := x509_certificate_list .x509.list ima_x509_certificate .x509.ima
|
|
endif
|
|
|
|
ifeq ($(CONFIG_MODULE_SIG),y)
|
|
diff --git a/kernel/ima_certificate.S b/kernel/ima_certificate.S
|
|
new file mode 100644
|
|
index 0000000..0c665dd
|
|
--- /dev/null
|
|
+++ b/kernel/ima_certificate.S
|
|
@@ -0,0 +1,20 @@
|
|
+#include <linux/export.h>
|
|
+#include <linux/init.h>
|
|
+
|
|
+ __INITRODATA
|
|
+
|
|
+ .align 8
|
|
+ .globl VMLINUX_SYMBOL(ima_system_certificate)
|
|
+VMLINUX_SYMBOL(ima_system_certificate):
|
|
+__cert_list_start:
|
|
+ .incbin "kernel/ima_x509_certificate"
|
|
+__cert_list_end:
|
|
+
|
|
+ .align 8
|
|
+ .globl VMLINUX_SYMBOL(ima_system_certificate_size)
|
|
+VMLINUX_SYMBOL(ima_system_certificate_size):
|
|
+#ifdef CONFIG_64BIT
|
|
+ .quad __cert_list_end - __cert_list_start
|
|
+#else
|
|
+ .long __cert_list_end - __cert_list_start
|
|
+#endif
|
|
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
|
|
index c15e93f..92beb15 100644
|
|
--- a/kernel/system_keyring.c
|
|
+++ b/kernel/system_keyring.c
|
|
@@ -23,10 +23,15 @@ EXPORT_SYMBOL_GPL(system_trusted_keyring);
|
|
#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
|
|
struct key *system_blacklist_keyring;
|
|
#endif
|
|
+struct key *ima_keyring;
|
|
+EXPORT_SYMBOL_GPL(ima_keyring);
|
|
|
|
extern __initconst const u8 system_certificate_list[];
|
|
extern __initconst const unsigned long system_certificate_list_size;
|
|
|
|
+extern __initconst const u8 ima_system_certificate[];
|
|
+extern __initconst const unsigned long ima_system_certificate_size;
|
|
+
|
|
/*
|
|
* Load the compiled-in keys
|
|
*/
|
|
@@ -57,6 +62,27 @@ static __init int system_trusted_keyring_init(void)
|
|
|
|
set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags);
|
|
#endif
|
|
+ /* Normally (if trusted integrity keyring is disabled), the _ima
|
|
+ * keyring needs to be created by user space but that has the
|
|
+ * added disadvantage of requiring the IMA public key to reside on
|
|
+ * the file system as opposed to being compiled in.
|
|
+ * We will therefore form a _ima keyring here and load build
|
|
+ * the IMA X.509 certificate
|
|
+ *
|
|
+ * N.B: The IMA keyring only allows root userspace view & read ops
|
|
+ */
|
|
+ pr_notice("Initializing system IMA keyring\n");
|
|
+
|
|
+ ima_keyring = keyring_alloc("_ima",
|
|
+ KUIDT_INIT(0), KGIDT_INIT(0),
|
|
+ current_cred(),
|
|
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
+ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
|
|
+ KEY_ALLOC_NOT_IN_QUOTA, NULL);
|
|
+ if (IS_ERR(ima_keyring))
|
|
+ panic("Can't allocate system IMA keyring\n");
|
|
+
|
|
+ set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_keyring->flags);
|
|
|
|
return 0;
|
|
}
|
|
@@ -121,3 +147,59 @@ dodgy_cert:
|
|
return 0;
|
|
}
|
|
late_initcall(load_system_certificate_list);
|
|
+
|
|
+/*
|
|
+ * Load the compiled-in IMA certificate.
|
|
+ */
|
|
+static __init int load_ima_system_certificate(void)
|
|
+{
|
|
+ key_ref_t key;
|
|
+ const u8 *p, *end;
|
|
+ size_t plen;
|
|
+
|
|
+ pr_notice("Loading compiled-in X.509 IMA certificate\n");
|
|
+
|
|
+ p = ima_system_certificate;
|
|
+ end = p + ima_system_certificate_size;
|
|
+ while (p < end) {
|
|
+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
|
|
+ * than 256 bytes in size.
|
|
+ */
|
|
+ if (end - p < 4)
|
|
+ goto dodgy_cert;
|
|
+ if (p[0] != 0x30 &&
|
|
+ p[1] != 0x82)
|
|
+ goto dodgy_cert;
|
|
+ plen = (p[2] << 8) | p[3];
|
|
+ plen += 4;
|
|
+ if (plen > end - p)
|
|
+ goto dodgy_cert;
|
|
+
|
|
+ key = key_create_or_update(make_key_ref(ima_keyring, 1),
|
|
+ "asymmetric",
|
|
+ NULL,
|
|
+ p,
|
|
+ plen,
|
|
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
|
|
+ KEY_USR_VIEW | KEY_USR_READ),
|
|
+ KEY_ALLOC_NOT_IN_QUOTA |
|
|
+ KEY_ALLOC_TRUSTED);
|
|
+ if (IS_ERR(key)) {
|
|
+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
|
|
+ PTR_ERR(key));
|
|
+ } else {
|
|
+ set_bit(KEY_FLAG_BUILTIN, &key_ref_to_ptr(key)->flags);
|
|
+ pr_notice("Loaded X.509 cert '%s'\n",
|
|
+ key_ref_to_ptr(key)->description);
|
|
+ key_ref_put(key);
|
|
+ }
|
|
+ p += plen;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+
|
|
+dodgy_cert:
|
|
+ pr_err("Problem parsing in-kernel X.509 IMA certificate\n");
|
|
+ return 0;
|
|
+}
|
|
+late_initcall(load_ima_system_certificate);
|
|
--
|
|
1.8.3.1
|
|
|