All of lore.kernel.org
 help / color / mirror / Atom feed
From: Randy Dunlap <rdunlap@infradead.org>
To: Matthew Garrett <matthewgarrett@google.com>, jmorris@namei.org
Cc: linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org, dhowells@redhat.com
Subject: Re: [PATCH 02/27] Add a SysRq option to lift kernel lockdown
Date: Wed, 6 Mar 2019 16:09:57 -0800	[thread overview]
Message-ID: <7bcd6149-332d-15f8-31e1-ef0a6b7f496e@infradead.org> (raw)
In-Reply-To: <20190306235913.6631-3-matthewgarrett@google.com>

On 3/6/19 3:58 PM, Matthew Garrett wrote:
> From: Kyle McMartin <kyle@redhat.com>
> 
> Make an option to provide a sysrq key that will lift the kernel lockdown,
> thereby allowing the running kernel image to be accessed and modified.

You still need to document this in Documentation/admin-guide/sysrq.rst,
like I mentioned last week.

> On x86 this is triggered with SysRq+x, but this key may not be available on
> all arches, so it is set by setting LOCKDOWN_LIFT_KEY in asm/setup.h.
> Since this macro must be defined in an arch to be able to use this facility
> for that arch, the Kconfig option is restricted to arches that support it.
> 
> Signed-off-by: Kyle McMartin <kyle@redhat.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: x86@kernel.org
> Signed-off-by: Matthew Garrett <matthewgarrett@google.com>
> ---
>  arch/x86/include/asm/setup.h |  2 ++
>  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 +-
>  security/Kconfig             |  9 +++++++
>  security/lock_down.c         | 47 ++++++++++++++++++++++++++++++++++++
>  8 files changed, 85 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
> index ed8ec011a9fd..8daf633a5347 100644
> --- a/arch/x86/include/asm/setup.h
> +++ b/arch/x86/include/asm/setup.h
> @@ -9,6 +9,8 @@
>  #include <linux/linkage.h>
>  #include <asm/page_types.h>
>  
> +#define LOCKDOWN_LIFT_KEY 'x'
> +
>  #ifdef __i386__
>  
>  #include <linux/pfn.h>
> diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
> index 8ec483e8688b..c2a77dc73fa0 100644
> --- a/drivers/input/misc/uinput.c
> +++ b/drivers/input/misc/uinput.c
> @@ -365,6 +365,7 @@ static int uinput_create_device(struct uinput_device *udev)
>  		dev->flush = uinput_dev_flush;
>  	}
>  
> +	dev->flags |= INPUTDEV_FLAGS_SYNTHETIC;
>  	dev->event = uinput_dev_event;
>  
>  	input_set_drvdata(udev->dev, udev);
> diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
> index 1f03078ec352..0a05d336008e 100644
> --- a/drivers/tty/sysrq.c
> +++ b/drivers/tty/sysrq.c
> @@ -480,6 +480,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 */
> @@ -523,7 +524,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;
> @@ -543,11 +544,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);
> @@ -579,7 +584,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(struct timer_list *t)
>  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,
> @@ -812,8 +817,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;
>  	}
> @@ -1096,7 +1103,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 7c7516eb7d76..38cd0ea72c37 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 8c71874e8485..7de1f08b60a9 100644
> --- a/include/linux/sysrq.h
> +++ b/include/linux/sysrq.h
> @@ -29,6 +29,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;
> @@ -43,8 +45,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 82a3b32a7cfc..efee1abf5e8e 100644
> --- a/kernel/debug/kdb/kdb_main.c
> +++ b/kernel/debug/kdb/kdb_main.c
> @@ -1981,7 +1981,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;
> diff --git a/security/Kconfig b/security/Kconfig
> index 47dc3403b5af..8346eb883336 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -244,6 +244,15 @@ config LOCK_DOWN_KERNEL_FORCE
>          help
>            Enable the kernel lock down functionality automatically at boot.
>  
> +config ALLOW_LOCKDOWN_LIFT_BY_SYSRQ
> +	bool "Allow the kernel lockdown to be lifted by SysRq"
> +	depends on LOCK_DOWN_KERNEL
> +	depends on MAGIC_SYSRQ
> +	depends on X86
> +	help
> +	  Allow the lockdown on a kernel to be lifted, by pressing a SysRq key
> +	  combination on a wired keyboard.
> +
>  source "security/selinux/Kconfig"
>  source "security/smack/Kconfig"
>  source "security/tomoyo/Kconfig"
> diff --git a/security/lock_down.c b/security/lock_down.c
> index 13a8228c1034..cfbc2c39712b 100644
> --- a/security/lock_down.c
> +++ b/security/lock_down.c
> @@ -11,8 +11,14 @@
>  
>  #include <linux/security.h>
>  #include <linux/export.h>
> +#include <linux/sysrq.h>
> +#include <asm/setup.h>
>  
> +#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ
> +static __read_mostly bool kernel_locked_down;
> +#else
>  static __ro_after_init bool kernel_locked_down;
> +#endif
>  
>  /*
>   * Put the kernel into lock-down mode.
> @@ -57,3 +63,44 @@ bool __kernel_is_locked_down(const char *what, bool first)
>  	return kernel_locked_down;
>  }
>  EXPORT_SYMBOL(__kernel_is_locked_down);
> +
> +#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ
> +
> +/*
> + * Take the kernel out of lockdown mode.
> + */
> +static void lift_kernel_lockdown(void)
> +{
> +	pr_notice("Lifting lockdown\n");
> +	kernel_locked_down = false;
> +}
> +
> +/*
> + * Allow lockdown to be lifted by pressing something like SysRq+x (and not by
> + * echoing the appropriate letter into the sysrq-trigger file).
> + */
> +static void sysrq_handle_lockdown_lift(int key)
> +{
> +	if (kernel_locked_down)
> +		lift_kernel_lockdown();
> +}
> +
> +static struct sysrq_key_op lockdown_lift_sysrq_op = {
> +	.handler	= sysrq_handle_lockdown_lift,
> +	.help_msg	= "unSB(x)",
> +	.action_msg	= "Disabling Secure Boot restrictions",
> +	.enable_mask	= SYSRQ_DISABLE_USERSPACE,
> +};
> +
> +static int __init lockdown_lift_sysrq(void)
> +{
> +	if (kernel_locked_down) {
> +		lockdown_lift_sysrq_op.help_msg[5] = LOCKDOWN_LIFT_KEY;
> +		register_sysrq_key(LOCKDOWN_LIFT_KEY, &lockdown_lift_sysrq_op);
> +	}
> +	return 0;
> +}
> +
> +late_initcall(lockdown_lift_sysrq);
> +
> +#endif /* CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ */
> 


-- 
~Randy

  reply	other threads:[~2019-03-07  0:10 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-06 23:58 [PULL REQUEST] Kernel lockdown patches for 5.2 Matthew Garrett
2019-03-06 23:58 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image Matthew Garrett
2019-03-06 23:58 ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown Matthew Garrett
2019-03-07  0:09   ` Randy Dunlap [this message]
2019-03-07  0:12     ` Matthew Garrett
2019-03-06 23:58 ` [PATCH 03/27] Enforce module signatures if the kernel is locked down Matthew Garrett
2019-03-08 23:00   ` James Morris
2019-03-08 23:30     ` Matthew Garrett
2019-03-09  4:45       ` James Morris
2019-03-06 23:58 ` [PATCH 04/27] Restrict /dev/{mem,kmem,port} when " Matthew Garrett
2019-03-06 23:58 ` [PATCH 05/27] kexec_load: Disable at runtime if " Matthew Garrett
2019-03-06 23:58 ` [PATCH 06/27] Copy secure_boot flag in boot params across kexec reboot Matthew Garrett
2019-03-06 23:58 ` [PATCH 07/27] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE Matthew Garrett
2019-03-06 23:58 ` [PATCH 08/27] kexec_file: Restrict at runtime if the kernel is locked down Matthew Garrett
2019-03-06 23:58 ` [PATCH 09/27] hibernate: Disable when " Matthew Garrett
2019-03-07 14:55   ` Alan Cox
2019-03-07 17:32     ` Matthew Garrett
2019-03-18 18:55       ` Alan Cox
2019-03-06 23:58 ` [PATCH 10/27] uswsusp: " Matthew Garrett
2019-03-06 23:58 ` [PATCH 11/27] PCI: Lock down BAR access " Matthew Garrett
2019-03-06 23:58 ` [PATCH 12/27] x86: Lock down IO port " Matthew Garrett
2019-03-06 23:58 ` [PATCH 13/27] x86/msr: Restrict MSR " Matthew Garrett
2019-03-06 23:59 ` [PATCH 14/27] ACPI: Limit access to custom_method " Matthew Garrett
2019-03-06 23:59 ` [PATCH 15/27] acpi: Ignore acpi_rsdp kernel param when the kernel has been " Matthew Garrett
2019-03-06 23:59 ` [PATCH 16/27] acpi: Disable ACPI table override if the kernel is " Matthew Garrett
2019-03-06 23:59 ` [PATCH 17/27] acpi: Disable APEI error injection " Matthew Garrett
2019-03-06 23:59 ` [PATCH 18/27] Prohibit PCMCIA CIS storage when " Matthew Garrett
2019-03-06 23:59 ` [PATCH 19/27] Lock down TIOCSSERIAL Matthew Garrett
2019-03-06 23:59 ` [PATCH 20/27] Lock down module params that specify hardware parameters (eg. ioport) Matthew Garrett
2019-03-06 23:59 ` [PATCH 21/27] x86/mmiotrace: Lock down the testmmiotrace module Matthew Garrett
2019-03-06 23:59 ` [PATCH 22/27] Lock down /proc/kcore Matthew Garrett
2019-03-06 23:59 ` [PATCH 23/27] Lock down kprobes Matthew Garrett
2019-03-06 23:59 ` [PATCH 24/27] bpf: Restrict kernel image access functions when the kernel is locked down Matthew Garrett
2019-03-06 23:59 ` [PATCH 25/27] Lock down perf Matthew Garrett
2019-03-06 23:59 ` [PATCH 26/27] debugfs: Restrict debugfs when the kernel is locked down Matthew Garrett
2019-04-25 10:49   ` Vasily Gorbik
2019-04-25 21:44     ` Matthew Garrett
2019-03-06 23:59 ` [PATCH 27/27] lockdown: Print current->comm in restriction messages Matthew Garrett
2019-03-07  3:56 ` [PULL REQUEST] Kernel lockdown patches for 5.2 Mimi Zohar
2019-03-07  4:24   ` Matthew Garrett
2019-03-12  0:42     ` Matthew Garrett
2019-03-12  1:52       ` Mimi Zohar
2019-03-07 15:59 ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown David Howells
  -- strict thread matches above, loose matches on Subject: below --
2019-02-28 21:28 [PULL REQUEST] Lock down patches Matthew Garrett
2019-02-28 22:44 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image Matthew Garrett
2019-02-28 22:44   ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown Matthew Garrett
2019-02-28 23:10 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image Matthew Garrett
2019-02-28 23:10   ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown Matthew Garrett
2019-02-28 23:11 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image Matthew Garrett
2019-02-28 23:11   ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown Matthew Garrett
2019-02-28 23:11 ` [PATCH 01/27] Add the ability to lock down access to the running kernel image Matthew Garrett
2019-02-28 23:11   ` [PATCH 02/27] Add a SysRq option to lift kernel lockdown Matthew Garrett
2017-10-19 14:50 [PATCH 00/27] security, efi: Add " David Howells
2017-10-19 14:50 ` [PATCH 02/27] Add a SysRq option to lift " David Howells
2017-10-19 14:50   ` David Howells
2017-10-19 17:20   ` Randy Dunlap
2017-10-19 17:20     ` Randy Dunlap
2017-10-19 17:20     ` Randy Dunlap
2017-10-19 22:12   ` David Howells
2017-10-19 22:12     ` David Howells
2017-10-19 22:12     ` David Howells
2017-11-07 17:39   ` Thiago Jung Bauermann
2017-11-07 17:39     ` Thiago Jung Bauermann
2017-11-07 22:56   ` David Howells
2017-11-07 22:56     ` 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=7bcd6149-332d-15f8-31e1-ef0a6b7f496e@infradead.org \
    --to=rdunlap@infradead.org \
    --cc=dhowells@redhat.com \
    --cc=jmorris@namei.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=matthewgarrett@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.