diff mbox

[01/24] Add the ability to lock down access to the running kernel image

Message ID 152346388583.4030.15146667041427303547.stgit@warthog.procyon.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

David Howells April 11, 2018, 4:24 p.m. UTC
Provide a single call to allow kernel code to determine whether the system
should be locked down, thereby disallowing various accesses that might
allow the running kernel image to be changed, including:

 - /dev/mem and similar
 - Loading of unauthorised modules
 - Fiddling with MSR registers
 - Suspend to disk managed by the kernel
 - Use of device DMA

Two kernel configuration options are provided:

 (*) CONFIG_LOCK_DOWN_KERNEL

     This makes lockdown available and applies it to all the points that
     need to be locked down if the mode is set.  Lockdown mode can be
     enabled by providing:

	lockdown=1

     on the command line.

 (*) CONFIG_LOCK_DOWN_MANDATORY

     This forces lockdown on at compile time, overriding the command line
     option.

init_lockdown() is used as a hook from which lockdown can be managed in
future.  It has to be called from arch setup code before things like ACPI
are enabled.

Note that, with the other changes in this series, if lockdown mode is
enabled, the kernel will not be able to use certain drivers as the ability
to manually configure hardware parameters would then be prohibited.  This
primarily applies to ISA hardware devices.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/x86/kernel/setup.c |    2 +
 include/linux/kernel.h  |   32 +++++++++++++++++++++++
 security/Kconfig        |   23 ++++++++++++++++-
 security/Makefile       |    3 ++
 security/lock_down.c    |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 security/lock_down.c


--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Jann Horn April 11, 2018, 4:44 p.m. UTC | #1
On Wed, Apr 11, 2018 at 6:24 PM, David Howells <dhowells@redhat.com> wrote:
> Provide a single call to allow kernel code to determine whether the system
> should be locked down, thereby disallowing various accesses that might
> allow the running kernel image to be changed, including:
>
>  - /dev/mem and similar
>  - Loading of unauthorised modules
>  - Fiddling with MSR registers
>  - Suspend to disk managed by the kernel
>  - Use of device DMA
>
> Two kernel configuration options are provided:
>
>  (*) CONFIG_LOCK_DOWN_KERNEL
>
>      This makes lockdown available and applies it to all the points that
>      need to be locked down if the mode is set.  Lockdown mode can be
>      enabled by providing:
>
>         lockdown=1
>
>      on the command line.
>
>  (*) CONFIG_LOCK_DOWN_MANDATORY
>
>      This forces lockdown on at compile time, overriding the command line
>      option.
>
> init_lockdown() is used as a hook from which lockdown can be managed in
> future.  It has to be called from arch setup code before things like ACPI
> are enabled.
>
> Note that, with the other changes in this series, if lockdown mode is
> enabled, the kernel will not be able to use certain drivers as the ability
> to manually configure hardware parameters would then be prohibited.  This
> primarily applies to ISA hardware devices.
>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
[...]
> diff --git a/security/lock_down.c b/security/lock_down.c
> new file mode 100644
> index 000000000000..f35ffdd096ad
> --- /dev/null
> +++ b/security/lock_down.c
[...]
> +/*
> + * Lock the kernel down from very early in the arch setup.  This must happen
> + * prior to things like ACPI being initialised.
> + */

Pedantic nit: I think this comment is wrong now? This function
actually just prints stuff.

> +void __init init_lockdown(void)
> +{
> +#ifdef CONFIG_LOCK_DOWN_MANDATORY
> +       pr_notice("Kernel is locked down from config; see man kernel_lockdown.7\n");
> +#endif
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Randy Dunlap April 11, 2018, 5:37 p.m. UTC | #2
On 04/11/2018 09:24 AM, David Howells wrote:
> ---
> 
>  arch/x86/kernel/setup.c |    2 +
>  include/linux/kernel.h  |   32 +++++++++++++++++++++++
>  security/Kconfig        |   23 ++++++++++++++++-
>  security/Makefile       |    3 ++
>  security/lock_down.c    |   65 +++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 124 insertions(+), 1 deletion(-)
>  create mode 100644 security/lock_down.c

> diff --git a/security/Kconfig b/security/Kconfig
> index c4302067a3ad..a68e5bdebad5 100644
> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -231,6 +231,28 @@ config STATIC_USERMODEHELPER_PATH
>  	  If you wish for all usermode helper programs to be disabled,
>  	  specify an empty string here (i.e. "").
>  
> +config LOCK_DOWN_KERNEL
> +	bool "Allow the kernel to be 'locked down'"
> +	help
> +	  Allow the kernel to be locked down.  Locking down the kernel turns
> +	  off various features that might otherwise allow access to the kernel

	  s/turns off/disables/

> +	  image (eg. setting MSR registers).

	         e.g.

> +
> +	  Note, however, that locking down your kernel will prevent some

	                                   the kernel
	                                   a kernel

> +	  drivers from functioning because allowing manual configuration of
> +	  hardware parameters is forbidden, lest a device be used to access the
> +	  kernel by DMA.  This mostly applies to ISA devices.

	Is DMA from non-ISA devices OK, or did I miss seeing that patch?

> +	  The kernel lockdown can be triggered by adding lockdown=1 to the
> +	  kernel command line.


> diff --git a/security/lock_down.c b/security/lock_down.c
> new file mode 100644
> index 000000000000..f35ffdd096ad
> --- /dev/null
> +++ b/security/lock_down.c
> @@ -0,0 +1,65 @@
> +/* Lock down the kernel
> + *
> + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
> + * Written by David Howells (dhowells@redhat.com)
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public Licence
> + * as published by the Free Software Foundation; either version
> + * 2 of the Licence, or (at your option) any later version.

fsf.org spells that Licence word as License. :)

> + */
David Howells April 11, 2018, 5:49 p.m. UTC | #3
Randy Dunlap <rdunlap@infradead.org> wrote:

> > +	  drivers from functioning because allowing manual configuration of
> > +	  hardware parameters is forbidden, lest a device be used to access the
> > +	  kernel by DMA.  This mostly applies to ISA devices.
> 
> 	Is DMA from non-ISA devices OK, or did I miss seeing that patch?

The issue is where you can directly command a device to do DMA, possibly by
using the wrong driver.  Ask Alan Cox.

David
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Torvalds April 11, 2018, 6:09 p.m. UTC | #4
On Wed, Apr 11, 2018 at 9:24 AM, David Howells <dhowells@redhat.com> wrote:
> Provide a single call to allow kernel code to determine whether the system
> should be locked down, thereby disallowing various accesses that might
> allow the running kernel image to be changed, including:
>
>  - /dev/mem and similar
>  - Loading of unauthorised modules
>  - Fiddling with MSR registers
>  - Suspend to disk managed by the kernel
>  - Use of device DMA

So what I stlll absolutely detest about  this series is that I think
many of these things should simply be done as separate config options.

For example, if the distro is sure that it doesn't need /dev/mem, then
why the hell is  this tied to "lockdown" that then may have to be
disabled because *other* changes may not be acceptable (eg people may
need that device DMA, or whatever).

If that /dev/mem access prevention was just instead done as an even
stricter mode of the existing CONFIG_STRICT_DEVMEM, it could just be
enabled unconditionally.

So none of these patches raise my hackles per se. But what continues
to makes me very very uncomfortable is how this is all tied together.

Why is this one magical mode that then - because it has such a big
impact - has to be enabled/disabled as a single magical mode and with
very odd rules?

I think a lot of people would be happier if this wasn't so incestuous
and mixing together independent things under one name, and one flag.

I think a lot of the secure boot problems were exacerbated by that mixup.

So I would seriously ask that the distros that have been using these
patches look at which parts of lockdown they could make unconditional
(because it doesn't break machines), and which ones need that escape
clause.

                 Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Justin Forbes April 11, 2018, 6:35 p.m. UTC | #5
On Wed, Apr 11, 2018 at 1:09 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Wed, Apr 11, 2018 at 9:24 AM, David Howells <dhowells@redhat.com> wrote:
>> Provide a single call to allow kernel code to determine whether the system
>> should be locked down, thereby disallowing various accesses that might
>> allow the running kernel image to be changed, including:
>>
>>  - /dev/mem and similar
>>  - Loading of unauthorised modules
>>  - Fiddling with MSR registers
>>  - Suspend to disk managed by the kernel
>>  - Use of device DMA
>
> So what I stlll absolutely detest about  this series is that I think
> many of these things should simply be done as separate config options.
>
> For example, if the distro is sure that it doesn't need /dev/mem, then
> why the hell is  this tied to "lockdown" that then may have to be
> disabled because *other* changes may not be acceptable (eg people may
> need that device DMA, or whatever).
>
> If that /dev/mem access prevention was just instead done as an even
> stricter mode of the existing CONFIG_STRICT_DEVMEM, it could just be
> enabled unconditionally.
>
> So none of these patches raise my hackles per se. But what continues
> to makes me very very uncomfortable is how this is all tied together.
>
> Why is this one magical mode that then - because it has such a big
> impact - has to be enabled/disabled as a single magical mode and with
> very odd rules?
>
> I think a lot of people would be happier if this wasn't so incestuous
> and mixing together independent things under one name, and one flag.
>
> I think a lot of the secure boot problems were exacerbated by that mixup.
>
> So I would seriously ask that the distros that have been using these
> patches look at which parts of lockdown they could make unconditional
> (because it doesn't break machines), and which ones need that escape
> clause.
>

Optionally, it might make sense to add separate config options for
each of these pieces which can be unconditionally enabled, and a
separate option for secure boot which selects all of them? As much as
I hate select, it might make sense here.  Of course the flip side to
that, is users no longer have one big switch "turn off secure boot"
which turns it all off in case of trouble.

Justin
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Miguel Ojeda April 11, 2018, 6:50 p.m. UTC | #6
On Wed, Apr 11, 2018 at 7:37 PM, Randy Dunlap <rdunlap@infradead.org> wrote:
> On 04/11/2018 09:24 AM, David Howells wrote:
>
>> diff --git a/security/lock_down.c b/security/lock_down.c
>> new file mode 100644
>> index 000000000000..f35ffdd096ad
>> --- /dev/null
>> +++ b/security/lock_down.c
>> @@ -0,0 +1,65 @@
>> +/* Lock down the kernel
>> + *
>> + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
>> + * Written by David Howells (dhowells@redhat.com)
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public Licence
>> + * as published by the Free Software Foundation; either version
>> + * 2 of the Licence, or (at your option) any later version.
>
> fsf.org spells that Licence word as License. :)

Given this is a new file, simply use the SPF identifier on top.

Cheers,
Miguel
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg Kroah-Hartman April 11, 2018, 7:56 p.m. UTC | #7
On Wed, Apr 11, 2018 at 08:50:00PM +0200, Miguel Ojeda wrote:
> On Wed, Apr 11, 2018 at 7:37 PM, Randy Dunlap <rdunlap@infradead.org> wrote:
> > On 04/11/2018 09:24 AM, David Howells wrote:
> >
> >> diff --git a/security/lock_down.c b/security/lock_down.c
> >> new file mode 100644
> >> index 000000000000..f35ffdd096ad
> >> --- /dev/null
> >> +++ b/security/lock_down.c
> >> @@ -0,0 +1,65 @@
> >> +/* Lock down the kernel
> >> + *
> >> + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
> >> + * Written by David Howells (dhowells@redhat.com)
> >> + *
> >> + * This program is free software; you can redistribute it and/or
> >> + * modify it under the terms of the GNU General Public Licence
> >> + * as published by the Free Software Foundation; either version
> >> + * 2 of the Licence, or (at your option) any later version.
> >
> > fsf.org spells that Licence word as License. :)
> 
> Given this is a new file, simply use the SPF identifier on top.

checkpatch.pl should now check for this as well.
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jordan Glover April 11, 2018, 9:05 p.m. UTC | #8
On April 11, 2018 8:09 PM, Linus Torvalds <torvalds@linux-foundation.org> wrote:

> On Wed, Apr 11, 2018 at 9:24 AM, David Howells dhowells@redhat.com wrote:
> 
> > Provide a single call to allow kernel code to determine whether the system
> > 
> > should be locked down, thereby disallowing various accesses that might
> > 
> > allow the running kernel image to be changed, including:
> > 
> > -   /dev/mem and similar
> > -   Loading of unauthorised modules
> > -   Fiddling with MSR registers
> > -   Suspend to disk managed by the kernel
> > -   Use of device DMA
> 
> So what I stlll absolutely detest about this series is that I think
> 
> many of these things should simply be done as separate config options.
> 
> For example, if the distro is sure that it doesn't need /dev/mem, then
> 
> why the hell is this tied to "lockdown" that then may have to be
> 
> disabled because other changes may not be acceptable (eg people may
> 
> need that device DMA, or whatever).
> 
> If that /dev/mem access prevention was just instead done as an even
> 
> stricter mode of the existing CONFIG_STRICT_DEVMEM, it could just be
> 
> enabled unconditionally.

CONFIG_DEVMEM=n

> 
> So none of these patches raise my hackles per se. But what continues
> 
> to makes me very very uncomfortable is how this is all tied together.
> 
> Why is this one magical mode that then - because it has such a big
> 
> impact - has to be enabled/disabled as a single magical mode and with
> 
> very odd rules?
> 
> I think a lot of people would be happier if this wasn't so incestuous
> 
> and mixing together independent things under one name, and one flag.
> 
> I think a lot of the secure boot problems were exacerbated by that mixup.
> 
> So I would seriously ask that the distros that have been using these
> 
> patches look at which parts of lockdown they could make unconditional
> 
> (because it doesn't break machines), and which ones need that escape
> 
> clause.
> 
> Linus
> 

​Jordan
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Torvalds April 11, 2018, 10:38 p.m. UTC | #9
On Wed, Apr 11, 2018 at 2:05 PM, Jordan Glover
<Golden_Miller83@protonmail.ch> wrote:
>>
>> If that /dev/mem access prevention was just instead done as an even
>> stricter mode of the existing CONFIG_STRICT_DEVMEM, it could just be
>> enabled unconditionally.
>
> CONFIG_DEVMEM=n

It's actually CONFIG_DEVMEM, CONFIG_DEVKMEM and CONFIG_DEVPORT, it's
just not obvious from the patch.

But the important part is this part:

>> So I would seriously ask that the distros that have been using these
>> patches look at which parts of lockdown they could make unconditional
>> (because it doesn't break machines), and which ones need that escape
>> clause.

.. because I get the feeling that not a lot of people have actually
been testing this, because "turn off secure boot" is such a universal
thing when people boot Linux.

So it's really the whole claim that distributions have been running
for this for the last five years that I wonder about, and how often
people end up being told: "just disable secure boot":.

But if people really don't need DEVMEM/DEVKMEM/DEVPORT, maybe we
should just disable them in the default configs, and consider them
legacy.

I'm just surprised. I suspect a lot of people end up actually using
devmem as a fallback for dmidecode etc. Maybe those people don't boot
with EFI secure mode, but if so that just shows that this whole
"hardening" is just security theater.

              Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andy Lutomirski April 12, 2018, 2:57 a.m. UTC | #10
On Wed, Apr 11, 2018 at 9:24 AM, David Howells <dhowells@redhat.com> wrote:
>
>  (*) CONFIG_LOCK_DOWN_KERNEL
>
>      This makes lockdown available and applies it to all the points that
>      need to be locked down if the mode is set.  Lockdown mode can be
>      enabled by providing:
>
>         lockdown=1

By doing this, you are basically committing to making the
protect-kernel-integrity vs protect-kernel-secrecy split be a
second-class citizen if it gets added.

How about lockdown=integrity_and_secrecy or lockdown=2 if you feel
like using numbers?
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Justin Forbes April 12, 2018, 1:09 p.m. UTC | #11
On Wed, Apr 11, 2018, 5:38 PM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Wed, Apr 11, 2018 at 2:05 PM, Jordan Glover
> <Golden_Miller83@protonmail.ch> wrote:
> >>
> >> If that /dev/mem access prevention was just instead done as an even
> >> stricter mode of the existing CONFIG_STRICT_DEVMEM, it could just be
> >> enabled unconditionally.
> >
> > CONFIG_DEVMEM=n
>
> It's actually CONFIG_DEVMEM, CONFIG_DEVKMEM and CONFIG_DEVPORT, it's
> just not obvious from the patch.
>
> But the important part is this part:
>
> >> So I would seriously ask that the distros that have been using these
> >> patches look at which parts of lockdown they could make unconditional
> >> (because it doesn't break machines), and which ones need that escape
> >> clause.
>
> .. because I get the feeling that not a lot of people have actually
> been testing this, because "turn off secure boot" is such a universal
> thing when people boot Linux.
>
> So it's really the whole claim that distributions have been running
> for this for the last five years that I wonder about, and how often
> people end up being told: "just disable secure boot":.

Very rarely in my experience. And the one time that we sent a kernel
to updates-testing that was signed with the test key instead of the
real key, we had a surprisingly high number of reports from users that
it was broken before the update even got synched to mirrors.  So we
don't have actual numbers of users running active secure boot with
Fedora, but we do know it is more than we expected.  The majority of
people who do run into issues are those running out of tree modules,
who haven't imported any sort of key for local signing.  This isn't
like SELinux was at launch where it was so invasive that a large
number of users instinctively turned it off with every installation, I
would guess even people who turned it off in the past, don't even
think about it when they get a new machine and leave it on.

> But if people really don't need DEVMEM/DEVKMEM/DEVPORT, maybe we
> should just disable them in the default configs, and consider them
> legacy.
>
> I'm just surprised. I suspect a lot of people end up actually using
> devmem as a fallback for dmidecode etc. Maybe those people don't boot
> with EFI secure mode, but if so that just shows that this whole
> "hardening" is just security theater.
>
>               Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Linus Torvalds April 12, 2018, 4:52 p.m. UTC | #12
On Thu, Apr 12, 2018 at 6:09 AM, Justin Forbes <jmforbes@linuxtx.org> wrote:
> On Wed, Apr 11, 2018, 5:38 PM Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>>
>> So it's really the whole claim that distributions have been running
>> for this for the last five years that I wonder about, and how often
>> people end up being told: "just disable secure boot":.
>
> Very rarely in my experience.

Good. Do you have a handle on the reasons?

Because I'm assuming it's not /dev/{mem,kmem,port}? Because I'd really
be happier if we just say "those are legacy, don't enable them at all
for modern distros".

That way they'd _stay_ disabled even if somebody cannot handle the
other limitations, like DMA etc.

                 Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 6285697b6e56..566f0f447053 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -996,6 +996,8 @@  void __init setup_arch(char **cmdline_p)
 	if (efi_enabled(EFI_BOOT))
 		efi_init();
 
+	init_lockdown();
+
 	dmi_scan_machine();
 	dmi_memdev_walk();
 	dmi_set_dump_stack_arch_desc();
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4ae1dfd9bf05..7d085cca9cee 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -306,6 +306,38 @@  static inline void refcount_error_report(struct pt_regs *regs, const char *err)
 { }
 #endif
 
+#ifdef CONFIG_LOCK_DOWN_KERNEL
+extern void __init init_lockdown(void);
+extern bool __kernel_is_locked_down(const char *what, bool first);
+
+#ifndef CONFIG_LOCK_DOWN_MANDATORY
+#define kernel_is_locked_down(what)					\
+	({								\
+		static bool message_given;				\
+		bool locked_down = __kernel_is_locked_down(what, !message_given); \
+		message_given = true;					\
+		locked_down;						\
+	})
+#else
+#define kernel_is_locked_down(what)					\
+	({								\
+		static bool message_given;				\
+		__kernel_is_locked_down(what, !message_given);		\
+		message_given = true;					\
+		true;							\
+	})
+#endif
+#else
+static inline void __init init_lockdown(void)
+{
+}
+static inline bool __kernel_is_locked_down(const char *what, bool first)
+{
+	return false;
+}
+#define kernel_is_locked_down(what) ({ false; })
+#endif
+
 /* Internal, do not use. */
 int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
 int __must_check _kstrtol(const char *s, unsigned int base, long *res);
diff --git a/security/Kconfig b/security/Kconfig
index c4302067a3ad..a68e5bdebad5 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -231,6 +231,28 @@  config STATIC_USERMODEHELPER_PATH
 	  If you wish for all usermode helper programs to be disabled,
 	  specify an empty string here (i.e. "").
 
+config LOCK_DOWN_KERNEL
+	bool "Allow the kernel to be 'locked down'"
+	help
+	  Allow the kernel to be locked down.  Locking down the kernel turns
+	  off various features that might otherwise allow access to the kernel
+	  image (eg. setting MSR registers).
+
+	  Note, however, that locking down your kernel will prevent some
+	  drivers from functioning because allowing manual configuration of
+	  hardware parameters is forbidden, lest a device be used to access the
+	  kernel by DMA.  This mostly applies to ISA devices.
+
+	  The kernel lockdown can be triggered by adding lockdown=1 to the
+	  kernel command line.
+
+config LOCK_DOWN_MANDATORY
+	bool "Make kernel lockdown mandatory"
+	depends on LOCK_DOWN_KERNEL
+	help
+	  Makes the lockdown non-negotiable.  It is always on and cannot be
+	  disabled.
+
 source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
@@ -278,4 +300,3 @@  config DEFAULT_SECURITY
 	default "" if DEFAULT_SECURITY_DAC
 
 endmenu
-
diff --git a/security/Makefile b/security/Makefile
index 4d2d3782ddef..507ac8c520ce 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -30,3 +30,6 @@  obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 # Object integrity file lists
 subdir-$(CONFIG_INTEGRITY)		+= integrity
 obj-$(CONFIG_INTEGRITY)			+= integrity/
+
+# Allow the kernel to be locked down
+obj-$(CONFIG_LOCK_DOWN_KERNEL)		+= lock_down.o
diff --git a/security/lock_down.c b/security/lock_down.c
new file mode 100644
index 000000000000..f35ffdd096ad
--- /dev/null
+++ b/security/lock_down.c
@@ -0,0 +1,65 @@ 
+/* Lock down the kernel
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/export.h>
+#include <linux/sched.h>
+
+#ifndef CONFIG_LOCK_DOWN_MANDATORY
+static __ro_after_init bool kernel_locked_down;
+#else
+#define kernel_locked_down true
+#endif
+
+/*
+ * Put the kernel into lock-down mode.
+ */
+static void __init lock_kernel_down(const char *where)
+{
+#ifndef CONFIG_LOCK_DOWN_MANDATORY
+	if (!kernel_locked_down) {
+		kernel_locked_down = true;
+		pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",
+			  where);
+	}
+#endif
+}
+
+static int __init lockdown_param(char *ignored)
+{
+	lock_kernel_down("command line");
+	return 0;
+}
+
+early_param("lockdown", lockdown_param);
+
+/*
+ * Lock the kernel down from very early in the arch setup.  This must happen
+ * prior to things like ACPI being initialised.
+ */
+void __init init_lockdown(void)
+{
+#ifdef CONFIG_LOCK_DOWN_MANDATORY
+	pr_notice("Kernel is locked down from config; see man kernel_lockdown.7\n");
+#endif
+}
+
+/**
+ * kernel_is_locked_down - Find out if the kernel is locked down
+ * @what: Tag to use in notice generated if lockdown is in effect
+ */
+bool __kernel_is_locked_down(const char *what, bool first)
+{
+	if (what && first && kernel_locked_down)
+		pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n",
+			  current->comm, what);
+	return kernel_locked_down;
+}
+EXPORT_SYMBOL(__kernel_is_locked_down);