Add Matthew Garrett's securelevel patchset in preparation for Secure Boot support
This commit is contained in:
parent
ea7af96b4d
commit
7321950826
|
@ -8,6 +8,8 @@ linux (4.5-1~exp2) UNRELEASED; urgency=medium
|
|||
write support
|
||||
* Merge linux-tools source package into linux
|
||||
(Closes: #550379, #573483, #816500)
|
||||
* Add Matthew Garrett's securelevel patchset in preparation for Secure Boot
|
||||
support (see Documentation/security/securelevel.txt)
|
||||
|
||||
-- Ben Hutchings <ben@decadent.org.uk> Fri, 25 Mar 2016 13:43:57 +0000
|
||||
|
||||
|
|
|
@ -6655,6 +6655,7 @@ CONFIG_SECURITY=y
|
|||
CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_NETWORK_XFRM=y
|
||||
# CONFIG_SECURITY_PATH is not set
|
||||
CONFIG_SECURITY_SECURELEVEL=y
|
||||
# CONFIG_INTEL_TXT is not set
|
||||
CONFIG_LSM_MMAP_MIN_ADDR=32768
|
||||
## choice: Default security module
|
||||
|
|
|
@ -54,6 +54,7 @@ CONFIG_X86_SMAP=y
|
|||
CONFIG_X86_INTEL_MPX=y
|
||||
CONFIG_EFI=y
|
||||
CONFIG_EFI_STUB=y
|
||||
CONFIG_EFI_SECURE_BOOT_SECURELEVEL=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_CRASH_DUMP=y
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
From: Linn Crosetto <linn@hpe.com>
|
||||
Date: Fri, 4 Mar 2016 16:08:24 -0700
|
||||
Subject: [16/18] acpi: Disable ACPI table override if securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/a4a5ed2835e8ea042868b7401dced3f517cafa76
|
||||
|
||||
From the kernel documentation (initrd_table_override.txt):
|
||||
|
||||
If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible
|
||||
to override nearly any ACPI table provided by the BIOS with an
|
||||
instrumented, modified one.
|
||||
|
||||
When securelevel is set, the kernel should disallow any unauthenticated
|
||||
changes to kernel space. ACPI tables contain code invoked by the kernel, so
|
||||
do not allow ACPI tables to be overridden if securelevel is set.
|
||||
|
||||
Signed-off-by: Linn Crosetto <linn@hpe.com>
|
||||
---
|
||||
arch/x86/kernel/setup.c | 12 ++++++------
|
||||
drivers/acpi/osl.c | 6 ++++++
|
||||
2 files changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/arch/x86/kernel/setup.c
|
||||
+++ b/arch/x86/kernel/setup.c
|
||||
@@ -1136,6 +1136,12 @@ void __init setup_arch(char **cmdline_p)
|
||||
/* Allocate bigger log buffer */
|
||||
setup_log_buf(1);
|
||||
|
||||
+#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
|
||||
+ if (boot_params.secure_boot) {
|
||||
+ set_securelevel(1);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
reserve_initrd();
|
||||
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
|
||||
@@ -1146,12 +1152,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
io_delay_init();
|
||||
|
||||
-#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
|
||||
- if (boot_params.secure_boot) {
|
||||
- set_securelevel(1);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* Parse the ACPI tables for possible boot-time SMP configuration.
|
||||
*/
|
||||
--- a/drivers/acpi/osl.c
|
||||
+++ b/drivers/acpi/osl.c
|
||||
@@ -698,6 +698,12 @@ void __init acpi_initrd_override(void *d
|
||||
if (table_nr == 0)
|
||||
return;
|
||||
|
||||
+ if (get_securelevel() > 0) {
|
||||
+ pr_notice(PREFIX
|
||||
+ "securelevel enabled, ignoring table override\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
acpi_tables_addr =
|
||||
memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT,
|
||||
all_tables_size, PAGE_SIZE);
|
|
@ -0,0 +1,45 @@
|
|||
From: Linn Crosetto <linn@hpe.com>
|
||||
Date: Wed, 16 Mar 2016 14:43:33 -0600
|
||||
Subject: [17/18] acpi: Disable APEI error injection if securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/d7a6be58edc01b1c66ecd8fcc91236bfbce0a420
|
||||
|
||||
ACPI provides an error injection mechanism, EINJ, for debugging and testing
|
||||
the ACPI Platform Error Interface (APEI) and other RAS features. If
|
||||
supported by the firmware, ACPI specification 5.0 and later provide for a
|
||||
way to specify a physical memory address to which to inject the error.
|
||||
|
||||
Injecting errors through EINJ can produce errors which to the platform are
|
||||
indistinguishable from real hardware errors. This can have undesirable
|
||||
side-effects, such as causing the platform to mark hardware as needing
|
||||
replacement.
|
||||
|
||||
While it does not provide a method to load unauthenticated privileged code,
|
||||
the effect of these errors may persist across reboots and affect trust in
|
||||
the underlying hardware, so disable error injection through EINJ if
|
||||
securelevel is set.
|
||||
|
||||
Signed-off-by: Linn Crosetto <linn@hpe.com>
|
||||
---
|
||||
drivers/acpi/apei/einj.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/acpi/apei/einj.c
|
||||
+++ b/drivers/acpi/apei/einj.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/nmi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
+#include <linux/security.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "apei-internal.h"
|
||||
@@ -521,6 +522,9 @@ static int einj_error_inject(u32 type, u
|
||||
int rc;
|
||||
unsigned long pfn;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
/* If user manually set "flags", make sure it is legal */
|
||||
if (flags && (flags &
|
||||
~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
|
|
@ -0,0 +1,36 @@
|
|||
From: Josh Boyer <jwboyer@redhat.com>
|
||||
Date: Mon, 25 Jun 2012 19:57:30 -0400
|
||||
Subject: [07/18] acpi: Ignore acpi_rsdp kernel parameter when securelevel is
|
||||
set
|
||||
Origin: https://github.com/mjg59/linux/commit/9524fadac774fbe85e2ac6abe7b957b1750c7e36
|
||||
|
||||
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 securelevel is set.
|
||||
|
||||
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 814d5f83b75e..242ca81bb606 100644
|
||||
--- a/drivers/acpi/osl.c
|
||||
+++ b/drivers/acpi/osl.c
|
||||
@@ -40,6 +40,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>
|
||||
@@ -254,7 +255,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_securelevel() <= 0))
|
||||
return acpi_rsdp;
|
||||
#endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Mar 2012 08:39:37 -0500
|
||||
Subject: [06/18] acpi: Limit access to custom_method if securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/3cdc48db6b6d1b3cc1412d428389889f74cafe83
|
||||
|
||||
custom_method effectively allows arbitrary access to system memory, making
|
||||
it possible for an attacker to modify the kernel at runtime. Prevent this
|
||||
if securelevel has been set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
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 c68e72414a67..359f45d54543 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_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (!(*ppos)) {
|
||||
/* parse the table header to get the table length */
|
||||
if (count <= sizeof(struct acpi_table_header))
|
208
debian/patches/features/all/securelevel/add-bsd-style-securelevel-support.patch
vendored
Normal file
208
debian/patches/features/all/securelevel/add-bsd-style-securelevel-support.patch
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Aug 2013 17:58:15 -0400
|
||||
Subject: [01/18] Add BSD-style securelevel support
|
||||
Origin: https://github.com/mjg59/linux/commit/058b8ddfe86dc90268f6dbe0ffed29ec46f1fafa
|
||||
|
||||
Provide a coarse-grained runtime configuration option for restricting
|
||||
userspace's ability to modify the running kernel.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
Documentation/security/securelevel.txt | 23 +++++++
|
||||
include/linux/security.h | 8 +++
|
||||
security/Kconfig | 8 +++
|
||||
security/Makefile | 1 +
|
||||
security/securelevel.c | 116 +++++++++++++++++++++++++++++++++
|
||||
5 files changed, 156 insertions(+)
|
||||
create mode 100644 Documentation/security/securelevel.txt
|
||||
create mode 100644 security/securelevel.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Documentation/security/securelevel.txt
|
||||
@@ -0,0 +1,23 @@
|
||||
+Linux securelevel interface
|
||||
+---------------------------
|
||||
+
|
||||
+The Linux securelevel interface (inspired by the BSD securelevel interface)
|
||||
+is a runtime mechanism for configuring coarse-grained kernel-level security
|
||||
+restrictions. It provides a runtime configuration variable at
|
||||
+/sys/kernel/security/securelevel which can be written to by root. The
|
||||
+following values are supported:
|
||||
+
|
||||
+-1: Permanently insecure mode. This level is equivalent to level 0, but once
|
||||
+ set cannot be changed.
|
||||
+
|
||||
+0: Insecure mode (default). This level imposes no additional kernel
|
||||
+ restrictions.
|
||||
+
|
||||
+1: Secure mode. If set, 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.
|
||||
+
|
||||
+Once the securelevel value is increased, it may not be decreased.
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -1589,6 +1589,14 @@ static inline void security_audit_rule_f
|
||||
#endif /* CONFIG_SECURITY */
|
||||
#endif /* CONFIG_AUDIT */
|
||||
|
||||
+#ifdef CONFIG_SECURITY_SECURELEVEL
|
||||
+extern int get_securelevel(void);
|
||||
+extern int set_securelevel(int new_securelevel);
|
||||
+#else
|
||||
+static inline int get_securelevel(void) { return 0; }
|
||||
+static inline int set_securelevel(int new_securelevel) { return 0; }
|
||||
+#endif /* CONFIG_SECURELEVEL */
|
||||
+
|
||||
#ifdef CONFIG_SECURITYFS
|
||||
|
||||
extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
|
||||
--- a/security/Kconfig
|
||||
+++ b/security/Kconfig
|
||||
@@ -93,6 +93,14 @@ config SECURITY_PATH
|
||||
implement pathname based access controls.
|
||||
If you are unsure how to answer this question, answer N.
|
||||
|
||||
+config SECURITY_SECURELEVEL
|
||||
+ bool "Securelevel kernel restriction interface"
|
||||
+ depends on SECURITY
|
||||
+ help
|
||||
+ This enables support for adding a set of additional kernel security
|
||||
+ restrictions at runtime. See Documentation/security/securelevel.txt
|
||||
+ for further information.
|
||||
+
|
||||
config INTEL_TXT
|
||||
bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
|
||||
depends on HAVE_INTEL_TXT
|
||||
--- a/security/Makefile
|
||||
+++ b/security/Makefile
|
||||
@@ -16,6 +16,7 @@ obj-$(CONFIG_MMU) += min_addr.o
|
||||
# Object file lists
|
||||
obj-$(CONFIG_SECURITY) += security.o
|
||||
obj-$(CONFIG_SECURITYFS) += inode.o
|
||||
+obj-$(CONFIG_SECURITY_SECURELEVEL) += securelevel.o
|
||||
obj-$(CONFIG_SECURITY_SELINUX) += selinux/
|
||||
obj-$(CONFIG_SECURITY_SMACK) += smack/
|
||||
obj-$(CONFIG_AUDIT) += lsm_audit.o
|
||||
--- /dev/null
|
||||
+++ b/security/securelevel.c
|
||||
@@ -0,0 +1,116 @@
|
||||
+/*
|
||||
+ * securelevel.c - support for generic kernel lockdown
|
||||
+ *
|
||||
+ * Copyright Nebula, Inc <mjg59@srcf.ucam.org>
|
||||
+ *
|
||||
+ * 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 int securelevel;
|
||||
+
|
||||
+static DEFINE_SPINLOCK(securelevel_lock);
|
||||
+
|
||||
+#define MAX_SECURELEVEL 1
|
||||
+
|
||||
+int get_securelevel(void)
|
||||
+{
|
||||
+ return securelevel;
|
||||
+}
|
||||
+EXPORT_SYMBOL(get_securelevel);
|
||||
+
|
||||
+int set_securelevel(int new_securelevel)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ spin_lock(&securelevel_lock);
|
||||
+
|
||||
+ if ((securelevel == -1) || (new_securelevel < securelevel) ||
|
||||
+ (new_securelevel > MAX_SECURELEVEL)) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ securelevel = new_securelevel;
|
||||
+out:
|
||||
+ spin_unlock(&securelevel_lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL(set_securelevel);
|
||||
+
|
||||
+static ssize_t securelevel_read(struct file *filp, char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ char tmpbuf[12];
|
||||
+ ssize_t length;
|
||||
+
|
||||
+ length = scnprintf(tmpbuf, sizeof(tmpbuf), "%d", securelevel);
|
||||
+ return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
|
||||
+}
|
||||
+
|
||||
+static ssize_t securelevel_write(struct file *file, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ char *page = NULL;
|
||||
+ ssize_t length;
|
||||
+ int new_securelevel;
|
||||
+
|
||||
+ 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_securelevel) != 1)
|
||||
+ goto out;
|
||||
+
|
||||
+ length = set_securelevel(new_securelevel);
|
||||
+ if (length)
|
||||
+ goto out;
|
||||
+
|
||||
+ length = count;
|
||||
+out:
|
||||
+ free_page((unsigned long) page);
|
||||
+ return length;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations securelevel_fops = {
|
||||
+ .read = securelevel_read,
|
||||
+ .write = securelevel_write,
|
||||
+ .llseek = generic_file_llseek,
|
||||
+};
|
||||
+
|
||||
+static __init int setup_securelevel(void)
|
||||
+{
|
||||
+ struct dentry *securelevel_file;
|
||||
+
|
||||
+ securelevel_file = securityfs_create_file("securelevel",
|
||||
+ S_IWUSR | S_IRUGO,
|
||||
+ NULL, NULL,
|
||||
+ &securelevel_fops);
|
||||
+
|
||||
+ if (IS_ERR(securelevel_file))
|
||||
+ return PTR_ERR(securelevel_file);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+late_initcall(setup_securelevel);
|
148
debian/patches/features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
vendored
Normal file
148
debian/patches/features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Aug 2013 18:36:30 -0400
|
||||
Subject: [12/18] Add option to automatically set securelevel when in Secure
|
||||
Boot mode
|
||||
Origin: https://github.com/mjg59/linux/commit/e324de2d053295670f3ba8ef67289835d663aae5
|
||||
|
||||
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 <mjg59@srcf.ucam.org>
|
||||
---
|
||||
Documentation/x86/zero-page.txt | 2 ++
|
||||
arch/x86/Kconfig | 13 +++++++++++++
|
||||
arch/x86/boot/compressed/eboot.c | 36 +++++++++++++++++++++++++++++++++++
|
||||
arch/x86/include/uapi/asm/bootparam.h | 3 ++-
|
||||
arch/x86/kernel/setup.c | 7 +++++++
|
||||
5 files changed, 60 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/Documentation/x86/zero-page.txt
|
||||
+++ b/Documentation/x86/zero-page.txt
|
||||
@@ -31,6 +31,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
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -1754,6 +1754,19 @@ config EFI_MIXED
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config EFI_SECURE_BOOT_SECURELEVEL
|
||||
+ def_bool n
|
||||
+ depends on SECURITY_SECURELEVEL
|
||||
+ depends on EFI
|
||||
+ prompt "Automatically set securelevel when UEFI Secure Boot is enabled"
|
||||
+ ---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 securelevel enforcement
|
||||
+ when a system boots with UEFI Secure Boot enabled.
|
||||
+
|
||||
config SECCOMP
|
||||
def_bool y
|
||||
prompt "Enable seccomp to safely compute untrusted bytecode"
|
||||
--- 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"
|
||||
@@ -1050,6 +1051,37 @@ void setup_graphics(struct 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_early->call((unsigned long)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_early->call((unsigned long)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
|
||||
@@ -1432,6 +1464,10 @@ struct boot_params *efi_main(struct efi_
|
||||
else
|
||||
setup_boot_services32(efi_early);
|
||||
|
||||
+ sanitize_boot_params(boot_params);
|
||||
+
|
||||
+ boot_params->secure_boot = get_secure_boot();
|
||||
+
|
||||
setup_graphics(boot_params);
|
||||
|
||||
setup_efi_pci(boot_params);
|
||||
--- 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.
|
||||
*
|
||||
--- 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>
|
||||
@@ -1145,6 +1146,12 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
io_delay_init();
|
||||
|
||||
+#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
|
||||
+ if (boot_params.secure_boot) {
|
||||
+ set_securelevel(1);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Parse the ACPI tables for possible boot-time SMP configuration.
|
||||
*/
|
|
@ -0,0 +1,57 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Mar 2012 08:46:50 -0500
|
||||
Subject: [11/18] asus-wmi: Restrict debugfs interface when securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/f6e21827205ffcbfcce4b13d3a233427c3e742e0
|
||||
|
||||
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 securelevel is set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
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 a96630d52346..93943e480a67 100644
|
||||
--- a/drivers/platform/x86/asus-wmi.c
|
||||
+++ b/drivers/platform/x86/asus-wmi.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/thermal.h>
|
||||
+#include <linux/security.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <acpi/video.h>
|
||||
@@ -1867,6 +1868,9 @@ static int show_dsts(struct seq_file *m, void *data)
|
||||
int err;
|
||||
u32 retval = -1;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
|
||||
|
||||
if (err < 0)
|
||||
@@ -1883,6 +1887,9 @@ static int show_devs(struct seq_file *m, void *data)
|
||||
int err;
|
||||
u32 retval = -1;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
|
||||
&retval);
|
||||
|
||||
@@ -1907,6 +1914,9 @@ static int show_call(struct seq_file *m, void *data)
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
|
||||
1, asus->debug.method_id,
|
||||
&input, &output);
|
|
@ -0,0 +1,66 @@
|
|||
From: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Date: Tue, 5 Feb 2013 19:25:05 -0500
|
||||
Subject: [13/18] efi: Disable secure boot if shim is in insecure mode
|
||||
Origin: https://github.com/mjg59/linux/commit/f444a5ecb0ab09d6cf661b4520dd8e6fffacb8be
|
||||
|
||||
A user can manually tell the shim boot loader to disable validation of
|
||||
images it loads. When a user does this, it creates a UEFI variable called
|
||||
MokSBState that does not have the runtime attribute set. Given that the
|
||||
user explicitly disabled validation, we can honor that and not enable
|
||||
secure boot mode if that variable is set.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
---
|
||||
arch/x86/boot/compressed/eboot.c | 20 +++++++++++++++++++-
|
||||
include/linux/efi.h | 3 +++
|
||||
2 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/x86/boot/compressed/eboot.c
|
||||
+++ b/arch/x86/boot/compressed/eboot.c
|
||||
@@ -1053,8 +1053,9 @@ void setup_graphics(struct boot_params *
|
||||
|
||||
static int get_secure_boot(void)
|
||||
{
|
||||
- u8 sb, setup;
|
||||
+ u8 sb, setup, moksbstate;
|
||||
unsigned long datasize = sizeof(sb);
|
||||
+ u32 attr;
|
||||
efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
efi_status_t status;
|
||||
|
||||
@@ -1078,6 +1079,23 @@ static int get_secure_boot(void)
|
||||
if (setup == 1)
|
||||
return 0;
|
||||
|
||||
+ /* See if a user has put shim into insecure_mode. If so, and the variable
|
||||
+ * doesn't have the runtime attribute set, we might as well honor that.
|
||||
+ */
|
||||
+ var_guid = EFI_SHIM_LOCK_GUID;
|
||||
+ status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
|
||||
+ L"MokSBState", &var_guid, &attr, &datasize,
|
||||
+ &moksbstate);
|
||||
+
|
||||
+ /* If it fails, we don't care why. Default to secure */
|
||||
+ if (status != EFI_SUCCESS)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS)) {
|
||||
+ if (moksbstate == 1)
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
--- a/include/linux/efi.h
|
||||
+++ b/include/linux/efi.h
|
||||
@@ -629,6 +629,9 @@ typedef struct {
|
||||
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
|
||||
#define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
|
||||
|
||||
+#define EFI_SHIM_LOCK_GUID \
|
||||
+ EFI_GUID( 0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 )
|
||||
+
|
||||
typedef struct {
|
||||
efi_table_hdr_t hdr;
|
||||
u64 fw_vendor; /* physical addr of CHAR16 vendor string */
|
49
debian/patches/features/all/securelevel/enable-cold-boot-attack-mitigation.patch
vendored
Normal file
49
debian/patches/features/all/securelevel/enable-cold-boot-attack-mitigation.patch
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
From: Matthew Garrett <mjg59@coreos.com>
|
||||
Date: Tue, 12 Jan 2016 12:51:27 -0800
|
||||
Subject: [18/18] Enable cold boot attack mitigation
|
||||
Origin: https://github.com/mjg59/linux/commit/02d999574936dd234a508c0112a0200c135a5c34
|
||||
|
||||
---
|
||||
arch/x86/boot/compressed/eboot.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
|
||||
index 28c24d80d0a0..b0413ba639af 100644
|
||||
--- a/arch/x86/boot/compressed/eboot.c
|
||||
+++ b/arch/x86/boot/compressed/eboot.c
|
||||
@@ -1051,6 +1051,22 @@ void setup_graphics(struct boot_params *boot_params)
|
||||
}
|
||||
}
|
||||
|
||||
+#define MEMORY_ONLY_RESET_CONTROL_GUID \
|
||||
+ EFI_GUID (0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
|
||||
+
|
||||
+static void enable_reset_attack_mitigation(void)
|
||||
+{
|
||||
+ u8 val = 1;
|
||||
+ efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
|
||||
+
|
||||
+ /* Ignore the return value here - there's not really a lot we can do */
|
||||
+ efi_early->call((unsigned long)sys_table->runtime->set_variable,
|
||||
+ L"MemoryOverwriteRequestControl", &var_guid,
|
||||
+ EFI_VARIABLE_NON_VOLATILE |
|
||||
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), val);
|
||||
+}
|
||||
+
|
||||
static int get_secure_boot(void)
|
||||
{
|
||||
u8 sb, setup, moksbstate;
|
||||
@@ -1482,6 +1498,12 @@ struct boot_params *efi_main(struct efi_config *c,
|
||||
else
|
||||
setup_boot_services32(efi_early);
|
||||
|
||||
+ /*
|
||||
+ * Ask the firmware to clear memory if we don't have a clean
|
||||
+ * shutdown
|
||||
+ */
|
||||
+ enable_reset_attack_mitigation();
|
||||
+
|
||||
sanitize_boot_params(boot_params);
|
||||
|
||||
boot_params->secure_boot = get_secure_boot();
|
|
@ -0,0 +1,24 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Mon, 9 Sep 2013 08:46:52 -0400
|
||||
Subject: [02/18] Enforce module signatures when securelevel is greater than 0
|
||||
Origin: https://github.com/mjg59/linux/commit/90e0fa532b145d1bb76c368277a3a3e3b3eb5c94
|
||||
|
||||
If securelevel has been set to 1 or greater, require that all modules have
|
||||
valid signatures.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
kernel/module.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/kernel/module.c
|
||||
+++ b/kernel/module.c
|
||||
@@ -2616,7 +2616,7 @@ static int module_sig_check(struct load_
|
||||
}
|
||||
|
||||
/* Not having a signature is only an error if we're strict. */
|
||||
- if (err == -ENOKEY && !sig_enforce)
|
||||
+ if ((err == -ENOKEY && !sig_enforce) && (get_securelevel() <= 0))
|
||||
err = 0;
|
||||
|
||||
return err;
|
36
debian/patches/features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
vendored
Normal file
36
debian/patches/features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
From: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
Date: Fri, 20 Jun 2014 08:53:24 -0400
|
||||
Subject: [14/18] hibernate: Disable when securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/500a87278c5c0608ba88ed8af7a35fcfa955c492
|
||||
|
||||
There is currently no way to verify the resume image when returning
|
||||
from hibernate. This might compromise the securelevel trust model,
|
||||
so until we can work with signed hibernate images we disable it in
|
||||
a secure modules environment.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
|
||||
---
|
||||
kernel/power/hibernate.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
|
||||
index fca9254280ee..7bf7f723a27f 100644
|
||||
--- a/kernel/power/hibernate.c
|
||||
+++ b/kernel/power/hibernate.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/genhd.h>
|
||||
#include <linux/ktime.h>
|
||||
+#include <linux/security.h>
|
||||
#include <trace/events/power.h>
|
||||
|
||||
#include "power.h"
|
||||
@@ -66,7 +67,7 @@ static const struct platform_hibernation_ops *hibernation_ops;
|
||||
|
||||
bool hibernation_available(void)
|
||||
{
|
||||
- return (nohibernate == 0);
|
||||
+ return ((nohibernate == 0) && (get_securelevel() <= 0));
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,36 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Aug 2013 03:33:56 -0400
|
||||
Subject: [08/18] kexec: Disable at runtime if securelevel has been set.
|
||||
Origin: https://github.com/mjg59/linux/commit/ec87b6aac76fd553578cec2c05674e22b79afe3e
|
||||
|
||||
kexec permits the loading and execution of arbitrary code in ring 0, which
|
||||
permits the modification of the running kernel. Prevent this if securelevel
|
||||
has been set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
kernel/kexec.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kernel/kexec.c b/kernel/kexec.c
|
||||
index ee70aef5cd81..542655ea297c 100644
|
||||
--- a/kernel/kexec.c
|
||||
+++ b/kernel/kexec.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/security.h>
|
||||
|
||||
#include "kexec_internal.h"
|
||||
|
||||
@@ -134,6 +135,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
|
||||
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
|
||||
return -EPERM;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
/*
|
||||
* Verify we have a legal set of flags
|
||||
* This leaves us room for future extensions.
|
|
@ -0,0 +1,32 @@
|
|||
From: Dave Young <dyoung@redhat.com>
|
||||
Date: Tue, 6 Oct 2015 13:31:31 +0100
|
||||
Subject: [15/18] kexec/uefi: copy secure_boot flag in boot params across kexec
|
||||
reboot
|
||||
Origin: https://github.com/mjg59/linux/commit/4b2b64d5a6ebc84214755ebccd599baef7c1b798
|
||||
|
||||
Kexec reboot in case secure boot being enabled does not keep the secure
|
||||
boot mode in new kernel, so later one can load unsigned kernel via legacy
|
||||
kexec_load. In this state, the system is missing the protections provided
|
||||
by secure boot. Adding a patch to fix this by retain the secure_boot flag
|
||||
in original kernel.
|
||||
|
||||
secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
|
||||
stub. Fixing this issue by copying secure_boot flag across kexec reboot.
|
||||
|
||||
Signed-off-by: Dave Young <dyoung@redhat.com>
|
||||
---
|
||||
arch/x86/kernel/kexec-bzimage64.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
|
||||
index 2af478e3fd4e..61827eeb6881 100644
|
||||
--- a/arch/x86/kernel/kexec-bzimage64.c
|
||||
+++ b/arch/x86/kernel/kexec-bzimage64.c
|
||||
@@ -180,6 +180,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
|
||||
if (efi_enabled(EFI_OLD_MEMMAP))
|
||||
return 0;
|
||||
|
||||
+ params->secure_boot = boot_params.secure_boot;
|
||||
ei->efi_loader_signature = current_ei->efi_loader_signature;
|
||||
ei->efi_systab = current_ei->efi_systab;
|
||||
ei->efi_systab_hi = current_ei->efi_systab_hi;
|
108
debian/patches/features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
vendored
Normal file
108
debian/patches/features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Thu, 8 Mar 2012 10:10:38 -0500
|
||||
Subject: [03/18] PCI: Lock down BAR access when securelevel is enabled
|
||||
Origin: https://github.com/mjg59/linux/commit/2533a3844cf8c43bf58b653334f8925cd1e7d405
|
||||
|
||||
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 securelevel has been set. Default
|
||||
to paranoid - in future we can potentially relax this for sufficiently
|
||||
IOMMU-isolated devices.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
drivers/pci/pci-sysfs.c | 9 +++++++++
|
||||
drivers/pci/proc.c | 9 ++++++++-
|
||||
drivers/pci/syscall.c | 3 ++-
|
||||
3 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/pci/pci-sysfs.c
|
||||
+++ b/drivers/pci/pci-sysfs.c
|
||||
@@ -711,6 +711,9 @@ static ssize_t pci_write_config(struct f
|
||||
loff_t init_off = off;
|
||||
u8 *data = (u8 *) buf;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (off > dev->cfg_size)
|
||||
return 0;
|
||||
if (off + count > dev->cfg_size) {
|
||||
@@ -998,6 +1001,9 @@ static int pci_mmap_resource(struct kobj
|
||||
resource_size_t start, end;
|
||||
int i;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
for (i = 0; i < PCI_ROM_RESOURCE; i++)
|
||||
if (res == &pdev->resource[i])
|
||||
break;
|
||||
@@ -1098,6 +1104,9 @@ static ssize_t pci_write_resource_io(str
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
return pci_resource_io(filp, kobj, attr, buf, off, count, true);
|
||||
}
|
||||
|
||||
--- 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
|
||||
int size = dev->cfg_size;
|
||||
int cnt;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (pos >= size)
|
||||
return 0;
|
||||
if (nbytes >= size)
|
||||
@@ -195,6 +199,9 @@ static long proc_bus_pci_ioctl(struct fi
|
||||
#endif /* HAVE_PCI_MMAP */
|
||||
int ret = 0;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ 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
|
||||
struct pci_filp_private *fpriv = file->private_data;
|
||||
int i, ret;
|
||||
|
||||
- if (!capable(CAP_SYS_RAWIO))
|
||||
+ if (!capable(CAP_SYS_RAWIO) || (get_securelevel() > 0))
|
||||
return -EPERM;
|
||||
|
||||
/* Make sure the caller is mapping a real resource for this device */
|
||||
--- 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, unsigne
|
||||
u32 dword;
|
||||
int err = 0;
|
||||
|
||||
- if (!capable(CAP_SYS_ADMIN))
|
||||
+ if (!capable(CAP_SYS_ADMIN) || (get_securelevel() > 0))
|
||||
return -EPERM;
|
||||
|
||||
dev = pci_get_bus_and_slot(bus, dfn);
|
|
@ -0,0 +1,38 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 9 Mar 2012 09:28:15 -0500
|
||||
Subject: [05/18] Restrict /dev/mem and /dev/kmem when securelevel is set.
|
||||
Origin: https://github.com/mjg59/linux/commit/401996625d478c814fe9e736ca9e6c5c5f055f06
|
||||
|
||||
Allowing users to write to address space provides mechanisms that may permit
|
||||
modification of the kernel at runtime. Prevent this if securelevel has been
|
||||
set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
drivers/char/mem.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
|
||||
index cef0d40a3d74..c810f1e15c73 100644
|
||||
--- a/drivers/char/mem.c
|
||||
+++ b/drivers/char/mem.c
|
||||
@@ -167,6 +167,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
|
||||
if (p != *ppos)
|
||||
return -EFBIG;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (!valid_phys_addr_range(p, count))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -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_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (p < (unsigned long) high_memory) {
|
||||
unsigned long to_write = min_t(unsigned long, count,
|
||||
(unsigned long)high_memory - p);
|
36
debian/patches/features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
vendored
Normal file
36
debian/patches/features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Tue, 3 Sep 2013 11:23:29 -0400
|
||||
Subject: [09/18] uswsusp: Disable when securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/504f45f7cc9b4265a4d89728c4f8254295e81977
|
||||
|
||||
uswsusp allows a user process to dump and then restore kernel state, which
|
||||
makes it possible to modify the running kernel. Disable this if securelevel
|
||||
has been set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
kernel/power/user.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kernel/power/user.c b/kernel/power/user.c
|
||||
index 526e8911460a..40618bf41620 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>
|
||||
|
||||
@@ -52,6 +53,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
|
||||
if (!hibernation_available())
|
||||
return -EPERM;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
lock_system_sleep();
|
||||
|
||||
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
|
|
@ -0,0 +1,74 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Thu, 8 Mar 2012 10:35:59 -0500
|
||||
Subject: [04/18] x86: Lock down IO port access when securelevel is enabled
|
||||
Origin: https://github.com/mjg59/linux/commit/2ad64f6ea1f1164c8b552860faa27392d9da9928
|
||||
|
||||
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 securelevel is set.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
arch/x86/kernel/ioport.c | 5 +++--
|
||||
drivers/char/mem.c | 7 +++++++
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- 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
|
||||
|
||||
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_securelevel() > 0)))
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
@@ -103,7 +104,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
|
||||
return -EINVAL;
|
||||
/* Trying to gain more privileges? */
|
||||
if (level > old) {
|
||||
- if (!capable(CAP_SYS_RAWIO))
|
||||
+ if (!capable(CAP_SYS_RAWIO) || (get_securelevel() > 0))
|
||||
return -EPERM;
|
||||
}
|
||||
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
|
||||
--- a/drivers/char/mem.c
|
||||
+++ b/drivers/char/mem.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/uio.h>
|
||||
+#include <linux/security.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
@@ -559,6 +560,9 @@ static ssize_t read_port(struct file *fi
|
||||
unsigned long i = *ppos;
|
||||
char __user *tmp = buf;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ 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 *f
|
||||
unsigned long i = *ppos;
|
||||
const char __user *tmp = buf;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (!access_ok(VERIFY_READ, buf, count))
|
||||
return -EFAULT;
|
||||
while (count-- > 0 && i < 65536) {
|
46
debian/patches/features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
vendored
Normal file
46
debian/patches/features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
From: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
Date: Fri, 8 Feb 2013 11:12:13 -0800
|
||||
Subject: [10/18] x86: Restrict MSR access when securelevel is set
|
||||
Origin: https://github.com/mjg59/linux/commit/c6ad37822699967e60fae57a64ae89676f543182
|
||||
|
||||
Permitting write access to MSRs allows userspace to modify the running
|
||||
kernel. Prevent this if securelevel has been set. Based on a patch by Kees
|
||||
Cook.
|
||||
|
||||
Cc: Kees Cook <keescook@chromium.org>
|
||||
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
|
||||
---
|
||||
arch/x86/kernel/msr.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
--- 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>
|
||||
@@ -83,6 +84,9 @@ static ssize_t msr_write(struct file *fi
|
||||
int err = 0;
|
||||
ssize_t bytes = 0;
|
||||
|
||||
+ if (get_securelevel() > 0)
|
||||
+ return -EPERM;
|
||||
+
|
||||
if (count % 8)
|
||||
return -EINVAL; /* Invalid chunk size */
|
||||
|
||||
@@ -130,6 +134,10 @@ static long msr_ioctl(struct file *file,
|
||||
err = -EBADF;
|
||||
break;
|
||||
}
|
||||
+ if (get_securelevel() > 0) {
|
||||
+ err = -EPERM;
|
||||
+ break;
|
||||
+ }
|
||||
if (copy_from_user(®s, uregs, sizeof regs)) {
|
||||
err = -EFAULT;
|
||||
break;
|
|
@ -75,6 +75,26 @@ features/all/grsecurity/grsecurity-kconfig.patch
|
|||
#features/all/grsecurity/grsecurity-kbuild.patch
|
||||
features/all/grsecurity/grkernsec_perf_harden.patch
|
||||
|
||||
# Securelevel patchset from mjg59
|
||||
features/all/securelevel/add-bsd-style-securelevel-support.patch
|
||||
features/all/securelevel/enforce-module-signatures-when-securelevel-is-greate.patch
|
||||
features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
|
||||
features/all/securelevel/x86-lock-down-io-port-access-when-securelevel-is-ena.patch
|
||||
features/all/securelevel/restrict-dev-mem-and-dev-kmem-when-securelevel-is-se.patch
|
||||
features/all/securelevel/acpi-limit-access-to-custom_method-if-securelevel-is.patch
|
||||
features/all/securelevel/acpi-ignore-acpi_rsdp-kernel-parameter-when-securele.patch
|
||||
features/all/securelevel/kexec-disable-at-runtime-if-securelevel-has-been-set.patch
|
||||
features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
|
||||
features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
|
||||
features/all/securelevel/asus-wmi-restrict-debugfs-interface-when-securelevel.patch
|
||||
features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
|
||||
features/all/securelevel/efi-disable-secure-boot-if-shim-is-in-insecure-mode.patch
|
||||
features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
|
||||
features/all/securelevel/kexec-uefi-copy-secure_boot-flag-in-boot-params-acro.patch
|
||||
features/all/securelevel/acpi-disable-acpi-table-override-if-securelevel-is-s.patch
|
||||
features/all/securelevel/acpi-disable-apei-error-injection-if-securelevel-is-.patch
|
||||
features/all/securelevel/enable-cold-boot-attack-mitigation.patch
|
||||
|
||||
# Security fixes
|
||||
bugfix/all/ptrace-being-capable-wrt-a-process-requires-mapped-uids-gids.patch
|
||||
bugfix/x86/x86-mm-page-align-the-_end-symbol-to-avoid-pfn-conve.patch
|
||||
|
|
Loading…
Reference in New Issue