From: David Howells <dhowells@redhat.com>
To: keyrings@vger.kernel.org
Cc: dhowells@redhat.com, matthew.garrett@nebula.com,
linux-security-module@vger.kernel.org, linux-efi@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 06/16] Add a sysrq option to exit secure boot mode
Date: Wed, 16 Nov 2016 21:48:00 +0000 [thread overview]
Message-ID: <147933288015.19316.13883500379332751105.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <147933283664.19316.12454053022687659937.stgit@warthog.procyon.org.uk>
From: Kyle McMartin <kyle@redhat.com>
Make sysrq+x exit secure boot mode on x86_64, thereby allowing the running
kernel image to be modified. This lifts the lockdown.
Signed-off-by: David Howells <dhowells@redhat.com>
---
arch/x86/Kconfig | 10 ++++++++++
arch/x86/kernel/setup.c | 31 +++++++++++++++++++++++++++++++
drivers/input/misc/uinput.c | 1 +
drivers/tty/sysrq.c | 19 +++++++++++++------
include/linux/input.h | 5 +++++
include/linux/sysrq.h | 8 +++++++-
kernel/debug/kdb/kdb_main.c | 2 +-
7 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5b19997d88d0..c2b481b59931 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1798,6 +1798,16 @@ config EFI_SECURE_BOOT_LOCK_DOWN
image. Say Y here to automatically lock down the kernel when a
system boots with UEFI Secure Boot enabled.
+config EFI_ALLOW_SECURE_BOOT_EXIT
+ def_bool n
+ depends on EFI_SECURE_BOOT_LOCK_DOWN && MAGIC_SYSRQ
+ select ALLOW_LOCKDOWN_LIFT
+ prompt "Allow secure boot mode to be exited with SysRq+x on a keyboard"
+ ---help---
+ Allow secure boot mode to be exited and the kernel lockdown lifted by
+ typing SysRq+x on a keyboard attached to the system (not permitted
+ through procfs).
+
config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 539f29587712..89786c2270bd 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -71,6 +71,11 @@
#include <linux/jiffies.h>
#include <linux/security.h>
+#include <linux/fips.h>
+#include <linux/cred.h>
+#include <linux/sysrq.h>
+#include <linux/init_task.h>
+
#include <video/edid.h>
#include <asm/mtrr.h>
@@ -1291,6 +1296,32 @@ void __init i386_reserve_resources(void)
#endif /* CONFIG_X86_32 */
+#ifdef CONFIG_EFI_ALLOW_SECURE_BOOT_EXIT
+
+static void sysrq_handle_secure_boot(int key)
+{
+ if (!efi_enabled(EFI_SECURE_BOOT))
+ return;
+
+ pr_info("Secure boot disabled\n");
+ lift_kernel_lockdown();
+}
+static struct sysrq_key_op secure_boot_sysrq_op = {
+ .handler = sysrq_handle_secure_boot,
+ .help_msg = "unSB(x)",
+ .action_msg = "Disabling Secure Boot restrictions",
+ .enable_mask = SYSRQ_DISABLE_USERSPACE,
+};
+static int __init secure_boot_sysrq(void)
+{
+ if (efi_enabled(EFI_SECURE_BOOT))
+ register_sysrq_key('x', &secure_boot_sysrq_op);
+ return 0;
+}
+late_initcall(secure_boot_sysrq);
+#endif /*CONFIG_EFI_ALLOW_SECURE_BOOT_EXIT*/
+
+
static struct notifier_block kernel_offset_notifier = {
.notifier_call = dump_kernel_offset
};
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 92595b98e7ed..894ed3f74f04 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -379,6 +379,7 @@ static int uinput_allocate_device(struct uinput_device *udev)
if (!udev->dev)
return -ENOMEM;
+ udev->dev->flags |= INPUTDEV_FLAGS_SYNTHETIC;
udev->dev->event = uinput_dev_event;
input_set_drvdata(udev->dev, udev);
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 52bbd27e93ae..72f46a1a2ce7 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -479,6 +479,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
/* x: May be registered on mips for TLB dump */
/* x: May be registered on ppc/powerpc for xmon */
/* x: May be registered on sparc64 for global PMU dump */
+ /* x: May be registered on x86_64 for disabling secure boot */
NULL, /* x */
/* y: May be registered on sparc64 for global register dump */
NULL, /* y */
@@ -522,7 +523,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
sysrq_key_table[i] = op_p;
}
-void __handle_sysrq(int key, bool check_mask)
+void __handle_sysrq(int key, unsigned int from)
{
struct sysrq_key_op *op_p;
int orig_log_level;
@@ -542,11 +543,15 @@ void __handle_sysrq(int key, bool check_mask)
op_p = __sysrq_get_key_op(key);
if (op_p) {
+ /* Ban synthetic events from some sysrq functionality */
+ if ((from == SYSRQ_FROM_PROC || from == SYSRQ_FROM_SYNTHETIC) &&
+ op_p->enable_mask & SYSRQ_DISABLE_USERSPACE)
+ printk("This sysrq operation is disabled from userspace.\n");
/*
* Should we check for enabled operations (/proc/sysrq-trigger
* should not) and is the invoked operation enabled?
*/
- if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
+ if (from == SYSRQ_FROM_KERNEL || sysrq_on_mask(op_p->enable_mask)) {
pr_cont("%s\n", op_p->action_msg);
console_loglevel = orig_log_level;
op_p->handler(key);
@@ -578,7 +583,7 @@ void __handle_sysrq(int key, bool check_mask)
void handle_sysrq(int key)
{
if (sysrq_on())
- __handle_sysrq(key, true);
+ __handle_sysrq(key, SYSRQ_FROM_KERNEL);
}
EXPORT_SYMBOL(handle_sysrq);
@@ -659,7 +664,7 @@ static void sysrq_do_reset(unsigned long _state)
static void sysrq_handle_reset_request(struct sysrq_state *state)
{
if (state->reset_requested)
- __handle_sysrq(sysrq_xlate[KEY_B], false);
+ __handle_sysrq(sysrq_xlate[KEY_B], SYSRQ_FROM_KERNEL);
if (sysrq_reset_downtime_ms)
mod_timer(&state->keyreset_timer,
@@ -810,8 +815,10 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
default:
if (sysrq->active && value && value != 2) {
+ int from = sysrq->handle.dev->flags & INPUTDEV_FLAGS_SYNTHETIC ?
+ SYSRQ_FROM_SYNTHETIC : 0;
sysrq->need_reinject = false;
- __handle_sysrq(sysrq_xlate[code], true);
+ __handle_sysrq(sysrq_xlate[code], from);
}
break;
}
@@ -1095,7 +1102,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
if (get_user(c, buf))
return -EFAULT;
- __handle_sysrq(c, false);
+ __handle_sysrq(c, SYSRQ_FROM_PROC);
}
return count;
diff --git a/include/linux/input.h b/include/linux/input.h
index a65e3b24fb18..8b0357175049 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -42,6 +42,7 @@ struct input_value {
* @phys: physical path to the device in the system hierarchy
* @uniq: unique identification code for the device (if device has it)
* @id: id of the device (struct input_id)
+ * @flags: input device flags (SYNTHETIC, etc.)
* @propbit: bitmap of device properties and quirks
* @evbit: bitmap of types of events supported by the device (EV_KEY,
* EV_REL, etc.)
@@ -124,6 +125,8 @@ struct input_dev {
const char *uniq;
struct input_id id;
+ unsigned int flags;
+
unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
@@ -190,6 +193,8 @@ struct input_dev {
};
#define to_input_dev(d) container_of(d, struct input_dev, dev)
+#define INPUTDEV_FLAGS_SYNTHETIC 0x000000001
+
/*
* Verify that we are in sync with input_device_id mod_devicetable.h #defines
*/
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
index 387fa7d05c98..f7c52a9ea394 100644
--- a/include/linux/sysrq.h
+++ b/include/linux/sysrq.h
@@ -28,6 +28,8 @@
#define SYSRQ_ENABLE_BOOT 0x0080
#define SYSRQ_ENABLE_RTNICE 0x0100
+#define SYSRQ_DISABLE_USERSPACE 0x00010000
+
struct sysrq_key_op {
void (*handler)(int);
char *help_msg;
@@ -42,8 +44,12 @@ struct sysrq_key_op {
* are available -- else NULL's).
*/
+#define SYSRQ_FROM_KERNEL 0x0001
+#define SYSRQ_FROM_PROC 0x0002
+#define SYSRQ_FROM_SYNTHETIC 0x0004
+
void handle_sysrq(int key);
-void __handle_sysrq(int key, bool check_mask);
+void __handle_sysrq(int key, unsigned int from);
int register_sysrq_key(int key, struct sysrq_key_op *op);
int unregister_sysrq_key(int key, struct sysrq_key_op *op);
struct sysrq_key_op *__sysrq_get_key_op(int key);
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 2a20c0dfdafc..d46d2e18a889 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1968,7 +1968,7 @@ static int kdb_sr(int argc, const char **argv)
return KDB_ARGCOUNT;
kdb_trap_printk++;
- __handle_sysrq(*argv[1], check_mask);
+ __handle_sysrq(*argv[1], check_mask ? SYSRQ_FROM_KERNEL : 0);
kdb_trap_printk--;
return 0;
next prev parent reply other threads:[~2016-11-16 21:50 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
2016-11-16 21:47 ` [PATCH 01/16] Add the ability to lock down access to the running kernel image David Howells
2016-11-16 22:20 ` Borislav Petkov
2016-11-16 22:40 ` David Howells
2016-12-25 21:20 ` Pavel Machek
2016-12-25 21:44 ` David Howells
2016-11-16 21:47 ` [PATCH 02/16] efi: Get the secure boot status David Howells
2016-11-17 12:37 ` Lukas Wunner
2016-11-22 0:31 ` [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services David Howells
2016-11-22 10:20 ` Lukas Wunner
2016-11-22 14:17 ` David Howells
2016-11-22 14:58 ` Joe Perches
2016-11-22 15:52 ` David Howells
2016-11-22 16:25 ` Joe Perches
2016-11-22 16:40 ` David Howells
2016-11-22 16:51 ` Joe Perches
2016-11-22 0:31 ` [PATCH 2/6] arm/efi: " David Howells
2016-11-22 0:31 ` [PATCH 3/6] efi: Add SHIM and image security database GUID definitions David Howells
2016-11-22 0:32 ` [PATCH 4/6] efi: Get the secure boot status David Howells
2016-11-22 10:44 ` Lukas Wunner
2016-11-22 10:49 ` Ard Biesheuvel
2016-11-22 14:47 ` David Howells
2016-11-22 20:30 ` Lukas Wunner
2016-11-23 0:02 ` David Howells
2016-11-22 14:52 ` David Howells
2016-11-22 20:36 ` Lukas Wunner
2016-11-22 14:57 ` David Howells
2016-11-22 0:32 ` [PATCH 5/6] efi: Disable secure boot if shim is in insecure mode David Howells
2016-11-22 13:03 ` Lukas Wunner
2016-11-22 0:32 ` [PATCH 6/6] efi: Add EFI_SECURE_BOOT bit David Howells
2016-11-22 13:04 ` Lukas Wunner
2016-11-21 11:42 ` [PATCH 02/16] efi: Get the secure boot status David Howells
2016-11-21 11:52 ` Ard Biesheuvel
2016-11-21 12:41 ` David Howells
2016-11-21 13:14 ` Ard Biesheuvel
2016-11-21 15:17 ` Lukas Wunner
2016-11-21 15:25 ` Ard Biesheuvel
2016-11-21 11:46 ` David Howells
2016-11-21 19:58 ` Lukas Wunner
2016-11-16 21:47 ` [PATCH 03/16] efi: Disable secure boot if shim is in insecure mode David Howells
2016-11-16 21:47 ` [PATCH 04/16] efi: Lock down the kernel if booted in secure boot mode David Howells
2016-11-16 21:47 ` [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit David Howells
2016-11-17 21:58 ` Ard Biesheuvel
2016-11-18 11:58 ` Josh Boyer
2016-11-18 12:10 ` Ard Biesheuvel
2016-11-18 17:28 ` David Howells
2016-11-16 21:48 ` David Howells [this message]
2016-11-16 21:48 ` [PATCH 07/16] kexec: Disable at runtime if the kernel is locked down David Howells
2016-11-16 21:48 ` [PATCH 08/16] Copy secure_boot flag in boot params across kexec reboot David Howells
2016-11-16 21:48 ` [PATCH 09/16] hibernate: Disable when the kernel is locked down David Howells
2016-11-16 21:48 ` [PATCH 10/16] PCI: Lock down BAR access " David Howells
2016-11-16 21:48 ` [PATCH 11/16] x86: Lock down IO port " David Howells
2016-11-16 21:48 ` [PATCH 12/16] ACPI: Limit access to custom_method " David Howells
2016-11-16 21:48 ` [PATCH 13/16] asus-wmi: Restrict debugfs interface " David Howells
2016-11-16 21:48 ` [PATCH 14/16] Restrict /dev/mem and /dev/kmem " David Howells
2016-11-16 21:49 ` [PATCH 15/16] acpi: Ignore acpi_rsdp kernel param when the kernel has been " David Howells
2016-11-16 21:49 ` [PATCH 16/16] x86: Restrict MSR access when the kernel is " David Howells
2016-11-16 22:27 ` [PATCH 00/16] Kernel lockdown One Thousand Gnomes
2016-11-21 19:53 ` Ard Biesheuvel
2016-11-30 14:27 ` One Thousand Gnomes
2016-11-16 22:28 ` Justin Forbes
2016-11-21 23:10 ` [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed David Howells
2016-11-22 6:12 ` Dominik Brodowski
2016-11-23 12:58 ` David Howells
2016-11-23 19:21 ` Dominik Brodowski
2016-11-24 17:34 ` David Howells
2016-11-24 20:19 ` Dominik Brodowski
2016-11-25 14:49 ` David Howells
2016-11-28 22:32 ` Corey Minyard
2016-11-29 0:11 ` David Howells
2016-11-29 0:23 ` Corey Minyard
2016-11-29 14:03 ` David Howells
2016-11-29 14:35 ` Corey Minyard
2016-11-30 14:41 ` One Thousand Gnomes
2016-11-30 16:25 ` David Howells
2016-11-29 10:40 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=147933288015.19316.13883500379332751105.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=keyrings@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=matthew.garrett@nebula.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).