linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Trusted kernel patchset
@ 2015-03-13 21:38 Matthew Garrett
  2015-03-13 21:38 ` [PATCH 01/12] Add support for indicating that the booted kernel is externally trusted Matthew Garrett
                   ` (13 more replies)
  0 siblings, 14 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes

This is a slightly cleaned up version of the patchset posted last year
(https://lkml.org/lkml/2014/2/26/554). I've made a couple of minor changes
based on feedback, but otherwise this is pretty much the same. Some things
I *haven't* done:

1) Disabled CAP_SYS_RAWIO

Disabling CAP_SYS_RAWIO has the fun side effect of disabling things like
CPU microcode loading. Given that the microcode is already signed and the
CPU validates that, this isn't helpful. There's just too many cases where
CAP_SYS_RAWIO is required for features that are outside the scope of ensuring
that the kernel can't be tampered with. In addition, there are features that
don't require CAP_SYS_RAWIO which should be blocked.

2) Disabled CAP_SYS_RAWIO but whitelisted specific CAP_SYS_RAWIO features

This was Alan's suggestion - change capable() to check whether the capability
requested was blacklisted, and then add a capable_always() that ignored the
blacklist. In this scenario, /dev/mem would still use capable(CAP_SYS_RAWIO)
and would be denied, but the microcode loader would use
capable_always(CAP_SYS_RAWIO) and would be permitted. This changes certain
behavioural expectations (eg, having CAP_SYS_RAWIO would no longer be
sufficient to pass capable(CAP_SYS_RAWIO)) and would still hit the problem
of features that should be blocked but don't currently require CAP_SYS_RAWIO.
I think this is fundamentally more confusing than the approach I've
implemented.

3) Done one of the above and added new CAP_SYS_RAWIO checks

This would handle the case of features that should be blocked but which don't
currently require CAP_SYS_RAWIO, but would break any userspace that has
dropped privileges and expects to be able to use these features even in the
case that this feature isn't enabled. I don't think it's beneficial.

4) Used the word "measured"

Nothing is being measured.

A patchset basically equivalent to this is already used by most major Linux
distributions, so it would be nice to either get this merged or have feedback
from a relevant maintainer as to how they'd like it to be implemented instead.

-- 
Matthew Garrett | <matthew.garrett@nebula.com> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 01/12] Add support for indicating that the booted kernel is externally trusted
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 02/12] Enforce module signatures when trusted kernel is enabled Matthew Garrett
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

Provide a boolean runtime configuration option for restricting userspace's
ability to modify the running kernel. This can be used when some external
validation of the kernel's state has been performed.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 Documentation/kernel-parameters.txt       |   6 ++
 Documentation/security/trusted_kernel.txt |  35 ++++++++++
 include/linux/security.h                  |  10 +++
 security/Kconfig                          |   9 +++
 security/Makefile                         |   1 +
 security/trusted_kernel.c                 | 111 ++++++++++++++++++++++++++++++
 6 files changed, 172 insertions(+)
 create mode 100644 Documentation/security/trusted_kernel.txt
 create mode 100644 security/trusted_kernel.c

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index bfcb1a6..2d2aa946 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -3647,6 +3647,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			with respect to transparent hugepages.
 			See Documentation/vm/transhuge.txt for more details.
 
+	trusted_kernel	Indicate that the booted kernel has been verified to
+			be trustworthy and that userspace should be forbidden
+			from modifying it at runtime.
+			See Documentation/security/trusted_kernel.txt for more
+			details.
+
 	tsc=		Disable clocksource stability checks for TSC.
 			Format: <string>
 			[x86] reliable: mark tsc clocksource as reliable, this
diff --git a/Documentation/security/trusted_kernel.txt b/Documentation/security/trusted_kernel.txt
new file mode 100644
index 0000000..95300bb
--- /dev/null
+++ b/Documentation/security/trusted_kernel.txt
@@ -0,0 +1,35 @@
+Linux trusted kernel support
+----------------------------
+
+Various mechanisms exist to ensure that a booted kernel is trusted by the
+user or some external party (UEFI Secure Boot, Intel TXT, embedded platform
+bootloaders). If userspace is able to modify the running kernel then this
+trust can be subverted.
+
+The trusted kernel support modifies certain kernel interfaces such that
+userspace is restricted from performing acts that would allow it to inject
+untrusted code into the kernel. Userspace will be unable to perform direct
+access to PCI devices, port IO access, access system memory directly via
+/dev/mem and /dev/kmem, perform kexec_load(), use the userspace software
+suspend mechanism, insert new ACPI code at runtime via the custom_method
+interface or modify CPU MSRs (on x86). Certain drivers may also limit
+additional interfaces.
+
+The trusted kernel feature may be enabled in multiple ways:
+
+1) Platform-specific code may automatically enable it when it detects that
+the system has been booted appropriately
+
+2) The user or bootloader may pass the "trusted_kernel" kernel parameter
+
+3) Userspace may write "1" to the /sys/kernel/security/trusted_kernel
+node. This must be done sufficiently early in the boot process that
+untrusted userspace has no opportunity to modify the kernel.
+
+Once enabled, trusted kernel support may not be disabled without rebooting
+the system.
+
+Note that this is a mechanism for the kernel to determine whether or not
+it is externally trusted. Untrusted userspace can enable this option even
+if the kernel is not trusted, and therefore userspace should not use this
+value as an indication of whether or not the kernel is trustworthy.
diff --git a/include/linux/security.h b/include/linux/security.h
index a1b7dbd..87bbbc0 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -3174,6 +3174,16 @@ static inline void security_audit_rule_free(void *lsmrule)
 #endif /* CONFIG_SECURITY */
 #endif /* CONFIG_AUDIT */
 
+#ifdef CONFIG_SECURITY_TRUSTED_KERNEL
+extern bool get_trusted_kernel(void);
+extern int set_trusted_kernel(bool new_trusted_kernel);
+#else
+static inline bool get_trusted_kernel(void) { return 0; }
+static inline int set_trusted_kernel(bool new_trusted_kernel) {
+	return -ENOTSUPP;
+}
+#endif /* CONFIG_SECURITY_TRUSTED_KERNEL */
+
 #ifdef CONFIG_SECURITYFS
 
 extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
diff --git a/security/Kconfig b/security/Kconfig
index beb86b5..c0462c9 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -70,6 +70,15 @@ config SECURITY_PATH
 	  implement pathname based access controls.
 	  If you are unsure how to answer this question, answer N.
 
+config SECURITY_TRUSTED_KERNEL
+        bool "Support for indicating that the kernel is trusted"
+	depends on SECURITY
+	help
+	  This enables support for adding a set of additional kernel security
+	  restrictions at runtime.
+	  See Documentation/security/trusted_kernel.txt for further
+	   information.
+
 config INTEL_TXT
 	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
 	depends on HAVE_INTEL_TXT
diff --git a/security/Makefile b/security/Makefile
index 05f1c93..0d5d689 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMU)			+= min_addr.o
 # Object file lists
 obj-$(CONFIG_SECURITY)			+= security.o capability.o
 obj-$(CONFIG_SECURITYFS)		+= inode.o
+obj-$(CONFIG_SECURITY_TRUSTED_KERNEL)	+= trusted_kernel.o
 obj-$(CONFIG_SECURITY_SELINUX)		+= selinux/
 obj-$(CONFIG_SECURITY_SMACK)		+= smack/
 obj-$(CONFIG_AUDIT)			+= lsm_audit.o
diff --git a/security/trusted_kernel.c b/security/trusted_kernel.c
new file mode 100644
index 0000000..2808113
--- /dev/null
+++ b/security/trusted_kernel.c
@@ -0,0 +1,111 @@
+/*
+ *  trusted_kernel.c - support for generic kernel lockdown
+ *
+ *  Copyright Nebula, Inc <matthew.garrett@nebula.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/uaccess.h>
+
+static bool trusted_kernel;
+
+bool get_trusted_kernel(void)
+{
+	return trusted_kernel;
+}
+EXPORT_SYMBOL(get_trusted_kernel);
+
+int set_trusted_kernel(bool new_trusted_kernel)
+{
+	if (trusted_kernel == true && new_trusted_kernel == false)
+		return -EINVAL;
+
+	trusted_kernel = new_trusted_kernel;
+
+	return 0;
+}
+EXPORT_SYMBOL(set_trusted_kernel);
+
+static ssize_t trusted_kernel_read(struct file *filp, char __user *buf,
+				   size_t count, loff_t *ppos)
+{
+	char tmpbuf[2];
+	ssize_t length;
+
+	length = scnprintf(tmpbuf, sizeof(tmpbuf), "%d", trusted_kernel);
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static ssize_t trusted_kernel_write(struct file *file, const char __user *buf,
+				    size_t count, loff_t *ppos)
+{
+	char *page = NULL;
+	ssize_t length;
+	int new_trusted_kernel;
+
+	length = -ENOMEM;
+	if (count >= PAGE_SIZE)
+		goto out;
+
+	length = -EINVAL;
+	if (*ppos != 0)
+		goto out;
+
+	length = -ENOMEM;
+	page = (char *)get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		goto out;
+
+	length = -EFAULT;
+	if (copy_from_user(page, buf, count))
+		goto out;
+
+	length = -EINVAL;
+	if (sscanf(page, "%d", &new_trusted_kernel) != 1)
+		goto out;
+
+	length = set_trusted_kernel(!!new_trusted_kernel);
+	if (length)
+		goto out;
+
+	length = count;
+out:
+	free_page((unsigned long) page);
+	return length;
+}
+
+static const struct file_operations trusted_kernel_fops = {
+	.read	= trusted_kernel_read,
+	.write	= trusted_kernel_write,
+	.llseek	= generic_file_llseek,
+};
+
+static __init int setup_trusted_kernel(void)
+{
+	struct dentry *trusted_kernel_file;
+
+	trusted_kernel_file = securityfs_create_file("trusted_kernel",
+						     S_IWUSR | S_IRUGO,
+						     NULL, NULL,
+						     &trusted_kernel_fops);
+
+	if (IS_ERR(trusted_kernel_file))
+		return PTR_ERR(trusted_kernel_file);
+
+	return 0;
+}
+late_initcall(setup_trusted_kernel);
+
+static int __init enable_trusted_kernel(char *__str)
+{
+	trusted_kernel = true;
+	return 1;
+}
+__setup("trusted_kernel", enable_trusted_kernel);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 02/12] Enforce module signatures when trusted kernel is enabled
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
  2015-03-13 21:38 ` [PATCH 01/12] Add support for indicating that the booted kernel is externally trusted Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 03/12] PCI: Lock down register access when trusted_kernel is true Matthew Garrett
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

If trusted_kernel is true, require that all modules have valid signatures.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 include/linux/module.h    | 6 ++++++
 kernel/module.c           | 6 ++++++
 security/trusted_kernel.c | 6 +++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 42999fe..1cf89e2 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -502,6 +502,8 @@ int unregister_module_notifier(struct notifier_block *nb);
 
 extern void print_modules(void);
 
+void enable_module_sig_enforce(void);
+
 #else /* !CONFIG_MODULES... */
 
 /* Given an address, look for it in the exception tables. */
@@ -612,6 +614,10 @@ static inline int unregister_module_notifier(struct notifier_block *nb)
 static inline void print_modules(void)
 {
 }
+
+static inline void enable_module_sig_enforce(void)
+{
+}
 #endif /* CONFIG_MODULES */
 
 #ifdef CONFIG_SYSFS
diff --git a/kernel/module.c b/kernel/module.c
index cc93cf6..842f58e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3893,3 +3893,9 @@ void module_layout(struct module *mod,
 }
 EXPORT_SYMBOL(module_layout);
 #endif
+
+void enable_module_sig_enforce(void)
+{
+	sig_enforce = true;
+}
+EXPORT_SYMBOL(enable_module_sig_enforce);
diff --git a/security/trusted_kernel.c b/security/trusted_kernel.c
index 2808113..22c4c30 100644
--- a/security/trusted_kernel.c
+++ b/security/trusted_kernel.c
@@ -11,6 +11,7 @@
 
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/security.h>
 #include <linux/uaccess.h>
 
@@ -29,6 +30,9 @@ int set_trusted_kernel(bool new_trusted_kernel)
 
 	trusted_kernel = new_trusted_kernel;
 
+	if (trusted_kernel == true)
+		enable_module_sig_enforce();
+
 	return 0;
 }
 EXPORT_SYMBOL(set_trusted_kernel);
@@ -105,7 +109,7 @@ late_initcall(setup_trusted_kernel);
 
 static int __init enable_trusted_kernel(char *__str)
 {
-	trusted_kernel = true;
+	set_trusted_kernel(true);
 	return 1;
 }
 __setup("trusted_kernel", enable_trusted_kernel);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 03/12] PCI: Lock down register access when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
  2015-03-13 21:38 ` [PATCH 01/12] Add support for indicating that the booted kernel is externally trusted Matthew Garrett
  2015-03-13 21:38 ` [PATCH 02/12] Enforce module signatures when trusted kernel is enabled Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 04/12] x86: Lock down IO port " Matthew Garrett
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

Any hardware that can potentially generate DMA has to be locked down from
userspace in order to avoid it being possible for an attacker to modify
kernel code. This should be prevented if trusted_kernel has been set, so
this patch disables userspace access to PCI regions and config access.
In future we can potentially relax this for sufficiently IOMMU-isolated
devices.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 drivers/pci/pci-sysfs.c | 9 +++++++++
 drivers/pci/proc.c      | 9 ++++++++-
 drivers/pci/syscall.c   | 3 ++-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 312f23a..7348ed7 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -710,6 +710,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
 	loff_t init_off = off;
 	u8 *data = (u8 *) buf;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (off > dev->cfg_size)
 		return 0;
 	if (off + count > dev->cfg_size) {
@@ -1004,6 +1007,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	resource_size_t start, end;
 	int i;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
 		if (res == &pdev->resource[i])
 			break;
@@ -1105,6 +1111,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
 				     struct bin_attribute *attr, char *buf,
 				     loff_t off, size_t count)
 {
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 3f155e7..701ff1a 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -11,6 +11,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/capability.h>
+#include <linux/security.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include "pci.h"
@@ -116,6 +117,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
 	int size = dev->cfg_size;
 	int cnt;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (pos >= size)
 		return 0;
 	if (nbytes >= size)
@@ -195,6 +199,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
 #endif /* HAVE_PCI_MMAP */
 	int ret = 0;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	switch (cmd) {
 	case PCIIOC_CONTROLLER:
 		ret = pci_domain_nr(dev->bus);
@@ -233,7 +240,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 	struct pci_filp_private *fpriv = file->private_data;
 	int i, ret;
 
-	if (!capable(CAP_SYS_RAWIO))
+	if (!capable(CAP_SYS_RAWIO) || (get_trusted_kernel()))
 		return -EPERM;
 
 	/* Make sure the caller is mapping a real resource for this device */
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
index b91c4da..95bcbc5 100644
--- a/drivers/pci/syscall.c
+++ b/drivers/pci/syscall.c
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/pci.h>
 #include <linux/syscalls.h>
+#include <linux/security.h>
 #include <asm/uaccess.h>
 #include "pci.h"
 
@@ -92,7 +93,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
 	u32 dword;
 	int err = 0;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN) || (get_trusted_kernel()))
 		return -EPERM;
 
 	dev = pci_get_bus_and_slot(bus, dfn);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 04/12] x86: Lock down IO port access when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (2 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 03/12] PCI: Lock down register access when trusted_kernel is true Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 05/12] Restrict /dev/mem and /dev/kmem " Matthew Garrett
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

IO port access would permit users to gain access to PCI configuration
registers, which in turn (on a lot of hardware) give access to MMIO register
space. This would potentially permit root to trigger arbitrary DMA, so lock
it down when trusted_kernel is true

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 arch/x86/kernel/ioport.c | 5 +++--
 drivers/char/mem.c       | 7 +++++++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 4ddaf66..3121541 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -15,6 +15,7 @@
 #include <linux/thread_info.h>
 #include <linux/syscalls.h>
 #include <linux/bitmap.h>
+#include <linux/security.h>
 #include <asm/syscalls.h>
 
 /*
@@ -28,7 +29,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
 		return -EINVAL;
-	if (turn_on && !capable(CAP_SYS_RAWIO))
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || (get_trusted_kernel())))
 		return -EPERM;
 
 	/*
@@ -103,7 +104,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
 		return -EINVAL;
 	/* Trying to gain more privileges? */
 	if (level > old) {
-		if (!capable(CAP_SYS_RAWIO))
+		if (!capable(CAP_SYS_RAWIO) || (get_trusted_kernel()))
 			return -EPERM;
 	}
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 297110c..74227cd 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -27,6 +27,7 @@
 #include <linux/export.h>
 #include <linux/io.h>
 #include <linux/aio.h>
+#include <linux/security.h>
 
 #include <linux/uaccess.h>
 
@@ -559,6 +560,9 @@ static ssize_t read_port(struct file *file, char __user *buf,
 	unsigned long i = *ppos;
 	char __user *tmp = buf;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (!access_ok(VERIFY_WRITE, buf, count))
 		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
@@ -577,6 +581,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
 	unsigned long i = *ppos;
 	const char __user *tmp = buf;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 05/12] Restrict /dev/mem and /dev/kmem when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (3 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 04/12] x86: Lock down IO port " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 06/12] acpi: Limit access to custom_method if " Matthew Garrett
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

Allowing users to write to address space provides mechanisms that may permit
modification of the kernel at runtime. Prevent this if trusted_kernel is
true.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 drivers/char/mem.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 74227cd..91e7409 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -164,6 +164,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
 	unsigned long copied;
 	void *ptr;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (p != *ppos)
 		return -EFBIG;
 
@@ -513,6 +516,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
 	char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
 	int err = 0;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (p < (unsigned long) high_memory) {
 		unsigned long to_write = min_t(unsigned long, count,
 					       (unsigned long)high_memory - p);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 06/12] acpi: Limit access to custom_method if trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (4 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 05/12] Restrict /dev/mem and /dev/kmem " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 07/12] acpi: Ignore acpi_rsdp kernel parameter when " Matthew Garrett
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

custom_method effectively allows arbitrary access to system memory, making
it possible for an attacker to modify the kernel at runtime. Prevent this
if trusted_kernel is true.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 drivers/acpi/custom_method.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
index c68e724..774bb7b 100644
--- a/drivers/acpi/custom_method.c
+++ b/drivers/acpi/custom_method.c
@@ -8,6 +8,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/acpi.h>
+#include <linux/security.h>
 
 #include "internal.h"
 
@@ -29,6 +30,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
 	struct acpi_table_header table;
 	acpi_status status;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (!(*ppos)) {
 		/* parse the table header to get the table length */
 		if (count <= sizeof(struct acpi_table_header))
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 07/12] acpi: Ignore acpi_rsdp kernel parameter when trusted_kernel is true.
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (5 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 06/12] acpi: Limit access to custom_method if " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 08/12] kexec: Disable loading of unverified images Matthew Garrett
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes, Josh Boyer

From: Josh Boyer <jwboyer@redhat.com>

This option allows userspace to pass the RSDP address to the kernel, which
makes it possible for a user to execute arbitrary code in the kernel.
Disable this when trusted_kernel is true.

Signed-off-by: Josh Boyer <jwboyer@redhat.com>
---
 drivers/acpi/osl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index f9eeae8..6984fc0 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -44,6 +44,7 @@
 #include <linux/list.h>
 #include <linux/jiffies.h>
 #include <linux/semaphore.h>
+#include <linux/security.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -255,7 +256,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
 acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
 #ifdef CONFIG_KEXEC
-	if (acpi_rsdp)
+	if (acpi_rsdp && !get_trusted_kernel())
 		return acpi_rsdp;
 #endif
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 08/12] kexec: Disable loading of unverified images
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (6 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 07/12] acpi: Ignore acpi_rsdp kernel parameter when " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 09/12] uswsusp: Disable when trusted_kernel is true Matthew Garrett
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

kexec permits the loading and execution of arbitrary code in ring 0, which
permits the modification of the running kernel. Restrict it such that only
images which have been verified may be loaded when trusted_kernel is true.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 kernel/kexec.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/kernel/kexec.c b/kernel/kexec.c
index 38c25b1..463b369 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -36,6 +36,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/compiler.h>
 #include <linux/hugetlb.h>
+#include <linux/security.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -1247,6 +1248,14 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 		return -EPERM;
 
 	/*
+	 * This codepath has no mechanism for verifying that the loaded image
+	 * is trustworthy, so forbid using kexec_load() if the kernel is
+	 * trusted
+	 */
+	if (get_trusted_kernel())
+		return -EPERM;
+
+	/*
 	 * Verify we have a legal set of flags
 	 * This leaves us room for future extensions.
 	 */
@@ -1388,6 +1397,15 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
 	int ret = 0, i;
 	struct kimage **dest_image, *image;
 
+#ifndef CONFIG_KEXEC_VERIFY_SIG
+	/*
+	 * Don't permit images to be loaded into trusted kernels if we're not
+	 * going to verify the signature on them
+	 */
+	if (get_trusted_kernel())
+		return -EPERM;
+#endif
+
 	/* We only trust the superuser with rebooting the system. */
 	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
 		return -EPERM;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 09/12] uswsusp: Disable when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (7 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 08/12] kexec: Disable loading of unverified images Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-16 21:36   ` Kees Cook
  2015-03-13 21:38 ` [PATCH 10/12] x86: Restrict MSR access " Matthew Garrett
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

uswsusp allows a user process to dump and then restore kernel state, which
makes it possible to modify the running kernel. Disable this if
trusted_kernel is true.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 kernel/power/user.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/power/user.c b/kernel/power/user.c
index 526e891..43b7b59 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -24,6 +24,7 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 
@@ -49,7 +50,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
 	struct snapshot_data *data;
 	int error;
 
-	if (!hibernation_available())
+	if (get_trusted_kernel() || !hibernation_available())
 		return -EPERM;
 
 	lock_system_sleep();
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 10/12] x86: Restrict MSR access when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (8 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 09/12] uswsusp: Disable when trusted_kernel is true Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 11/12] asus-wmi: Restrict debugfs interface " Matthew Garrett
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

Permitting write access to MSRs allows userspace to modify the running
kernel. Prevent this if trusted_kernel is true. Based on a patch by Kees
Cook.

Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 arch/x86/kernel/msr.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 113e707..dec5550 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -39,6 +39,7 @@
 #include <linux/notifier.h>
 #include <linux/uaccess.h>
 #include <linux/gfp.h>
+#include <linux/security.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -105,6 +106,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
 	int err = 0;
 	ssize_t bytes = 0;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	if (count % 8)
 		return -EINVAL;	/* Invalid chunk size */
 
@@ -152,6 +156,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
 			err = -EBADF;
 			break;
 		}
+		if (get_trusted_kernel()) {
+			err = -EPERM;
+			break;
+		}
 		if (copy_from_user(&regs, uregs, sizeof regs)) {
 			err = -EFAULT;
 			break;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 11/12] asus-wmi: Restrict debugfs interface when trusted_kernel is true
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (9 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 10/12] x86: Restrict MSR access " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-03-13 21:38 ` [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode Matthew Garrett
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

We have no way of validating what all of the Asus WMI methods do on a
given machine, and there's a risk that some will allow hardware state to
be manipulated in such a way that arbitrary code can be executed in the
kernel. Prevent that if trusted_kernel is true.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 drivers/platform/x86/asus-wmi.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 7543a56..d708fdc 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -47,6 +47,7 @@
 #include <linux/thermal.h>
 #include <linux/acpi.h>
 #include <linux/dmi.h>
+#include <linux/security.h>
 #include <acpi/video.h>
 
 #include "asus-wmi.h"
@@ -1589,6 +1590,9 @@ static int show_dsts(struct seq_file *m, void *data)
 	int err;
 	u32 retval = -1;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
 
 	if (err < 0)
@@ -1605,6 +1609,9 @@ static int show_devs(struct seq_file *m, void *data)
 	int err;
 	u32 retval = -1;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
 				    &retval);
 
@@ -1629,6 +1636,9 @@ static int show_call(struct seq_file *m, void *data)
 	union acpi_object *obj;
 	acpi_status status;
 
+	if (get_trusted_kernel())
+		return -EPERM;
+
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
 				     1, asus->debug.method_id,
 				     &input, &output);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (10 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 11/12] asus-wmi: Restrict debugfs interface " Matthew Garrett
@ 2015-03-13 21:38 ` Matthew Garrett
  2015-04-22 11:36   ` Dan Carpenter
  2015-03-15  1:53 ` Trusted kernel patchset Matthew Garrett
  2015-03-16 14:45 ` One Thousand Gnomes
  13 siblings, 1 reply; 30+ messages in thread
From: Matthew Garrett @ 2015-03-13 21:38 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes,
	Matthew Garrett

UEFI Secure Boot provides a mechanism for ensuring that the firmware will
only load signed bootloaders and kernels. Certain use cases may also
require that the kernel prevent userspace from inserting untrusted kernel
code at runtime. Add a configuration option that enforces this automatically
when enabled.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
---
 Documentation/x86/zero-page.txt       |  2 ++
 arch/x86/Kconfig                      | 13 +++++++++++++
 arch/x86/boot/compressed/eboot.c      | 33 +++++++++++++++++++++++++++++++++
 arch/x86/include/uapi/asm/bootparam.h |  3 ++-
 arch/x86/kernel/setup.c               |  6 ++++++
 5 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
index 82fbdbc..a811210 100644
--- a/Documentation/x86/zero-page.txt
+++ b/Documentation/x86/zero-page.txt
@@ -30,6 +30,8 @@ Offset	Proto	Name		Meaning
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
 				(below)
+1EB/001	ALL     kbd_status      Numlock is enabled
+1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
 2D0/A00	ALL	e820_map	E820 memory map table
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b7d31ca..0f9ee6f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1695,6 +1695,19 @@ config EFI_MIXED
 
 	   If unsure, say N.
 
+config EFI_SECURE_BOOT_TRUSTED_KERNEL
+        def_bool n
+	depends on SECURITY_TRUSTED_KERNEL
+	depends on EFI
+	prompt "Automatically set trusted_kernel with UEFI Secure Boot"
+	---help---
+	  UEFI Secure Boot provides a mechanism for ensuring that the
+	  firmware will only load signed bootloaders and kernels. Certain
+	  use cases may also require that the kernel restrict any userspace
+	  mechanism that could insert untrusted code into the kernel.
+	  Say Y here to automatically enable trusted_kernel enforcement
+	  when a system boots with UEFI Secure Boot enabled.
+
 config SECCOMP
 	def_bool y
 	prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index ef17683..4def2aa 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -12,6 +12,7 @@
 #include <asm/efi.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/bootparam_utils.h>
 
 #include "../string.h"
 #include "eboot.h"
@@ -1030,6 +1031,36 @@ void setup_graphics(struct boot_params *boot_params)
 	}
 }
 
+static int get_secure_boot(void)
+{
+	u8 sb, setup;
+	unsigned long datasize = sizeof(sb);
+	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+	efi_status_t status;
+
+	status = efi_call_phys5(sys_table->runtime->get_variable,
+				L"SecureBoot", &var_guid, NULL, &datasize, &sb);
+
+	if (status != EFI_SUCCESS)
+		return 0;
+
+	if (sb == 0)
+		return 0;
+
+
+	status = efi_call_phys5(sys_table->runtime->get_variable,
+				L"SetupMode", &var_guid, NULL, &datasize,
+				&setup);
+
+	if (status != EFI_SUCCESS)
+		return 0;
+
+	if (setup == 1)
+		return 0;
+
+	return 1;
+}
+
 /*
  * Because the x86 boot code expects to be passed a boot_params we
  * need to create one ourselves (usually the bootloader would create
@@ -1406,6 +1437,8 @@ struct boot_params *efi_main(struct efi_config *c,
 	else
 		setup_boot_services32(efi_early);
 
+	boot_params->secure_boot = get_secure_boot();
+
 	setup_graphics(boot_params);
 
 	setup_efi_pci(boot_params);
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 44e6dd7..3ddf415 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -134,7 +134,8 @@ struct boot_params {
 	__u8  eddbuf_entries;				/* 0x1e9 */
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
 	__u8  kbd_status;				/* 0x1eb */
-	__u8  _pad5[3];					/* 0x1ec */
+	__u8  secure_boot;				/* 0x1ec */
+	__u8  _pad5[2];					/* 0x1ed */
 	/*
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
 	 *
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 98dc931..980e308 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -50,6 +50,7 @@
 #include <linux/init_ohci1394_dma.h>
 #include <linux/kvm_para.h>
 #include <linux/dma-contiguous.h>
+#include <linux/security.h>
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -1165,6 +1166,11 @@ void __init setup_arch(char **cmdline_p)
 
 	io_delay_init();
 
+#ifdef CONFIG_EFI_SECURE_BOOT_TRUSTED_KERNEL
+	if (boot_params.secure_boot)
+		set_trusted_kernel(true);
+#endif
+
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (11 preceding siblings ...)
  2015-03-13 21:38 ` [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode Matthew Garrett
@ 2015-03-15  1:53 ` Matthew Garrett
  2015-03-16 14:45 ` One Thousand Gnomes
  13 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-15  1:53 UTC (permalink / raw)
  To: linux-security-module
  Cc: james.l.morris, serge, linux-kernel, keescook, hpa, gnomes

I've had some feedback on a couple of these, so I'll repost a new 
version within the next couple of days. Please hold off review until 
then.

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
                   ` (12 preceding siblings ...)
  2015-03-15  1:53 ` Trusted kernel patchset Matthew Garrett
@ 2015-03-16 14:45 ` One Thousand Gnomes
  2015-03-16 18:15   ` Matthew Garrett
  13 siblings, 1 reply; 30+ messages in thread
From: One Thousand Gnomes @ 2015-03-16 14:45 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: linux-security-module, james.l.morris, serge, linux-kernel,
	keescook, hpa

On Fri, 13 Mar 2015 11:38:16 -1000
Matthew Garrett <matthew.garrett@nebula.com> wrote:

> 4) Used the word "measured"
> 
> Nothing is being measured.

Nothing is being trusted either. It's simple ensuring you probably have
the same holes as before.

Also the boot loader should be measuring the kernel before it runs it,
thats how it knows the signature is correct.

On other points:

- your sysfs node is useless. I can mount over it to fake trusted and
  fool apps even in a supposedly "trusted" environment - it has to be a
  syscall I think so anything sensitive can invoke it directly from
  statically bound code and get a true answer.

- there are devices that do things triggered on read cycles. It might not
  be a bad idea to lock down reading mem and kmem too

- All suspend/resumes allow modifying the kernel. I can boot Linux
  suspend, boot windows, modify the Linux restore image, boot Linux and
  own the box. You would need to sign the resume image somehow I think or
  just disable all suspend/resume

- Why pick on ASUS WMI - every magical firmware interface has this
  property, and given how bad most firmware is I'd be more worried about
  access to things like UEFI services or straight forward ACPI methods.
  Also consider user access to GPIO pins. You can do some very
  interesting things on certain machines with those, such as glitching
  device power rails for a few microseconds.

I think this looks a lot better. It's still security theatre but fixing
that requires actually fixing the rest of the kernel too.

What you don't document is the assumption about how the kernel boot
parameters are handled. A large number of boot parameters allow arbitrary
I/O access or allow code execution if used with skill and cunning.

Alan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 14:45 ` One Thousand Gnomes
@ 2015-03-16 18:15   ` Matthew Garrett
  2015-03-16 20:07     ` One Thousand Gnomes
                       ` (3 more replies)
  0 siblings, 4 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-16 18:15 UTC (permalink / raw)
  To: gnomes
  Cc: keescook, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4112 bytes --]

On Mon, 2015-03-16 at 14:45 +0000, One Thousand Gnomes wrote:
> On Fri, 13 Mar 2015 11:38:16 -1000
> Matthew Garrett <matthew.garrett@nebula.com> wrote:
> 
> > 4) Used the word "measured"
> > 
> > Nothing is being measured.
> 
> Nothing is being trusted either. It's simple ensuring you probably have
> the same holes as before.
>
> Also the boot loader should be measuring the kernel before it runs it,
> thats how it knows the signature is correct.

That's one implementation. Another is the kernel being stored on
non-volatile media.

> On other points:
> 
> - your sysfs node is useless. I can mount over it to fake trusted and
>   fool apps even in a supposedly "trusted" environment - it has to be a
>   syscall I think so anything sensitive can invoke it directly from
>   statically bound code and get a true answer.

The sysfs node isn't intended to be used as a mechanism for userspace to
determine whether the kernel is trustworthy - there's clearly no way to
do that, since anyone able to launch an untrusted kernel can simply
modify it so that it lies there. It exists so that people deploying some
form of trusted boot chain can enable the lockdowns while still within
the trusted codebase. If you want to prove trustworthiness then you're
still going to need something like TPM-based attestation.

> - there are devices that do things triggered on read cycles. It might not
>   be a bad idea to lock down reading mem and kmem too

Yeah, at the very least doing that for anything mapped as a device is
entirely reasonable. Let me look at that.

> - All suspend/resumes allow modifying the kernel. I can boot Linux
>   suspend, boot windows, modify the Linux restore image, boot Linux and
>   own the box. You would need to sign the resume image somehow I think or
>   just disable all suspend/resume

I'm kind of torn on this - yes, there are deployment scenarios where
hibernation can be used to circumvent the restrictions, but there are
also scenarios where that can be avoided (eg, the bootloader verifies
some state with respect to the hibernation image).

> - Why pick on ASUS WMI - every magical firmware interface has this
>   property, and given how bad most firmware is I'd be more worried about
>   access to things like UEFI services or straight forward ACPI methods.

The ASUS WMI driver basically allows the execution of an entirely
unknown set of SMI calls, whereas all the other drivers execute a
curated subset of functions. Specific platforms may have specific bugs,
but in general we control access to firmware calls quite strictly.

>   Also consider user access to GPIO pins. You can do some very
>   interesting things on certain machines with those, such as glitching
>   device power rails for a few microseconds.

Good point. In general there's also the risk that GPIOs may be used for
features like TPM physical presence detection, so exposing those to
userspace does seem like a bad idea.

> What you don't document is the assumption about how the kernel boot
> parameters are handled. A large number of boot parameters allow arbitrary
> I/O access or allow code execution if used with skill and cunning.

Things that spring to mind here:

1) The ability to disable IOMMUs (some handwaving about the number of
machines that still don't have IOMMUs because security is a perfectly
reasonable thing to perform product differentiation on I guess?)
2) Your previous concerns about being able to manipulate the memory map
in hostile ways
3) Drivers that allow users to tell the kernel devices exist at
arbitrary memory addresses and then benefit from probe routines that
write blindly

Are there any other categories you're worried about? I have made an
effort to audit the generic kernel options and the only ones I'm
especially worried about in category (3) are the earlyprintk ones, but
obviously there's a bunch of old drivers that allow arbitrary addresses
to be passed and cleaning those up would be worth it.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 18:15   ` Matthew Garrett
@ 2015-03-16 20:07     ` One Thousand Gnomes
  2015-03-16 20:35     ` David Lang
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 30+ messages in thread
From: One Thousand Gnomes @ 2015-03-16 20:07 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: keescook, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa

> > Also the boot loader should be measuring the kernel before it runs it,
> > thats how it knows the signature is correct.
> 
> That's one implementation. Another is the kernel being stored on
> non-volatile media.

Same thing. One is just an optimisation ("const") 8)

> form of trusted boot chain can enable the lockdowns while still within
> the trusted codebase. If you want to prove trustworthiness then you're
> still going to need something like TPM-based attestation.

Makes sense.

On hibernate I think eventually it has to come down to the bootloader
and TPM signatures but to an extent it depends if you are getting into
the territory of protecting a machine from its supposed owner, or just
from passing malware.

> > What you don't document is the assumption about how the kernel boot
> > parameters are handled. A large number of boot parameters allow arbitrary
> > I/O access or allow code execution if used with skill and cunning.
> 
> Things that spring to mind here:

Ok I was more assuming it was going to be "the bootloader only allows you
to do ..." 

> 1) The ability to disable IOMMUs (some handwaving about the number of
> machines that still don't have IOMMUs because security is a perfectly
> reasonable thing to perform product differentiation on I guess?)
> 2) Your previous concerns about being able to manipulate the memory map
> in hostile ways
> 3) Drivers that allow users to tell the kernel devices exist at
> arbitrary memory addresses and then benefit from probe routines that
> write blindly

That's the main one

4) firewire and other interfaces that allow you to leave debug features
enabled. Firewire is the obvious one to me.

5) Manipulating firmware (acpi table replacements, alternative and extra
devicetree nodes etc)

> especially worried about in category (3) are the earlyprintk ones, but
> obviously there's a bunch of old drivers that allow arbitrary addresses
> to be passed and cleaning those up would be worth it.

When you get to devicetree or non x86 stuff there are quite a few modern
ones that do pretty much the same I think.

Alan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 18:15   ` Matthew Garrett
  2015-03-16 20:07     ` One Thousand Gnomes
@ 2015-03-16 20:35     ` David Lang
  2015-03-16 20:57       ` One Thousand Gnomes
  2015-03-16 21:11       ` Matthew Garrett
  2015-03-16 21:29     ` Kees Cook
  2015-03-16 21:54     ` Jiri Kosina
  3 siblings, 2 replies; 30+ messages in thread
From: David Lang @ 2015-03-16 20:35 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: gnomes, keescook, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa

On Mon, 16 Mar 2015, Matthew Garrett wrote:

> On Mon, 2015-03-16 at 14:45 +0000, One Thousand Gnomes wrote:
>> On Fri, 13 Mar 2015 11:38:16 -1000
>> Matthew Garrett <matthew.garrett@nebula.com> wrote:
>>
>>> 4) Used the word "measured"
>>>
>>> Nothing is being measured.
>>
>> Nothing is being trusted either. It's simple ensuring you probably have
>> the same holes as before.
>>
>> Also the boot loader should be measuring the kernel before it runs it,
>> thats how it knows the signature is correct.
>
> That's one implementation. Another is the kernel being stored on
> non-volatile media.

Anything that encourages deploying systems that can't be upgraded to fix bugs 
that are discovered is a problem.

This is an issue that the Internet of Things folks are just starting to notice, 
and it's only going to get worse before it gets better.

How do you patch bugs on your non-volitile media? What keeps that mechansim from 
being abused.

David Lang

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 20:35     ` David Lang
@ 2015-03-16 20:57       ` One Thousand Gnomes
  2015-03-16 21:11       ` Matthew Garrett
  1 sibling, 0 replies; 30+ messages in thread
From: One Thousand Gnomes @ 2015-03-16 20:57 UTC (permalink / raw)
  To: David Lang
  Cc: Matthew Garrett, keescook, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa

> Anything that encourages deploying systems that can't be upgraded to fix bugs 
> that are discovered is a problem.
> 
> This is an issue that the Internet of Things folks are just starting to notice, 
> and it's only going to get worse before it gets better.
> 
> How do you patch bugs on your non-volitile media? What keeps that mechansim from 
> being abused.

One example is flash memory that can only be written by a special part of
the system which verifies the signatures then writes the data to the
flash. That to most intents and purposes is "non volatile". In some
environments jumpers or particular sequences of holding buttons in may
deal with it - if they are handled such that malicious software cannot do
it.

Some systems go further than that and do measure the boot path - so
modern x86 firmware will typically not allow you to flash the BIOS
firmware except from measured firmware, and won't run the result without
checking signatures. Not everything goes that far.

The IoT and general security underfunding is a social and economic issue
however, and isn't soluble by technical means. It will be fixed when the
lawmakers finally stop listening to the lobbyists, or when something
*really bad* happens and they extend liability law to paid services and
licensed components of sold products on the back of either some massive
disruptive hack or serious loss of life.

Alan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 20:35     ` David Lang
  2015-03-16 20:57       ` One Thousand Gnomes
@ 2015-03-16 21:11       ` Matthew Garrett
  1 sibling, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-16 21:11 UTC (permalink / raw)
  To: david
  Cc: keescook, linux-kernel, james.l.morris, gnomes, serge,
	linux-security-module, hpa

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 827 bytes --]

On Mon, 2015-03-16 at 13:35 -0700, David Lang wrote:
> On Mon, 16 Mar 2015, Matthew Garrett wrote:
> > That's one implementation. Another is the kernel being stored on
> > non-volatile media.
> 
> Anything that encourages deploying systems that can't be upgraded to fix bugs 
> that are discovered is a problem.
> 
> This is an issue that the Internet of Things folks are just starting to notice, 
> and it's only going to get worse before it gets better.
> 
> How do you patch bugs on your non-volitile media? What keeps that mechansim from 
> being abused.

Nothing stops people from deploying kernels on non-volatile media right
now. This doesn't change anything.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 18:15   ` Matthew Garrett
  2015-03-16 20:07     ` One Thousand Gnomes
  2015-03-16 20:35     ` David Lang
@ 2015-03-16 21:29     ` Kees Cook
  2015-03-17 17:48       ` One Thousand Gnomes
  2015-03-17 20:22       ` Simon McVittie
  2015-03-16 21:54     ` Jiri Kosina
  3 siblings, 2 replies; 30+ messages in thread
From: Kees Cook @ 2015-03-16 21:29 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: gnomes, linux-kernel, james.l.morris, serge, linux-security-module, hpa

On Mon, Mar 16, 2015 at 11:15 AM, Matthew Garrett
<matthew.garrett@nebula.com> wrote:
> On Mon, 2015-03-16 at 14:45 +0000, One Thousand Gnomes wrote:
>> On Fri, 13 Mar 2015 11:38:16 -1000
>> Matthew Garrett <matthew.garrett@nebula.com> wrote:
>>
>> > 4) Used the word "measured"
>> >
>> > Nothing is being measured.
>>
>> Nothing is being trusted either. It's simple ensuring you probably have
>> the same holes as before.
>>
>> Also the boot loader should be measuring the kernel before it runs it,
>> thats how it knows the signature is correct.
>
> That's one implementation. Another is the kernel being stored on
> non-volatile media.

I really think "trusted" is the right term here. It's about as
accurate as possible for what this flag means. In the same way that
nothing is ever bug-free, nothing can be perfect. The word "measured"
isn't right for this series because it is a subset of "trusted". We
trust the kernel is some specific thing, trusted (to some level)
externally. It's trusted to be "known good". Some implementations can
even revoke that trust via a number of ways (roll-back protection,
e.g.), so it doesn't have to mean "trusted forever" either.

>> On other points:
>>
>> - your sysfs node is useless. I can mount over it to fake trusted and
>>   fool apps even in a supposedly "trusted" environment - it has to be a
>>   syscall I think so anything sensitive can invoke it directly from
>>   statically bound code and get a true answer.
>
> The sysfs node isn't intended to be used as a mechanism for userspace to
> determine whether the kernel is trustworthy - there's clearly no way to
> do that, since anyone able to launch an untrusted kernel can simply
> modify it so that it lies there. It exists so that people deploying some
> form of trusted boot chain can enable the lockdowns while still within
> the trusted codebase. If you want to prove trustworthiness then you're
> still going to need something like TPM-based attestation.

_Everything_ can be faked from userspace. I can ptrace-intercept
syscalls and fake out a return value too. Having it as an
informational tool has benefits for how a userspace tool may want to
react to discovering it can't fiddle with some blocked interface, for
example.

>> - there are devices that do things triggered on read cycles. It might not
>>   be a bad idea to lock down reading mem and kmem too
>
> Yeah, at the very least doing that for anything mapped as a device is
> entirely reasonable. Let me look at that.

I've always been creeped out that userspace and go examine PCI space. :)

>> - All suspend/resumes allow modifying the kernel. I can boot Linux
>>   suspend, boot windows, modify the Linux restore image, boot Linux and
>>   own the box. You would need to sign the resume image somehow I think or
>>   just disable all suspend/resume
>
> I'm kind of torn on this - yes, there are deployment scenarios where
> hibernation can be used to circumvent the restrictions, but there are
> also scenarios where that can be avoided (eg, the bootloader verifies
> some state with respect to the hibernation image).

We have no system yet to validate hibernation images, so it's correct
to disable hibernation images that lack validation (which is all of
them).

>> - Why pick on ASUS WMI - every magical firmware interface has this
>>   property, and given how bad most firmware is I'd be more worried about
>>   access to things like UEFI services or straight forward ACPI methods.
>
> The ASUS WMI driver basically allows the execution of an entirely
> unknown set of SMI calls, whereas all the other drivers execute a
> curated subset of functions. Specific platforms may have specific bugs,
> but in general we control access to firmware calls quite strictly.

And if we find more terrible interfaces, we add them to this "blacklist".

>>   Also consider user access to GPIO pins. You can do some very
>>   interesting things on certain machines with those, such as glitching
>>   device power rails for a few microseconds.
>
> Good point. In general there's also the risk that GPIOs may be used for
> features like TPM physical presence detection, so exposing those to
> userspace does seem like a bad idea.

Possibly the SPI driver too.

>> What you don't document is the assumption about how the kernel boot
>> parameters are handled. A large number of boot parameters allow arbitrary
>> I/O access or allow code execution if used with skill and cunning.
>
> Things that spring to mind here:
>
> 1) The ability to disable IOMMUs (some handwaving about the number of
> machines that still don't have IOMMUs because security is a perfectly
> reasonable thing to perform product differentiation on I guess?)
> 2) Your previous concerns about being able to manipulate the memory map
> in hostile ways
> 3) Drivers that allow users to tell the kernel devices exist at
> arbitrary memory addresses and then benefit from probe routines that
> write blindly
>
> Are there any other categories you're worried about? I have made an
> effort to audit the generic kernel options and the only ones I'm
> especially worried about in category (3) are the earlyprintk ones, but
> obviously there's a bunch of old drivers that allow arbitrary addresses
> to be passed and cleaning those up would be worth it.

I still say that a trusted kernel includes its boot parameters. This
is true in the Chrome OS case, as parameters are part of the verified
kernel boot block, but it could be a concern for someone who has built
a grub-based CDROM or something and didn't lock the grub menu down. I
think, though, that those things need to be part of documentation, not
code, as this point.

-Kees

-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 09/12] uswsusp: Disable when trusted_kernel is true
  2015-03-13 21:38 ` [PATCH 09/12] uswsusp: Disable when trusted_kernel is true Matthew Garrett
@ 2015-03-16 21:36   ` Kees Cook
  2015-03-16 21:40     ` Matthew Garrett
  0 siblings, 1 reply; 30+ messages in thread
From: Kees Cook @ 2015-03-16 21:36 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: linux-security-module, James Morris, Serge E. Hallyn, LKML,
	H. Peter Anvin, gnomes

On Fri, Mar 13, 2015 at 2:38 PM, Matthew Garrett
<matthew.garrett@nebula.com> wrote:
> uswsusp allows a user process to dump and then restore kernel state, which
> makes it possible to modify the running kernel. Disable this if
> trusted_kernel is true.
>
> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
> ---
>  kernel/power/user.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/power/user.c b/kernel/power/user.c
> index 526e891..43b7b59 100644
> --- a/kernel/power/user.c
> +++ b/kernel/power/user.c
> @@ -24,6 +24,7 @@
>  #include <linux/console.h>
>  #include <linux/cpu.h>
>  #include <linux/freezer.h>
> +#include <linux/security.h>
>
>  #include <asm/uaccess.h>
>
> @@ -49,7 +50,7 @@ static int snapshot_open(struct inode *inode, struct file *filp)
>         struct snapshot_data *data;
>         int error;
>
> -       if (!hibernation_available())
> +       if (get_trusted_kernel() || !hibernation_available())
>                 return -EPERM;
>
>         lock_system_sleep();
> --
> 2.1.0
>

Perhaps this should be folded into the hibernation_available check
instead of added as an "||" check here?

-Kees


-- 
Kees Cook
Chrome OS Security

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 09/12] uswsusp: Disable when trusted_kernel is true
  2015-03-16 21:36   ` Kees Cook
@ 2015-03-16 21:40     ` Matthew Garrett
  0 siblings, 0 replies; 30+ messages in thread
From: Matthew Garrett @ 2015-03-16 21:40 UTC (permalink / raw)
  To: keescook
  Cc: hpa, linux-kernel, james.l.morris, serge, linux-security-module, gnomes

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 486 bytes --]

On Mon, 2015-03-16 at 14:36 -0700, Kees Cook wrote:

> Perhaps this should be folded into the hibernation_available check
> instead of added as an "||" check here?

That would end up covering in-kernel hibernation as well, which was more
than I was aiming to do. But it's plausibly a justifiable implementation
at the moment.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 18:15   ` Matthew Garrett
                       ` (2 preceding siblings ...)
  2015-03-16 21:29     ` Kees Cook
@ 2015-03-16 21:54     ` Jiri Kosina
  2015-03-18 13:24       ` joeyli
  3 siblings, 1 reply; 30+ messages in thread
From: Jiri Kosina @ 2015-03-16 21:54 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: gnomes, keescook, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa, jlee

On Mon, 16 Mar 2015, Matthew Garrett wrote:

> > - All suspend/resumes allow modifying the kernel. I can boot Linux
> >   suspend, boot windows, modify the Linux restore image, boot Linux and
> >   own the box. You would need to sign the resume image somehow I think or
> >   just disable all suspend/resume
> 
> I'm kind of torn on this - yes, there are deployment scenarios where
> hibernation can be used to circumvent the restrictions, but there are
> also scenarios where that can be avoided (eg, the bootloader verifies
> some state with respect to the hibernation image).

[ adding Joey to CC ]

Just for completness -- there is a way around this:

	https://lkml.org/lkml/2013/9/14/183

The series is not really the optimal one, as Alan Stern later figured out 
that symmetric cryptography is strong enough to achieve the same goal, but 
I am not sure whether Joey implemented that idea already.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 21:29     ` Kees Cook
@ 2015-03-17 17:48       ` One Thousand Gnomes
  2015-03-17 20:22       ` Simon McVittie
  1 sibling, 0 replies; 30+ messages in thread
From: One Thousand Gnomes @ 2015-03-17 17:48 UTC (permalink / raw)
  To: Kees Cook
  Cc: Matthew Garrett, linux-kernel, james.l.morris, serge,
	linux-security-module, hpa

> I really think "trusted" is the right term here. It's about as
> accurate as possible for what this flag means. In the same way that

verified perhaps - however its bikeshedding territory and I don't care
that much 8)

> > I'm kind of torn on this - yes, there are deployment scenarios where
> > hibernation can be used to circumvent the restrictions, but there are
> > also scenarios where that can be avoided (eg, the bootloader verifies
> > some state with respect to the hibernation image).
> 
> We have no system yet to validate hibernation images, so it's correct
> to disable hibernation images that lack validation (which is all of
> them).

Agreed.

> > Good point. In general there's also the risk that GPIOs may be used for
> > features like TPM physical presence detection, so exposing those to
> > userspace does seem like a bad idea.
> 
> Possibly the SPI driver too.

SPI and I2C from userspace are both good candidates. The devices are not
DMA but often it does include power management ICs. On many phones it
would however break assorted evilware binary userspace drivers not that I
care.

> I still say that a trusted kernel includes its boot parameters. This
> is true in the Chrome OS case, as parameters are part of the verified
> kernel boot block, but it could be a concern for someone who has built
> a grub-based CDROM or something and didn't lock the grub menu down. I
> think, though, that those things need to be part of documentation, not
> code, as this point.

I think we need to clearly document the assumption. Who owns validating
boot parameters, is there an assumption that boot parameters are safe, do
we need a whitelist to make it user friendly (eg turning off rhgb quiet
and adding debug init=/bin/sh every time systemd s**ts itself).

Alan

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 21:29     ` Kees Cook
  2015-03-17 17:48       ` One Thousand Gnomes
@ 2015-03-17 20:22       ` Simon McVittie
  2015-03-17 20:42         ` Matthew Garrett
  1 sibling, 1 reply; 30+ messages in thread
From: Simon McVittie @ 2015-03-17 20:22 UTC (permalink / raw)
  To: Kees Cook, Matthew Garrett
  Cc: gnomes, linux-kernel, james.l.morris, serge, linux-security-module, hpa

On 16/03/15 21:29, Kees Cook wrote:
> I really think "trusted" is the right term here. It's about as
> accurate as possible for what this flag means.

A subtlety that might make this clearer: there isn't really such a thing
as "trusted" in isolation, only "trusted by..." a specific other party;
and in this case, as far as I can see, the intended meaning is  that
lower layers (firmware and/or bootloader) have been configured to trust
this particular kernel.

It doesn't mean "user-space can trust me not to do bad things", because
any kernel, malicious or otherwise, could indeed easily claim that; and
if it is lying, what is user-space going to do about it anyway? Rather,
it means "the firmware is trusting me not to do things it would consider
bad".

I assume the intention isn't that it will make privileged bits of
userland be more careful to avoid breaking this trust assumption,
because the point of this patchset seems to be to make it impossible
(modulo bugs) for userland to do that.

Is the intention instead that it will make privileged bits of userland
more careful to avoid breaking the trust chain in ways that would "fail
safe" by refusing to boot?

-- 
Simon McVittie
Collabora Ltd. <http://www.collabora.com/>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-17 20:22       ` Simon McVittie
@ 2015-03-17 20:42         ` Matthew Garrett
  2015-03-18 11:34           ` Simon McVittie
  0 siblings, 1 reply; 30+ messages in thread
From: Matthew Garrett @ 2015-03-17 20:42 UTC (permalink / raw)
  To: simon.mcvittie
  Cc: keescook, linux-kernel, james.l.morris, gnomes, serge,
	linux-security-module, hpa

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 579 bytes --]

On Tue, 2015-03-17 at 20:22 +0000, Simon McVittie wrote:

> Is the intention instead that it will make privileged bits of userland
> more careful to avoid breaking the trust chain in ways that would "fail
> safe" by refusing to boot?

Not really. It's intended to avoid the situation where privileged
userspace is able to modify the running kernel to an extent that's
broadly equivalent to booting an arbitrary kernel.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-17 20:42         ` Matthew Garrett
@ 2015-03-18 11:34           ` Simon McVittie
  0 siblings, 0 replies; 30+ messages in thread
From: Simon McVittie @ 2015-03-18 11:34 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: keescook, linux-kernel, james.l.morris, gnomes, serge,
	linux-security-module, hpa

On 17/03/15 20:42, Matthew Garrett wrote:
> On Tue, 2015-03-17 at 20:22 +0000, Simon McVittie wrote:
>> Is the intention instead that it will make privileged bits of userland
>> more careful to avoid breaking the trust chain in ways that would "fail
>> safe" by refusing to boot?
> 
> Not really. It's intended to avoid the situation where privileged
> userspace is able to modify the running kernel to an extent that's
> broadly equivalent to booting an arbitrary kernel.

Sorry, I was imprecise about what I meant by "it". I understand that the
intention of the patchset as a whole is to prevent privileged userspace
from subverting the kernel; I was asking about the intention of the
ability to read from /sys/kernel/security/trusted_kernel.

-- 
Simon McVittie
Collabora Ltd. <http://www.collabora.com/>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Trusted kernel patchset
  2015-03-16 21:54     ` Jiri Kosina
@ 2015-03-18 13:24       ` joeyli
  0 siblings, 0 replies; 30+ messages in thread
From: joeyli @ 2015-03-18 13:24 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Matthew Garrett, gnomes, keescook, linux-kernel, james.l.morris,
	serge, linux-security-module, hpa

On Mon, Mar 16, 2015 at 10:54:54PM +0100, Jiri Kosina wrote:
> On Mon, 16 Mar 2015, Matthew Garrett wrote:
> 
> > > - All suspend/resumes allow modifying the kernel. I can boot Linux
> > >   suspend, boot windows, modify the Linux restore image, boot Linux and
> > >   own the box. You would need to sign the resume image somehow I think or
> > >   just disable all suspend/resume
> > 
> > I'm kind of torn on this - yes, there are deployment scenarios where
> > hibernation can be used to circumvent the restrictions, but there are
> > also scenarios where that can be avoided (eg, the bootloader verifies
> > some state with respect to the hibernation image).
> 
> [ adding Joey to CC ]
> 
> Just for completness -- there is a way around this:
> 
> 	https://lkml.org/lkml/2013/9/14/183
> 
> The series is not really the optimal one, as Alan Stern later figured out 
> that symmetric cryptography is strong enough to achieve the same goal, but 
> I am not sure whether Joey implemented that idea already.
> 
> -- 
> Jiri Kosina
> SUSE Labs

About the symmetric key edition, I developed a prototype the codes on github
are ugly and still need clear up. But it works for using HMAC to generate
signature and verify hibernate image.

There still has a situation need to solve:
 
There doesn't have enough random entropy for the FIRST TIME boot to generate
HMAC key in EFI stub.

And, I need implement a hash function in EFI stub, at least SHA1, to mess
entropies from difference sources (rdtsc, RdRand... not too many) for generating
new HMAC key. An other idea is sending a random seed from runtime random pool to
boot time to be one of the seed of next HMAC key.


Joey Lee

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode
  2015-03-13 21:38 ` [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode Matthew Garrett
@ 2015-04-22 11:36   ` Dan Carpenter
  0 siblings, 0 replies; 30+ messages in thread
From: Dan Carpenter @ 2015-04-22 11:36 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: linux-security-module, james.l.morris, serge, linux-kernel,
	keescook, hpa, gnomes

On Fri, Mar 13, 2015 at 11:38:28AM -1000, Matthew Garrett wrote:
> UEFI Secure Boot provides a mechanism for ensuring that the firmware will
> only load signed bootloaders and kernels. Certain use cases may also
> require that the kernel prevent userspace from inserting untrusted kernel
> code at runtime. Add a configuration option that enforces this automatically
> when enabled.
> 
> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
> ---
>  Documentation/x86/zero-page.txt       |  2 ++
>  arch/x86/Kconfig                      | 13 +++++++++++++
>  arch/x86/boot/compressed/eboot.c      | 33 +++++++++++++++++++++++++++++++++
>  arch/x86/include/uapi/asm/bootparam.h |  3 ++-
>  arch/x86/kernel/setup.c               |  6 ++++++
>  5 files changed, 56 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
> index 82fbdbc..a811210 100644
> --- a/Documentation/x86/zero-page.txt
> +++ b/Documentation/x86/zero-page.txt
> @@ -30,6 +30,8 @@ Offset	Proto	Name		Meaning
>  1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
>  1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
>  				(below)
> +1EB/001	ALL     kbd_status      Numlock is enabled

This line looks like it was included by mistake?

> +1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2015-04-22 11:37 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-13 21:38 Trusted kernel patchset Matthew Garrett
2015-03-13 21:38 ` [PATCH 01/12] Add support for indicating that the booted kernel is externally trusted Matthew Garrett
2015-03-13 21:38 ` [PATCH 02/12] Enforce module signatures when trusted kernel is enabled Matthew Garrett
2015-03-13 21:38 ` [PATCH 03/12] PCI: Lock down register access when trusted_kernel is true Matthew Garrett
2015-03-13 21:38 ` [PATCH 04/12] x86: Lock down IO port " Matthew Garrett
2015-03-13 21:38 ` [PATCH 05/12] Restrict /dev/mem and /dev/kmem " Matthew Garrett
2015-03-13 21:38 ` [PATCH 06/12] acpi: Limit access to custom_method if " Matthew Garrett
2015-03-13 21:38 ` [PATCH 07/12] acpi: Ignore acpi_rsdp kernel parameter when " Matthew Garrett
2015-03-13 21:38 ` [PATCH 08/12] kexec: Disable loading of unverified images Matthew Garrett
2015-03-13 21:38 ` [PATCH 09/12] uswsusp: Disable when trusted_kernel is true Matthew Garrett
2015-03-16 21:36   ` Kees Cook
2015-03-16 21:40     ` Matthew Garrett
2015-03-13 21:38 ` [PATCH 10/12] x86: Restrict MSR access " Matthew Garrett
2015-03-13 21:38 ` [PATCH 11/12] asus-wmi: Restrict debugfs interface " Matthew Garrett
2015-03-13 21:38 ` [PATCH 12/12] Add option to automatically set trusted_kernel when in Secure Boot mode Matthew Garrett
2015-04-22 11:36   ` Dan Carpenter
2015-03-15  1:53 ` Trusted kernel patchset Matthew Garrett
2015-03-16 14:45 ` One Thousand Gnomes
2015-03-16 18:15   ` Matthew Garrett
2015-03-16 20:07     ` One Thousand Gnomes
2015-03-16 20:35     ` David Lang
2015-03-16 20:57       ` One Thousand Gnomes
2015-03-16 21:11       ` Matthew Garrett
2015-03-16 21:29     ` Kees Cook
2015-03-17 17:48       ` One Thousand Gnomes
2015-03-17 20:22       ` Simon McVittie
2015-03-17 20:42         ` Matthew Garrett
2015-03-18 11:34           ` Simon McVittie
2015-03-16 21:54     ` Jiri Kosina
2015-03-18 13:24       ` joeyli

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).