linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] Kernel lockdown
@ 2016-11-16 21:47 David Howells
  2016-11-16 21:47 ` [PATCH 01/16] Add the ability to lock down access to the running kernel image David Howells
                   ` (16 more replies)
  0 siblings, 17 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings-u79uwXL29TY76Z2rM5mHXA
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA


These patches provide a facility by which a variety of avenues by which
userspace can feasibly modify the running kernel image can be locked down.
These include:

 (*) No unsigned modules and no modules for which can't validate the
     signature.

 (*) No use of ioperm(), iopl() and no writing to /dev/port.

 (*) No writing to /dev/mem or /dev/kmem.

 (*) No hibernation.

 (*) Restrict PCI BAR access.

 (*) Restrict MSR access.

 (*) No kexec_load().

 (*) Certain ACPI restrictions.

 (*) Restrict debugfs interface to ASUS WMI.

The lock-down can be configured to be triggered by the EFI secure boot
status, provided the shim isn't insecure.  The lock-down can be lifted by
typing SysRq+x on a keyboard attached to the system.


The patches can be found here also:

	http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-lockdown

They are dependent for some EFI definitions on the keys-uefi branch.

David
---
Dave Young (1):
      Copy secure_boot flag in boot params across kexec reboot

David Howells (3):
      Add the ability to lock down access to the running kernel image
      efi: Get the secure boot status
      efi: Lock down the kernel if booted in secure boot mode

Josh Boyer (4):
      efi: Disable secure boot if shim is in insecure mode
      efi: Add EFI_SECURE_BOOT bit
      hibernate: Disable when the kernel is locked down
      acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down

Kyle McMartin (1):
      Add a sysrq option to exit secure boot mode

Matthew Garrett (7):
      kexec: Disable at runtime if the kernel is locked down
      PCI: Lock down BAR access when the kernel is locked down
      x86: Lock down IO port access when the kernel is locked down
      ACPI: Limit access to custom_method when the kernel is locked down
      asus-wmi: Restrict debugfs interface when the kernel is locked down
      Restrict /dev/mem and /dev/kmem when the kernel is locked down
      x86: Restrict MSR access when the kernel is locked down


 Documentation/x86/zero-page.txt       |    2 +
 arch/x86/Kconfig                      |   22 ++++++++++++++
 arch/x86/boot/compressed/eboot.c      |   53 +++++++++++++++++++++++++++++++++
 arch/x86/include/uapi/asm/bootparam.h |    3 +-
 arch/x86/kernel/ioport.c              |    5 ++-
 arch/x86/kernel/kexec-bzimage64.c     |    1 +
 arch/x86/kernel/msr.c                 |    8 +++++
 arch/x86/kernel/setup.c               |   39 ++++++++++++++++++++++++
 drivers/acpi/custom_method.c          |    3 ++
 drivers/acpi/osl.c                    |    3 +-
 drivers/char/mem.c                    |   10 ++++++
 drivers/input/misc/uinput.c           |    1 +
 drivers/pci/pci-sysfs.c               |   10 ++++++
 drivers/pci/proc.c                    |    9 +++++-
 drivers/pci/syscall.c                 |    3 +-
 drivers/platform/x86/asus-wmi.c       |    9 ++++++
 drivers/tty/sysrq.c                   |   19 ++++++++----
 include/linux/efi.h                   |    1 +
 include/linux/input.h                 |    5 +++
 include/linux/security.h              |   16 ++++++++++
 include/linux/sysrq.h                 |    8 ++++-
 kernel/debug/kdb/kdb_main.c           |    2 +
 kernel/kexec.c                        |    8 +++++
 kernel/module.c                       |    2 +
 kernel/power/hibernate.c              |    3 +-
 security/Kconfig                      |   16 +++++++++-
 security/Makefile                     |    3 ++
 security/lock_down.c                  |   40 +++++++++++++++++++++++++
 28 files changed, 287 insertions(+), 17 deletions(-)
 create mode 100644 security/lock_down.c

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

* [PATCH 01/16] Add the ability to lock down access to the running kernel image
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
@ 2016-11-16 21:47 ` David Howells
       [not found]   ` <147933284407.19316.17886320817060158597.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
                     ` (3 more replies)
  2016-11-16 21:47 ` [PATCH 02/16] efi: Get the secure boot status David Howells
                   ` (15 subsequent siblings)
  16 siblings, 4 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

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 the loading of
modules that aren't validly signed with a key we recognise, fiddling with
MSR registers and disallowing hibernation,

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

 include/linux/security.h |   16 ++++++++++++++++
 security/Kconfig         |   16 +++++++++++++++-
 security/Makefile        |    3 +++
 security/lock_down.c     |   40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 security/lock_down.c

diff --git a/include/linux/security.h b/include/linux/security.h
index c2125e9093e8..785868b44364 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1685,5 +1685,21 @@ static inline void free_secdata(void *secdata)
 { }
 #endif /* CONFIG_SECURITY */
 
+#ifdef CONFIG_LOCK_DOWN_KERNEL
+extern void lock_kernel_down(void);
+extern bool kernel_is_locked_down(void);
+#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT
+extern void lift_kernel_lockdown(void);
+#endif
+#else
+static inline void lock_kernel_down(void)
+{
+}
+static inline bool kernel_is_locked_down(void)
+{
+	return false;
+}
+#endif
+
 #endif /* ! __LINUX_SECURITY_H */
 
diff --git a/security/Kconfig b/security/Kconfig
index 118f4549404e..21fac88e3062 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -158,6 +158,21 @@ config HARDENED_USERCOPY_PAGESPAN
 	  been removed. This config is intended to be used only while
 	  trying to find such users.
 
+config LOCK_DOWN_KERNEL
+	bool "Allow the kernel to be 'locked down'"
+	help
+	  Allow the kernel to be locked down under certain circumstances, for
+	  instance if UEFI secure boot is enabled.  Locking down the kernel
+	  turns off various features that might otherwise allow access to the
+	  kernel image (eg. setting MSR registers).
+
+config ALLOW_LOCKDOWN_LIFT
+	bool
+	help
+	  Allow the lockdown on a kernel to be lifted, thereby restoring the
+	  ability of userspace to access the kernel image (eg. by SysRq+x under
+	  x86).
+
 source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
@@ -205,4 +220,3 @@ config DEFAULT_SECURITY
 	default "" if DEFAULT_SECURITY_DAC
 
 endmenu
-
diff --git a/security/Makefile b/security/Makefile
index f2d71cdb8e19..8c4a43e3d4e0 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -29,3 +29,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..d63d12fdbba1
--- /dev/null
+++ b/security/lock_down.c
@@ -0,0 +1,40 @@
+/* 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/security.h>
+#include <linux/export.h>
+
+static __read_mostly bool kernel_locked_down;
+
+/*
+ * Put the kernel into lock-down mode.
+ */
+void lock_kernel_down(void)
+{
+	kernel_locked_down = true;
+}
+
+/*
+ * Take the kernel out of lockdown mode.
+ */
+void lift_kernel_lockdown(void)
+{
+	kernel_locked_down = false;
+}
+
+/**
+ * kernel_is_locked_down - Find out if the kernel is locked down
+ */
+bool kernel_is_locked_down(void)
+{
+	return kernel_locked_down;
+}
+EXPORT_SYMBOL(kernel_locked_down);

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

* [PATCH 02/16] efi: Get the secure boot status
  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 21:47 ` David Howells
  2016-11-17 12:37   ` Lukas Wunner
                     ` (2 more replies)
  2016-11-16 21:47 ` [PATCH 03/16] efi: Disable secure boot if shim is in insecure mode David Howells
                   ` (14 subsequent siblings)
  16 siblings, 3 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

Get the firmware's secure-boot status in the kernel boot wrapper and stash
it somewhere that the main kernel image can find.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 Documentation/x86/zero-page.txt       |    2 ++
 arch/x86/boot/compressed/eboot.c      |   35 +++++++++++++++++++++++++++++++++
 arch/x86/include/uapi/asm/bootparam.h |    3 ++-
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
index 95a4d34af3fd..b8527c6b7646 100644
--- 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
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index cc69e37548db..17b376596c96 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -12,6 +12,7 @@
 #include <asm/efi.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/bootparam_utils.h>
 
 #include "../string.h"
 #include "eboot.h"
@@ -537,6 +538,36 @@ static void setup_efi_pci(struct boot_params *params)
 	efi_call_early(free_pool, pci_handle);
 }
 
+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;
+}
+
 static efi_status_t
 setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
 {
@@ -1094,6 +1125,10 @@ struct boot_params *efi_main(struct efi_config *c,
 	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);
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index c18ce67495fa..2b3e5427097b 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -134,7 +134,8 @@ struct boot_params {
 	__u8  eddbuf_entries;				/* 0x1e9 */
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
 	__u8  kbd_status;				/* 0x1eb */
-	__u8  _pad5[3];					/* 0x1ec */
+	__u8  secure_boot;				/* 0x1ec */
+	__u8  _pad5[2];					/* 0x1ed */
 	/*
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
 	 *


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

* [PATCH 03/16] efi: Disable secure boot if shim is in insecure mode
  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 21:47 ` [PATCH 02/16] efi: Get the secure boot status David Howells
@ 2016-11-16 21:47 ` David Howells
  2016-11-16 21:47 ` [PATCH 04/16] efi: Lock down the kernel if booted in secure boot mode David Howells
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings
  Cc: matthew.garrett, linux-efi, linux-kernel, dhowells,
	linux-security-module, Josh Boyer

From: Josh Boyer <jwboyer@fedoraproject.org>

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>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/x86/boot/compressed/eboot.c |   20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 17b376596c96..2729a3844673 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -540,8 +540,9 @@ static void setup_efi_pci(struct boot_params *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;
 
@@ -565,6 +566,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;
 }
 


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

* [PATCH 04/16] efi: Lock down the kernel if booted in secure boot mode
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (2 preceding siblings ...)
  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 ` David Howells
  2016-11-16 21:47 ` [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit David Howells
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

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 all kernel modules also be signed.  Add a configuration option
that to lock down the kernel - which includes requiring validly signed
modules - if the kernel is secure-booted.

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

 arch/x86/Kconfig        |   12 ++++++++++++
 arch/x86/kernel/setup.c |    7 +++++++
 kernel/module.c         |    2 +-
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bada636d1065..5b19997d88d0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1786,6 +1786,18 @@ config EFI_MIXED
 
 	   If unsure, say N.
 
+config EFI_SECURE_BOOT_LOCK_DOWN
+	def_bool n
+	depends on EFI
+	prompt "Lock down the kernel 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 all kernel modules also be signed and that
+	  userspace is prevented from directly changing the running kernel
+	  image.  Say Y here to automatically lock down the kernel when a
+	  system boots with UEFI Secure Boot enabled.
+
 config SECCOMP
 	def_bool y
 	prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 9c337b0e8ba7..9521acce8378 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -69,6 +69,7 @@
 #include <linux/crash_dump.h>
 #include <linux/tboot.h>
 #include <linux/jiffies.h>
+#include <linux/security.h>
 
 #include <video/edid.h>
 
@@ -1160,6 +1161,12 @@ void __init setup_arch(char **cmdline_p)
 
 	io_delay_init();
 
+	if (boot_params.secure_boot &&
+	    IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
+		lock_kernel_down();
+		pr_info("Secure boot enabled\n");
+	}
+
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
diff --git a/kernel/module.c b/kernel/module.c
index f57dd63186e6..2a021c340efd 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2744,7 +2744,7 @@ static int module_sig_check(struct load_info *info, int flags)
 	}
 
 	/* Not having a signature is only an error if we're strict. */
-	if (err == -ENOKEY && !sig_enforce)
+	if (err == -ENOKEY && !sig_enforce && !kernel_is_locked_down())
 		err = 0;
 
 	return err;


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

* [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (3 preceding siblings ...)
  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 ` David Howells
  2016-11-17 21:58   ` Ard Biesheuvel
       [not found]   ` <CAKv+Gu_8r3oM-jvvuSiXTzxp0YMEVgc5KkScJ2UhGTaXm28L6w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2016-11-16 21:48 ` [PATCH 06/16] Add a sysrq option to exit secure boot mode David Howells
                   ` (11 subsequent siblings)
  16 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:47 UTC (permalink / raw)
  To: keyrings
  Cc: matthew.garrett, linux-efi, linux-kernel, dhowells,
	linux-security-module, Josh Boyer

From: Josh Boyer <jwboyer@fedoraproject.org>

UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
for use with efi_enabled.

Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/x86/kernel/setup.c |    1 +
 include/linux/efi.h     |    1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 9521acce8378..539f29587712 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1164,6 +1164,7 @@ void __init setup_arch(char **cmdline_p)
 	if (boot_params.secure_boot &&
 	    IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
 		lock_kernel_down();
+		set_bit(EFI_SECURE_BOOT, &efi.flags);
 		pr_info("Secure boot enabled\n");
 	}
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 11372fb8784c..5d7fb3e3400b 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1079,6 +1079,7 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_ARCH_1		7	/* First arch-specific bit */
 #define EFI_DBG			8	/* Print additional debug info at runtime */
 #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
+#define EFI_SECURE_BOOT		10	/* Are we in Secure Boot mode? */
 
 #ifdef CONFIG_EFI
 /*

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

* [PATCH 06/16] Add a sysrq option to exit secure boot mode
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (4 preceding siblings ...)
  2016-11-16 21:47 ` [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit David Howells
@ 2016-11-16 21:48 ` David Howells
  2016-11-16 21:48 ` [PATCH 07/16] kexec: Disable at runtime if the kernel is locked down David Howells
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

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;

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

* [PATCH 07/16] kexec: Disable at runtime if the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (5 preceding siblings ...)
  2016-11-16 21:48 ` [PATCH 06/16] Add a sysrq option to exit secure boot mode David Howells
@ 2016-11-16 21:48 ` David Howells
  2016-11-16 21:48 ` [PATCH 08/16] Copy secure_boot flag in boot params across kexec reboot David Howells
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

From: Matthew Garrett <matthew.garrett@nebula.com>

kexec permits the loading and execution of arbitrary code in ring 0, which
is something that lock-down is meant to prevent. It makes sense to disable
kexec in this situation.

This does not affect kexec_file_load() which can check for a signature on the
image to be booted.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 kernel/kexec.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/kexec.c b/kernel/kexec.c
index 980936a90ee6..c6aa4620d1bf 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/file.h>
 #include <linux/kexec.h>
+#include <linux/security.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/syscalls.h>
@@ -194,6 +195,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 		return -EPERM;
 
 	/*
+	 * kexec can be used to circumvent module loading restrictions, so
+	 * prevent loading in that case
+	 */
+	if (kernel_is_locked_down())
+		return -EPERM;
+
+	/*
 	 * Verify we have a legal set of flags
 	 * This leaves us room for future extensions.
 	 */

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

* [PATCH 08/16] Copy secure_boot flag in boot params across kexec reboot
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (6 preceding siblings ...)
  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 ` David Howells
  2016-11-16 21:48 ` [PATCH 09/16] hibernate: Disable when the kernel is locked down David Howells
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: matthew.garrett, linux-efi, linux-kernel, dhowells,
	linux-security-module, Dave Young

From: Dave Young <dyoung@redhat.com>

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>
Signed-off-by: David Howells <dhowells@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 3407b148c240..b843a4e57a9b 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -179,6 +179,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;

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

* [PATCH 09/16] hibernate: Disable when the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (7 preceding siblings ...)
  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 ` David Howells
  2016-11-16 21:48 ` [PATCH 10/16] PCI: Lock down BAR access " David Howells
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: matthew.garrett, linux-efi, linux-kernel, dhowells,
	linux-security-module, Josh Boyer

From: Josh Boyer <jwboyer@fedoraproject.org>

There is currently no way to verify the resume image when returning
from hibernate.  This might compromise the signed modules trust model,
so until we can work with signed hibernate images we disable it when the
kernel is locked down.

Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 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 b26dbc48c75b..a6ac5bd3f2a0 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"
@@ -67,7 +68,7 @@ static const struct platform_hibernation_ops *hibernation_ops;
 
 bool hibernation_available(void)
 {
-	return (nohibernate == 0);
+	return nohibernate == 0 && !kernel_is_locked_down();
 }
 
 /**

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

* [PATCH 10/16] PCI: Lock down BAR access when the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (8 preceding siblings ...)
  2016-11-16 21:48 ` [PATCH 09/16] hibernate: Disable when the kernel is locked down David Howells
@ 2016-11-16 21:48 ` David Howells
       [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

From: Matthew Garrett <matthew.garrett@nebula.com>

Any hardware that can potentially generate DMA has to be locked down in
order to avoid it being possible for an attacker to modify kernel code,
allowing them to circumvent disabled module loading or module signing.
Default to paranoid - in future we can potentially relax this for
sufficiently IOMMU-isolated devices.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/pci/pci-sysfs.c |   10 ++++++++++
 drivers/pci/proc.c      |    9 ++++++++-
 drivers/pci/syscall.c   |    3 ++-
 3 files changed, 20 insertions(+), 2 deletions(-)

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

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

* [PATCH 11/16] x86: Lock down IO port access when the kernel is locked down
       [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-16 21:48   ` David Howells
  2016-11-16 21:49   ` [PATCH 16/16] x86: Restrict MSR " David Howells
  2016-11-16 22:27   ` [PATCH 00/16] Kernel lockdown One Thousand Gnomes
  2 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings-u79uwXL29TY76Z2rM5mHXA
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Matthew Garrett <matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org>

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 by default.

Signed-off-by: Matthew Garrett <matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org>
Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---

 arch/x86/kernel/ioport.c |    5 +++--
 drivers/char/mem.c       |    4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 589b3193f102..2ee24e9ff6d8 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -15,6 +15,7 @@
 #include <linux/thread_info.h>
 #include <linux/syscalls.h>
 #include <linux/bitmap.h>
+#include <linux/security.h>
 #include <asm/syscalls.h>
 
 /*
@@ -28,7 +29,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
 		return -EINVAL;
-	if (turn_on && !capable(CAP_SYS_RAWIO))
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down()))
 		return -EPERM;
 
 	/*
@@ -108,7 +109,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
 		return -EINVAL;
 	/* Trying to gain more privileges? */
 	if (level > old) {
-		if (!capable(CAP_SYS_RAWIO))
+		if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
 			return -EPERM;
 	}
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5bb1985ec484..17e22cb2db14 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -28,6 +28,7 @@
 #include <linux/export.h>
 #include <linux/io.h>
 #include <linux/uio.h>
+#include <linux/security.h>
 
 #include <linux/uaccess.h>
 
@@ -580,6 +581,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
 	unsigned long i = *ppos;
 	const char __user *tmp = buf;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
 	while (count-- > 0 && i < 65536) {

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

* [PATCH 12/16] ACPI: Limit access to custom_method when the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (10 preceding siblings ...)
       [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-16 21:48 ` David Howells
  2016-11-16 21:48 ` [PATCH 13/16] asus-wmi: Restrict debugfs interface " David Howells
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

From: Matthew Garrett <matthew.garrett@nebula.com>

custom_method effectively allows arbitrary access to system memory, making
it possible for an attacker to circumvent restrictions on module loading.
Disable it if the kernel is locked down.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/acpi/custom_method.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
index c68e72414a67..e4d721c330c0 100644
--- a/drivers/acpi/custom_method.c
+++ b/drivers/acpi/custom_method.c
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
 	struct acpi_table_header table;
 	acpi_status status;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	if (!(*ppos)) {
 		/* parse the table header to get the table length */
 		if (count <= sizeof(struct acpi_table_header))

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

* [PATCH 13/16] asus-wmi: Restrict debugfs interface when the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (11 preceding siblings ...)
  2016-11-16 21:48 ` [PATCH 12/16] ACPI: Limit access to custom_method when the kernel is locked down David Howells
@ 2016-11-16 21:48 ` David Howells
  2016-11-16 21:48 ` [PATCH 14/16] Restrict /dev/mem and /dev/kmem " David Howells
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

From: Matthew Garrett <matthew.garrett@nebula.com>

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, circumventing module loading restrictions.  Prevent that if the
kernel is locked down.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/platform/x86/asus-wmi.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index ce6ca31a2d09..d860017f5240 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -1872,6 +1872,9 @@ static int show_dsts(struct seq_file *m, void *data)
 	int err;
 	u32 retval = -1;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
 
 	if (err < 0)
@@ -1888,6 +1891,9 @@ static int show_devs(struct seq_file *m, void *data)
 	int err;
 	u32 retval = -1;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
 				    &retval);
 
@@ -1912,6 +1918,9 @@ static int show_call(struct seq_file *m, void *data)
 	union acpi_object *obj;
 	acpi_status status;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
 				     1, asus->debug.method_id,
 				     &input, &output);

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

* [PATCH 14/16] Restrict /dev/mem and /dev/kmem when the kernel is locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (12 preceding siblings ...)
  2016-11-16 21:48 ` [PATCH 13/16] asus-wmi: Restrict debugfs interface " David Howells
@ 2016-11-16 21:48 ` David Howells
  2016-11-16 21:49 ` [PATCH 15/16] acpi: Ignore acpi_rsdp kernel param when the kernel has been " David Howells
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:48 UTC (permalink / raw)
  To: keyrings
  Cc: dhowells, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

From: Matthew Garrett <matthew.garrett@nebula.com>

Allowing users to write to address space makes it possible for the kernel to
be subverted, avoiding module loading restrictions.  Prevent this when the
kernel has been locked down.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/char/mem.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 17e22cb2db14..5dcc205e8373 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -164,6 +164,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
 	if (p != *ppos)
 		return -EFBIG;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	if (!valid_phys_addr_range(p, count))
 		return -EFAULT;
 
@@ -516,6 +519,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
 	if (!pfn_valid(PFN_DOWN(p)))
 		return -EIO;
 
+	if (kernel_is_locked_down())
+		return -EPERM;
+
 	if (p < (unsigned long) high_memory) {
 		unsigned long to_write = min_t(unsigned long, count,
 					       (unsigned long)high_memory - p);

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

* [PATCH 15/16] acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (13 preceding siblings ...)
  2016-11-16 21:48 ` [PATCH 14/16] Restrict /dev/mem and /dev/kmem " David Howells
@ 2016-11-16 21:49 ` David Howells
  2016-11-16 22:28 ` [PATCH 00/16] Kernel lockdown Justin Forbes
  2016-11-21 23:10 ` [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed David Howells
  16 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:49 UTC (permalink / raw)
  To: keyrings
  Cc: matthew.garrett, linux-efi, Josh Boyer, linux-kernel, dhowells,
	linux-security-module

From: Josh Boyer <jwboyer@redhat.com>

This option allows userspace to pass the RSDP address to the kernel, which
makes it possible for a user to circumvent any restrictions imposed on
loading modules.  Ignore the option when the kernel is locked down.

Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Signed-off-by: David Howells <dhowells@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 416953a42510..fb1dc79a7f1b 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>
@@ -191,7 +192,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 && !kernel_is_locked_down())
 		return acpi_rsdp;
 #endif
 

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

* [PATCH 16/16] x86: Restrict MSR access when the kernel is locked down
       [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-16 21:48   ` [PATCH 11/16] x86: Lock down IO port " David Howells
@ 2016-11-16 21:49   ` David Howells
  2016-11-16 22:27   ` [PATCH 00/16] Kernel lockdown One Thousand Gnomes
  2 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 21:49 UTC (permalink / raw)
  To: keyrings-u79uwXL29TY76Z2rM5mHXA
  Cc: matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA, Kees Cook,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA

From: Matthew Garrett <matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org>

Writing to MSRs should not be allowed if the kernel is locked down, since
it could lead to execution of arbitrary code in kernel mode.  Based on a
patch by Kees Cook.

Cc: Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Signed-off-by: Matthew Garrett <matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org>
Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---

 arch/x86/kernel/msr.c |    8 ++++++++
 1 file changed, 8 insertions(+)

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

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

* Re: [PATCH 01/16] Add the ability to lock down access to the running kernel image
       [not found]   ` <147933284407.19316.17886320817060158597.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-16 22:20     ` Borislav Petkov
  0 siblings, 0 replies; 76+ messages in thread
From: Borislav Petkov @ 2016-11-16 22:20 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Wed, Nov 16, 2016 at 09:47:24PM +0000, David Howells 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 the loading of
> modules that aren't validly signed with a key we recognise, fiddling with
> MSR registers and disallowing hibernation,
> 
> Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---

...

> +/**
> + * kernel_is_locked_down - Find out if the kernel is locked down
> + */
> +bool kernel_is_locked_down(void)
> +{
> +	return kernel_locked_down;
> +}
> +EXPORT_SYMBOL(kernel_locked_down);

Surely

EXPORT_SYMBOL(kernel_is_locked_down);

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

* Re: [PATCH 00/16] Kernel lockdown
       [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-16 21:48   ` [PATCH 11/16] x86: Lock down IO port " David Howells
  2016-11-16 21:49   ` [PATCH 16/16] x86: Restrict MSR " David Howells
@ 2016-11-16 22:27   ` One Thousand Gnomes
  2016-11-21 19:53     ` Ard Biesheuvel
  2 siblings, 1 reply; 76+ messages in thread
From: One Thousand Gnomes @ 2016-11-16 22:27 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Whether it's a good idea aside

You need to filter or lock down kernel module options because a lot of
modules let you set the I/O port or similar (eg mmio) which means you can
hack the entire machine with say the 8250 driver just by using it with an
mmio of the right location to patch the secure state to zero just by
getting the ability to write to the modules conf file.

Without that at least fixed I don't see the point in merging this. Either
we don't do it (which given the level of security the current Linux
kernel provides, and also all the golden key messups from elsewhere might
be the honest approach), or at least try and do the job right.

Less security is better than fake security. If you've got less security
your take appropriate precautions. If you rely on fake security you don't.

The two other nasty cases you miss should be fine for x86 secure boot -
but maybe not for secure boot in general. That is firmware loading and
initial firewire state. Both should be fine on any 'secure' boot PC.


Alan

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

* Re: [PATCH 00/16] Kernel lockdown
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (14 preceding siblings ...)
  2016-11-16 21:49 ` [PATCH 15/16] acpi: Ignore acpi_rsdp kernel param when the kernel has been " David Howells
@ 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
  16 siblings, 0 replies; 76+ messages in thread
From: Justin Forbes @ 2016-11-16 22:28 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

On Wed, Nov 16, 2016 at 3:47 PM, David Howells <dhowells@redhat.com> wrote:
>
> These patches provide a facility by which a variety of avenues by which
> userspace can feasibly modify the running kernel image can be locked down.
> These include:
>

Bit surprised to see this.  Not that I am opposed to the patches
themselves.  These were pulled into my tree as the first step towards
consolidating the implementation used for secure boot, and I know
there is interest in using large parts outside of a secure boot
context as well, but there were a few changes to be made after our
discussions in Santa Fe. Those are going into
http://git.kernel.org/cgit/linux/kernel/git/jforbes/linux.git/log/?h=lockdown
I am completely happy to submit those changes as separate patches if
people want to take these.  They do actually work, and are being
shipped and supported by multiple distributions at this point.

Justin

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

* Re: [PATCH 01/16] Add the ability to lock down access to the running kernel image
  2016-11-16 21:47 ` [PATCH 01/16] Add the ability to lock down access to the running kernel image David Howells
       [not found]   ` <147933284407.19316.17886320817060158597.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-16 22:40   ` David Howells
  2016-12-25 21:20   ` Pavel Machek
  2016-12-25 21:44   ` David Howells
  3 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-16 22:40 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel

Borislav Petkov <bp@alien8.de> wrote:

> > +EXPORT_SYMBOL(kernel_locked_down);
> 
> Surely
> 
> EXPORT_SYMBOL(kernel_is_locked_down);

Sorry, yes.  Obviously it won't cause a compilation error...

David

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

* Re: [PATCH 02/16] efi: Get the secure boot status
  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 2/6] arm/efi: Allow invocation of arbitrary runtime services David Howells
                       ` (4 more replies)
  2016-11-21 11:46   ` [PATCH 02/16] efi: Get the secure boot status David Howells
       [not found]   ` <20161117123731.GA11573-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
  2 siblings, 5 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-17 12:37 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

On Wed, Nov 16, 2016 at 09:47:31PM +0000, David Howells wrote:
> Get the firmware's secure-boot status in the kernel boot wrapper and stash
> it somewhere that the main kernel image can find.
> 
> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  Documentation/x86/zero-page.txt       |    2 ++
>  arch/x86/boot/compressed/eboot.c      |   35 +++++++++++++++++++++++++++++++++
>  arch/x86/include/uapi/asm/bootparam.h |    3 ++-
>  3 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
> index 95a4d34af3fd..b8527c6b7646 100644
> --- 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
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index cc69e37548db..17b376596c96 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -12,6 +12,7 @@
>  #include <asm/efi.h>
>  #include <asm/setup.h>
>  #include <asm/desc.h>
> +#include <asm/bootparam_utils.h>
>  
>  #include "../string.h"
>  #include "eboot.h"
> @@ -537,6 +538,36 @@ static void setup_efi_pci(struct boot_params *params)
>  	efi_call_early(free_pool, pci_handle);
>  }
>  
> +static int get_secure_boot(void)
> +{

This function is very similar to the existing efi_get_secureboot() in
drivers/firmware/efi/libstub/arm-stub.c.

Please avoid adding more duplicate code to the EFI stub and try to
reuse the existing code.

I suggest moving the existing efi_get_secureboot() to a new file
drivers/firmware/efi/libstub/secureboot.c which gets linked into
libstub, perhaps dependent on a new config option.


> +	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);

This doesn't work in mixed mode.

We already have the efi_call_early() macro to call boot services
in a manner that works across all arches and bitness variants.

In 4.10 there will be an efi_call_proto() macro to allow the same
for protocol calls:
http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=efi/core&id=3552fdf29f01

I suggest adding an efi_call_runtime() macro for arch- and bitness-
agnostic runtime services calls, like this:

#define efi_call_runtime(f, ...)					\
	__efi_early()->call(efi_table_attr(efi_runtime_services, f,	\
		__efi_early()->runtime_services), __VA_ARGS__)

For this to work you need to add a runtime_services attribute to struct
efi_config, this requires modifying head_32.S and head_64.S, use commit
0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
as a template.

If you define corresponding efi_call_runtime() macros for ARM, you
should indeed be able to share this function across arches.

Thanks,

Lukas


> +
> +	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;
> +}
> +
>  static efi_status_t
>  setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)
>  {
> @@ -1094,6 +1125,10 @@ struct boot_params *efi_main(struct efi_config *c,
>  	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);
> diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
> index c18ce67495fa..2b3e5427097b 100644
> --- a/arch/x86/include/uapi/asm/bootparam.h
> +++ b/arch/x86/include/uapi/asm/bootparam.h
> @@ -134,7 +134,8 @@ struct boot_params {
>  	__u8  eddbuf_entries;				/* 0x1e9 */
>  	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
>  	__u8  kbd_status;				/* 0x1eb */
> -	__u8  _pad5[3];					/* 0x1ec */
> +	__u8  secure_boot;				/* 0x1ec */
> +	__u8  _pad5[2];					/* 0x1ed */
>  	/*
>  	 * The sentinel is set to a nonzero value (0xff) in header.S.
>  	 *
> 

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

* Re: [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit
  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
       [not found]   ` <CAKv+Gu_8r3oM-jvvuSiXTzxp0YMEVgc5KkScJ2UhGTaXm28L6w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-17 21:58 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-efi, linux-kernel,
	linux-security-module, Josh Boyer

On 16 November 2016 at 21:47, David Howells <dhowells@redhat.com> wrote:
> From: Josh Boyer <jwboyer@fedoraproject.org>
>
> UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
> for use with efi_enabled.
>
> Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
>
>  arch/x86/kernel/setup.c |    1 +
>  include/linux/efi.h     |    1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 9521acce8378..539f29587712 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -1164,6 +1164,7 @@ void __init setup_arch(char **cmdline_p)
>         if (boot_params.secure_boot &&
>             IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
>                 lock_kernel_down();
> +               set_bit(EFI_SECURE_BOOT, &efi.flags);

Why is this x86 only? And why is this bit only set if
CONFIG_EFI_SECURE_BOOT_LOCK_DOWN is enabled?

>                 pr_info("Secure boot enabled\n");
>         }
>
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 11372fb8784c..5d7fb3e3400b 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1079,6 +1079,7 @@ extern int __init efi_setup_pcdp_console(char *);
>  #define EFI_ARCH_1             7       /* First arch-specific bit */
>  #define EFI_DBG                        8       /* Print additional debug info at runtime */
>  #define EFI_NX_PE_DATA         9       /* Can runtime data regions be mapped non-executable? */
> +#define EFI_SECURE_BOOT                10      /* Are we in Secure Boot mode? */
>
>  #ifdef CONFIG_EFI
>  /*
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-efi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit
  2016-11-17 21:58   ` Ard Biesheuvel
@ 2016-11-18 11:58     ` Josh Boyer
       [not found]       ` <CA+5PVA6F5qEnuL2UaXS9_fJ217J93cEZDDsz9Y2BPwHXcMdX-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 76+ messages in thread
From: Josh Boyer @ 2016-11-18 11:58 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: David Howells, keyrings, Matthew Garrett, linux-efi,
	linux-kernel, linux-security-module

On Thu, Nov 17, 2016 at 4:58 PM, Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
> On 16 November 2016 at 21:47, David Howells <dhowells@redhat.com> wrote:
>> From: Josh Boyer <jwboyer@fedoraproject.org>
>>
>> UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
>> for use with efi_enabled.
>>
>> Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
>> Signed-off-by: David Howells <dhowells@redhat.com>
>> ---
>>
>>  arch/x86/kernel/setup.c |    1 +
>>  include/linux/efi.h     |    1 +
>>  2 files changed, 2 insertions(+)
>>
>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>> index 9521acce8378..539f29587712 100644
>> --- a/arch/x86/kernel/setup.c
>> +++ b/arch/x86/kernel/setup.c
>> @@ -1164,6 +1164,7 @@ void __init setup_arch(char **cmdline_p)
>>         if (boot_params.secure_boot &&
>>             IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
>>                 lock_kernel_down();
>> +               set_bit(EFI_SECURE_BOOT, &efi.flags);
>
> Why is this x86 only? And why is this bit only set if

Because it was initially written like 3 years ago before ARM even had
UEFI.  Needs a refresh.

> CONFIG_EFI_SECURE_BOOT_LOCK_DOWN is enabled?

That part is new and something David added.  Probably not necessary.

josh

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

* Re: [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit
       [not found]       ` <CA+5PVA6F5qEnuL2UaXS9_fJ217J93cEZDDsz9Y2BPwHXcMdX-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-11-18 12:10         ` Ard Biesheuvel
  0 siblings, 0 replies; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-18 12:10 UTC (permalink / raw)
  To: Josh Boyer
  Cc: David Howells, keyrings-u79uwXL29TY76Z2rM5mHXA, Matthew Garrett,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-security-module

On 18 November 2016 at 11:58, Josh Boyer <jwboyer-rxtnV0ftBwyoClj4AeEUq9i2O/JbrIOy@public.gmane.org> wrote:
> On Thu, Nov 17, 2016 at 4:58 PM, Ard Biesheuvel
> <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>> On 16 November 2016 at 21:47, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>> From: Josh Boyer <jwboyer-rxtnV0ftBwyoClj4AeEUq9i2O/JbrIOy@public.gmane.org>
>>>
>>> UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
>>> for use with efi_enabled.
>>>
>>> Signed-off-by: Josh Boyer <jwboyer-rxtnV0ftBwyoClj4AeEUq9i2O/JbrIOy@public.gmane.org>
>>> Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>> ---
>>>
>>>  arch/x86/kernel/setup.c |    1 +
>>>  include/linux/efi.h     |    1 +
>>>  2 files changed, 2 insertions(+)
>>>
>>> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
>>> index 9521acce8378..539f29587712 100644
>>> --- a/arch/x86/kernel/setup.c
>>> +++ b/arch/x86/kernel/setup.c
>>> @@ -1164,6 +1164,7 @@ void __init setup_arch(char **cmdline_p)
>>>         if (boot_params.secure_boot &&
>>>             IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
>>>                 lock_kernel_down();
>>> +               set_bit(EFI_SECURE_BOOT, &efi.flags);
>>
>> Why is this x86 only? And why is this bit only set if
>
> Because it was initially written like 3 years ago before ARM even had
> UEFI.  Needs a refresh.
>

Ah ok. I missed that part.

In any case, we have been working very hard over the past couple of
years to move all the UEFI stuff out of arch/x86, except for the
pieces that *really* belong there. For this series, that means that a
fair share of the changes will need to be reworked and moved under
drivers/firmware/efi. Note that that also means you cannot use L""
string literals anymore, since arm64's UEFI stub is linked into the
kernel proper, and the wide character formats are incompatible between
UEFI and the wide char handling that occurs under fs/. Please check
the existing secureboot_enabled() function Lukas referred to as an
example how to emit wide string literals instead.

>> CONFIG_EFI_SECURE_BOOT_LOCK_DOWN is enabled?
>
> That part is new and something David added.  Probably not necessary.
>

Regardless of anything else,  think is is useful to have a EFI_xx flag
that is always set when secure boot is enabled.

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

* Re: [PATCH 05/16] efi: Add EFI_SECURE_BOOT bit
       [not found]   ` <CAKv+Gu_8r3oM-jvvuSiXTzxp0YMEVgc5KkScJ2UhGTaXm28L6w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-11-18 17:28     ` David Howells
  0 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-18 17:28 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA, Josh Boyer

Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:

> > @@ -1164,6 +1164,7 @@ void __init setup_arch(char **cmdline_p)
> >         if (boot_params.secure_boot &&
> >             IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
> >                 lock_kernel_down();
> > +               set_bit(EFI_SECURE_BOOT, &efi.flags);
> 
> Why is this x86 only?

It probably doesn't really need to be, but that's what the patches I ported
do.

> And why is this bit only set if CONFIG_EFI_SECURE_BOOT_LOCK_DOWN is enabled?

Actually, the EFI_SECURE_BOOT bit should probably be set outside of that
portion of the if-condition.

David

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

* Re: [PATCH 02/16] efi: Get the secure boot status
       [not found]   ` <20161117123731.GA11573-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
@ 2016-11-21 11:42     ` David Howells
       [not found]       ` <29779.1479728545-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
       [not found]       ` <CAKv+Gu-frVDhzORDRZ6XT+FxewsTgrxhXmM=DqaS6Ns4mJhQ9g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2016-11-22  0:31     ` [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services David Howells
  1 sibling, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-21 11:42 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Hi Lukas,

Looking in efi_get_secureboot(), is there a reason:

	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;

isn't static const?

David

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

* Re: [PATCH 02/16] efi: Get the secure boot status
  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-21 11:46   ` David Howells
  2016-11-21 19:58     ` Lukas Wunner
       [not found]   ` <20161117123731.GA11573-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
  2 siblings, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-21 11:46 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel

Lukas Wunner <lukas@wunner.de> wrote:

> We already have the efi_call_early() macro to call boot services
> in a manner that works across all arches and bitness variants.
> 
> In 4.10 there will be an efi_call_proto() macro to allow the same
> for protocol calls:
> http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=efi/core&id=3552fdf29f01
> 
> I suggest adding an efi_call_runtime() macro for arch- and bitness-
> agnostic runtime services calls, like this:
> 
> #define efi_call_runtime(f, ...)					\
> 	__efi_early()->call(efi_table_attr(efi_runtime_services, f,	\
> 		__efi_early()->runtime_services), __VA_ARGS__)
> 
> For this to work you need to add a runtime_services attribute to struct
> efi_config, this requires modifying head_32.S and head_64.S, use commit
> 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
> as a template.
> 
> If you define corresponding efi_call_runtime() macros for ARM, you
> should indeed be able to share this function across arches.

I'm not sure why I need to do this if I replace get_secure_boot() from my
patch with a call to efi_get_secureboot().

David

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

* Re: [PATCH 02/16] efi: Get the secure boot status
       [not found]       ` <29779.1479728545-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-21 11:52         ` Ard Biesheuvel
  0 siblings, 0 replies; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-21 11:52 UTC (permalink / raw)
  To: David Howells, Linn Crosetto
  Cc: Lukas Wunner, keyrings-u79uwXL29TY76Z2rM5mHXA, Matthew Garrett,
	linux-security-module, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

(+ Linn)

On 21 November 2016 at 11:42, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Hi Lukas,
>
> Looking in efi_get_secureboot(), is there a reason:
>
>         efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
>
> isn't static const?
>

Not a good one, no. It used to be static const, but for some reason,
commit 30d7bf034c03 ("efi/arm64: Check SetupMode when determining
Secure Boot status") removed the static and the const (and I reviewed
it and did not complain AFAIR)
I'll gladly take a patch that reinstates that, though.

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

* Re: [PATCH 02/16] efi: Get the secure boot status
       [not found]       ` <CAKv+Gu-frVDhzORDRZ6XT+FxewsTgrxhXmM=DqaS6Ns4mJhQ9g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-11-21 12:41         ` David Howells
  2016-11-21 13:14           ` Ard Biesheuvel
  0 siblings, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-21 12:41 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Linn Crosetto, Lukas Wunner,
	keyrings-u79uwXL29TY76Z2rM5mHXA, Matthew Garrett,
	linux-security-module, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:

> > Looking in efi_get_secureboot(), is there a reason:
> >
> >         efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
> >
> > isn't static const?
> >
> 
> Not a good one, no. It used to be static const, but for some reason,
> commit 30d7bf034c03 ("efi/arm64: Check SetupMode when determining
> Secure Boot status") removed the static and the const (and I reviewed
> it and did not complain AFAIR)
> I'll gladly take a patch that reinstates that, though.

Also, is there a reason that:

typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
					 unsigned long *data_size, void *data);

Doesn't have const name and vendor?

David

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

* Re: [PATCH 02/16] efi: Get the secure boot status
  2016-11-21 12:41         ` David Howells
@ 2016-11-21 13:14           ` Ard Biesheuvel
       [not found]             ` <CAKv+Gu8Lhm=u97hY1y+Y+Ladk=y7pSVNrow8ML1hQUJ9+74B-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-21 13:14 UTC (permalink / raw)
  To: David Howells
  Cc: Linn Crosetto, Lukas Wunner, keyrings, Matthew Garrett,
	linux-security-module, linux-efi, linux-kernel

On 21 November 2016 at 12:41, David Howells <dhowells@redhat.com> wrote:
> Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>
>> > Looking in efi_get_secureboot(), is there a reason:
>> >
>> >         efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
>> >
>> > isn't static const?
>> >
>>
>> Not a good one, no. It used to be static const, but for some reason,
>> commit 30d7bf034c03 ("efi/arm64: Check SetupMode when determining
>> Secure Boot status") removed the static and the const (and I reviewed
>> it and did not complain AFAIR)
>> I'll gladly take a patch that reinstates that, though.
>
> Also, is there a reason that:
>
> typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
>                                          unsigned long *data_size, void *data);
>
> Doesn't have const name and vendor?
>

Yes, but not a good one either.

Sadly, the prototypes in the UEFI spec completely ignore constness,
and these definitions are intended to be identical to the ones in the
spec. This also means, for instance, that most UEFI firmwares stores
these kinds of GUIDs in read-write memory, which is a potential
goldmine for hackers, given how GUIDs are UEFI's duct tape, i.e.,
keeping the world together.

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

* Re: [PATCH 02/16] efi: Get the secure boot status
       [not found]             ` <CAKv+Gu8Lhm=u97hY1y+Y+Ladk=y7pSVNrow8ML1hQUJ9+74B-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-11-21 15:17               ` Lukas Wunner
  2016-11-21 15:25                 ` Ard Biesheuvel
  0 siblings, 1 reply; 76+ messages in thread
From: Lukas Wunner @ 2016-11-21 15:17 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: David Howells, Linn Crosetto, keyrings-u79uwXL29TY76Z2rM5mHXA,
	Matthew Garrett, linux-security-module,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Mon, Nov 21, 2016 at 01:14:52PM +0000, Ard Biesheuvel wrote:
> On 21 November 2016 at 12:41, David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> >> > Looking in efi_get_secureboot(), is there a reason:
> >> >
> >> >         efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
> >> >
> >> > isn't static const?
> >>
> >> Not a good one, no. It used to be static const, but for some reason,
> >> commit 30d7bf034c03 ("efi/arm64: Check SetupMode when determining
> >> Secure Boot status") removed the static and the const (and I reviewed
> >> it and did not complain AFAIR)
> >> I'll gladly take a patch that reinstates that, though.
> >
> > Also, is there a reason that:
> >
> > typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
> >                                          unsigned long *data_size, void *data);
> >
> > Doesn't have const name and vendor?
> 
> Yes, but not a good one either.
> 
> Sadly, the prototypes in the UEFI spec completely ignore constness,
> and these definitions are intended to be identical to the ones in the
> spec. This also means, for instance, that most UEFI firmwares stores
> these kinds of GUIDs in read-write memory, which is a potential
> goldmine for hackers, given how GUIDs are UEFI's duct tape, i.e.,
> keeping the world together.

But the spec declares these two parameters as "IN", so it would seem
legal to declare them const, no?

Incidentally I've already prepared commits a couple of days ago to
change the GUID declarations to const everywhere and also change the
get_variable prototype, I was planning to submit them for 4.11... :-)

Thanks,

Lukas

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

* Re: [PATCH 02/16] efi: Get the secure boot status
  2016-11-21 15:17               ` Lukas Wunner
@ 2016-11-21 15:25                 ` Ard Biesheuvel
  0 siblings, 0 replies; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-21 15:25 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: David Howells, Linn Crosetto, keyrings, Matthew Garrett,
	linux-security-module, linux-efi, linux-kernel


> On 21 Nov 2016, at 15:17, Lukas Wunner <lukas@wunner.de> wrote:
> 
>> On Mon, Nov 21, 2016 at 01:14:52PM +0000, Ard Biesheuvel wrote:
>>> On 21 November 2016 at 12:41, David Howells <dhowells@redhat.com> wrote:
>>> Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
>>>>> Looking in efi_get_secureboot(), is there a reason:
>>>>> 
>>>>>        efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
>>>>> 
>>>>> isn't static const?
>>>> 
>>>> Not a good one, no. It used to be static const, but for some reason,
>>>> commit 30d7bf034c03 ("efi/arm64: Check SetupMode when determining
>>>> Secure Boot status") removed the static and the const (and I reviewed
>>>> it and did not complain AFAIR)
>>>> I'll gladly take a patch that reinstates that, though.
>>> 
>>> Also, is there a reason that:
>>> 
>>> typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
>>>                                         unsigned long *data_size, void *data);
>>> 
>>> Doesn't have const name and vendor?
>> 
>> Yes, but not a good one either.
>> 
>> Sadly, the prototypes in the UEFI spec completely ignore constness,
>> and these definitions are intended to be identical to the ones in the
>> spec. This also means, for instance, that most UEFI firmwares stores
>> these kinds of GUIDs in read-write memory, which is a potential
>> goldmine for hackers, given how GUIDs are UEFI's duct tape, i.e.,
>> keeping the world together.
> 
> But the spec declares these two parameters as "IN", so it would seem
> legal to declare them const, no?
> 

Good point.

> Incidentally I've already prepared commits a couple of days ago to
> change the GUID declarations to const everywhere and also change the
> get_variable prototype, I was planning to submit them for 4.11... :-)
> 

I would like to take those, provided that they only modify IN pointer arguments.

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

* Re: [PATCH 00/16] Kernel lockdown
  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
  0 siblings, 1 reply; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-21 19:53 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: David Howells, keyrings, Matthew Garrett, linux-security-module,
	linux-efi, linux-kernel

On 16 November 2016 at 23:27, One Thousand Gnomes
<gnomes@lxorguk.ukuu.org.uk> wrote:
> Whether it's a good idea aside
>
> You need to filter or lock down kernel module options because a lot of
> modules let you set the I/O port or similar (eg mmio) which means you can
> hack the entire machine with say the 8250 driver just by using it with an
> mmio of the right location to patch the secure state to zero just by
> getting the ability to write to the modules conf file.
>

This applies equally to the kernel command line, and given that we
cannot authenticate it, we should whitelist params that we know to be
safe, and filter out all others. A similar concern exists for the
device tree on ARM/arm64, and we already disable the DTB loader in the
UEFI stub if secure boot is enabled.

> Without that at least fixed I don't see the point in merging this. Either
> we don't do it (which given the level of security the current Linux
> kernel provides, and also all the golden key messups from elsewhere might
> be the honest approach), or at least try and do the job right.
>
> Less security is better than fake security. If you've got less security
> your take appropriate precautions. If you rely on fake security you don't.
>

In general, I think kernel hardening is an important topic, and this
series covers many cases where userland APIs can be subverted to
manipulate the state of the kernel in ways that weren't intended.
However, it would be naive to think that the series covers all such
cases, and I don't think that is what the authors intend to convey.

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

* Re: [PATCH 02/16] efi: Get the secure boot status
  2016-11-21 11:46   ` [PATCH 02/16] efi: Get the secure boot status David Howells
@ 2016-11-21 19:58     ` Lukas Wunner
  0 siblings, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-21 19:58 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

On Mon, Nov 21, 2016 at 11:46:51AM +0000, David Howells wrote:
> Lukas Wunner <lukas@wunner.de> wrote:
> > We already have the efi_call_early() macro to call boot services
> > in a manner that works across all arches and bitness variants.
> > 
> > In 4.10 there will be an efi_call_proto() macro to allow the same
> > for protocol calls:
> > http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?h=efi/core&id=3552fdf29f01
> > 
> > I suggest adding an efi_call_runtime() macro for arch- and bitness-
> > agnostic runtime services calls, like this:
> > 
> > #define efi_call_runtime(f, ...)					\
> > 	__efi_early()->call(efi_table_attr(efi_runtime_services, f,	\
> > 		__efi_early()->runtime_services), __VA_ARGS__)
> > 
> > For this to work you need to add a runtime_services attribute to struct
> > efi_config, this requires modifying head_32.S and head_64.S, use commit
> > 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
> > as a template.
> > 
> > If you define corresponding efi_call_runtime() macros for ARM, you
> > should indeed be able to share this function across arches.
> 
> I'm not sure why I need to do this if I replace get_secure_boot() from my
> patch with a call to efi_get_secureboot().

You need to do this to make the code run correctly in mixed mode
(64 bit CPU, but 32-bit EFI).

This dereferences efi_system_table_t *sys_table_arg as well as
efi_runtime_services_t *runtime:

	efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;

The problem is that efi_system_table_t and efi_runtime_services_t
uses 64-bit wide elements when compiled on 64-bit (unsigned long
or void *).  They need to be cast to efi_system_table_32_t and
efi_runtime_services_32_t at runtime if EFI is 32-bit.

The efi_call_early() and efi_call_proto() macros do this
automatically.  I suggest that you add efi_call_runtime() for
symmetry.

Thanks,

Lukas

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

* [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-16 21:47 [PATCH 00/16] Kernel lockdown David Howells
                   ` (15 preceding siblings ...)
  2016-11-16 22:28 ` [PATCH 00/16] Kernel lockdown Justin Forbes
@ 2016-11-21 23:10 ` David Howells
  2016-11-22  6:12   ` Dominik Brodowski
                     ` (4 more replies)
  16 siblings, 5 replies; 76+ messages in thread
From: David Howells @ 2016-11-21 23:10 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel

One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:

> You need to filter or lock down kernel module options because a lot of
> modules let you set the I/O port or similar (eg mmio) which means you can
> hack the entire machine with say the 8250 driver just by using it with an
> mmio of the right location to patch the secure state to zero just by
> getting the ability to write to the modules conf file.

Is the attached patch the right sort of idea?  [Note that I haven't actually
compiled most of these drivers to check my changes yet.]

David
---
commit 8613a9655dad98c3358d82a9c4310cebdcb852ae
Author: David Howells <dhowells@redhat.com>
Date:   Mon Nov 21 22:43:27 2016 +0000

    Lock down drivers that can have io ports, io mem, irqs and dma changed
    
    Lock down drivers that can have io ports, io mem, irqs and dma channels
    changed so that they can't be used to cause hardware to access the kernel
    image.
    
    Notes:
    
     (1) module_isa_driver() gets an extra parameter that, if true, will cause
         the module load to be rejected if the kernel is locked down.
    
     (2) module_driver() calls module_lockdown_check() to ask if the module
         load should be rejected if the kernel is locked down.  This is a macro
         that should be #undef'd and then redefined right before
         module_driver() is called.
    
     (3) module_pci_driver() is a wrapper around module_driver(), so the same
         macro is used as in (2).
    
     (4) A number of drivers use parport 'ports' - so I haven't touched those.

diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c
index 38868adf07ea..235493f9e205 100644
--- a/arch/x86/mm/testmmiotrace.c
+++ b/arch/x86/mm/testmmiotrace.c
@@ -115,6 +115,11 @@ static int __init init(void)
 {
 	unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
 
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	if (mmio_address == 0) {
 		pr_err("you have to use the module argument mmio_address.\n");
 		pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 14790304b84b..1c0a3878a440 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -192,6 +192,11 @@ static int __init applicom_init(void)
 
 	printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");
 
+	if ((irq || mem) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	/* No mem and irq given - check for a PCI card */
 
 	while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index a112c0146012..7fb9c299a183 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -3725,6 +3725,12 @@ static int init_ipmi_si(void)
 	struct smi_info *e;
 	enum ipmi_addr_src type = SI_INVALID;
 
+	if ((num_addrs || num_ports || num_irqs) &&
+	    kernel_is_locked_down()) {
+		pr_err(PFX "Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (initialized)
 		return 0;
 	initialized = 1;
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 3a3ff2eb6cba..ce573ffc5858 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -572,6 +572,11 @@ static int __init mwave_init(void)
 	int retval = 0;
 	pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
 
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	PRINTK_1(TRACE_MWAVE, "mwavedd::mwave_init entry\n");
 
 	memset(&mwave_s_mdd, 0, sizeof(MWAVE_DEVICE_DATA));
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c
index 9a7e37cf56b0..5facfc6b6e3b 100644
--- a/drivers/clocksource/cs5535-clockevt.c
+++ b/drivers/clocksource/cs5535-clockevt.c
@@ -145,6 +145,11 @@ static int __init cs5535_mfgpt_init(void)
 	int ret;
 	uint16_t val;
 
+	if (timer_irq != 0 && kernel_is_locked_down()) {
+		pr_err(DRV_NAME ": Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
 	if (!timer) {
 		printk(KERN_ERR DRV_NAME ": Could not allocate MFGPT timer\n");
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index 770a9ae1999a..c4cc1cd68d0e 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -318,6 +318,11 @@ MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
  */
 static int __init speedstep_init(void)
 {
+	if (smi_port != 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	if (!x86_match_cpu(ss_smi_ids))
 		return -ENODEV;
 
diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
index fcf776971ca9..cfb0db2d7c9f 100644
--- a/drivers/gpio/gpio-104-dio-48e.c
+++ b/drivers/gpio/gpio-104-dio-48e.c
@@ -393,7 +393,7 @@ static struct isa_driver dio48e_driver = {
 	},
 	.remove = dio48e_remove
 };
-module_isa_driver(dio48e_driver, num_dio48e);
+module_isa_driver(dio48e_driver, num_dio48e, num_dio48e > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c
index 2d2763ea1a68..12b57a2e39cf 100644
--- a/drivers/gpio/gpio-104-idi-48.c
+++ b/drivers/gpio/gpio-104-idi-48.c
@@ -299,7 +299,7 @@ static struct isa_driver idi_48_driver = {
 	},
 	.remove = idi_48_remove
 };
-module_isa_driver(idi_48_driver, num_idi_48);
+module_isa_driver(idi_48_driver, num_idi_48, num_idi_48 > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("ACCES 104-IDI-48 GPIO driver");
diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c
index 6787b8fcf0d8..2348c6c7cb11 100644
--- a/drivers/gpio/gpio-104-idio-16.c
+++ b/drivers/gpio/gpio-104-idio-16.c
@@ -275,7 +275,7 @@ static struct isa_driver idio_16_driver = {
 	.remove = idio_16_remove
 };
 
-module_isa_driver(idio_16_driver, num_idio_16);
+module_isa_driver(idio_16_driver, num_idio_16, num_idio_16 > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver");
diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c
index 1e7def9449ce..6507a88fe02d 100644
--- a/drivers/gpio/gpio-gpio-mm.c
+++ b/drivers/gpio/gpio-gpio-mm.c
@@ -260,7 +260,7 @@ static struct isa_driver gpiomm_driver = {
 	.remove = gpiomm_remove
 };
 
-module_isa_driver(gpiomm_driver, num_gpiomm);
+module_isa_driver(gpiomm_driver, num_gpiomm, num_gpiomm > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("Diamond Systems GPIO-MM GPIO driver");
diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c
index eaa71d440ccf..9d72a3446278 100644
--- a/drivers/gpio/gpio-ws16c48.c
+++ b/drivers/gpio/gpio-ws16c48.c
@@ -388,7 +388,7 @@ static struct isa_driver ws16c48_driver = {
 	.remove = ws16c48_remove
 };
 
-module_isa_driver(ws16c48_driver, num_ws16c48);
+module_isa_driver(ws16c48_driver, num_ws16c48, num_ws16c48 > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("WinSystems WS16C48 GPIO driver");
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 8af62fb3fe41..10d9cdee64d9 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -328,4 +328,4 @@ module_param(irq, int, 0);
 module_param(clock, int, 0);
 module_param(own, int, 0);
 module_param(mmapped, int, 0);
-module_isa_driver(i2c_elektor_driver, 1);
+module_isa_driver(i2c_elektor_driver, 1, true);
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index 1bcdd10b68b9..d880a159d433 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -219,6 +219,11 @@ static int __init i2c_parport_init(void)
 {
 	int err;
 
+	if ((base || irq) && kernel_is_locked_down()) {
+		pr_err(DRVNAME ": Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (type < 0) {
 		printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
 		return -ENODEV;
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index ba88f17f636c..7b6764279e49 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -209,4 +209,4 @@ MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
 		"\t\t\t\tFast: 100100 - 400099\n"
 		"\t\t\t\tFast+: 400100 - 10000099\n"
 		"\t\t\t\tTurbo: Up to 1265800");
-module_isa_driver(pca_isa_driver, 1);
+module_isa_driver(pca_isa_driver, 1, true);
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 0a7e410b6195..3506c0c571e9 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -41,8 +41,9 @@ MODULE_ALIAS("platform:cs5535-smb");
 MODULE_LICENSE("GPL");
 
 #define MAX_DEVICES 4
+static unsigned int nr_base = 0;
 static int base[MAX_DEVICES] = { 0x820, 0x840 };
-module_param_array(base, int, NULL, 0);
+module_param_array(base, int, &nr_base, 0);
 MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
 
 #define POLL_TIMEOUT	(HZ/5)
@@ -573,6 +574,11 @@ static __init void scx200_scan_isa(void)
 
 static int __init scx200_acb_init(void)
 {
+	if (nr_base > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
 
 	/* First scan for ISA-based devices */
diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
index 7e3645749eaf..e4f1b28e9cc3 100644
--- a/drivers/iio/adc/stx104.c
+++ b/drivers/iio/adc/stx104.c
@@ -373,7 +373,7 @@ static struct isa_driver stx104_driver = {
 	.remove = stx104_remove
 };
 
-module_isa_driver(stx104_driver, num_stx104);
+module_isa_driver(stx104_driver, num_stx104, num_stx104 > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver");
diff --git a/drivers/iio/dac/cio-dac.c b/drivers/iio/dac/cio-dac.c
index 5a743e2a779d..acd82c64531c 100644
--- a/drivers/iio/dac/cio-dac.c
+++ b/drivers/iio/dac/cio-dac.c
@@ -137,7 +137,7 @@ static struct isa_driver cio_dac_driver = {
 	}
 };
 
-module_isa_driver(cio_dac_driver, num_cio_dac);
+module_isa_driver(cio_dac_driver, num_cio_dac, num_cio_dac > 0);
 
 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 MODULE_DESCRIPTION("Measurement Computing CIO-DAC IIO driver");
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 3827a22362de..8d1b90fa8abd 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -132,6 +132,11 @@ static int __init inport_init(void)
 	unsigned char a, b, c;
 	int err;
 
+	if (inport_irq != INPORT_IRQ && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
 		printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
 		return -EBUSY;
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index e2413113df22..5f7b9a18a276 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -121,6 +121,11 @@ static int __init logibm_init(void)
 {
 	int err;
 
+	if (logibm_irq != LOGIBM_IRQ && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) {
 		printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_BASE);
 		return -EBUSY;
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index 36e57deacd03..213d5f8555f8 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -153,6 +153,12 @@ static int __init mk712_init(void)
 {
 	int err;
 
+	if ((mk712_io != 0x260  || mk712_irq != 10) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!request_region(mk712_io, 8, "mk712")) {
 		printk(KERN_WARNING "mk712: unable to get IO region\n");
 		return -ENODEV;
diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c
index 31ef8130a87f..47426c820c92 100644
--- a/drivers/isdn/hardware/avm/b1isa.c
+++ b/drivers/isdn/hardware/avm/b1isa.c
@@ -166,10 +166,11 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl)
 
 #define MAX_CARDS 4
 static struct pci_dev isa_dev[MAX_CARDS];
+static unsigned int nr_io;
 static int io[MAX_CARDS];
 static int irq[MAX_CARDS];
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
@@ -203,6 +204,11 @@ static int __init b1isa_init(void)
 	char rev[32];
 	int i;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index 72ef18853951..1d6cb9de374b 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -512,11 +512,12 @@ static char *t1isa_procinfo(struct capi_ctr *ctrl)
 
 #define MAX_CARDS 4
 static struct pci_dev isa_dev[MAX_CARDS];
+static unsigned int nr_io;
 static int io[MAX_CARDS];
 static int irq[MAX_CARDS];
 static int cardnr[MAX_CARDS];
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(irq, int, NULL, 0);
 module_param_array(cardnr, int, NULL, 0);
 MODULE_PARM_DESC(io, "I/O base address(es)");
@@ -552,6 +553,11 @@ static int __init t1isa_init(void)
 	char *p;
 	int i;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index bf04d2a3cf4a..6486174ff804 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -328,6 +328,7 @@ static char *HiSax_id = HiSaxID;
 /* Variables for insmod */
 static int type[HISAX_MAX_CARDS] = { 0, };
 static int protocol[HISAX_MAX_CARDS] = { 0, };
+static int nr_io;
 static int io[HISAX_MAX_CARDS] = { 0, };
 #undef IO0_IO1
 #ifdef CONFIG_HISAX_16_3
@@ -338,10 +339,12 @@ static int io[HISAX_MAX_CARDS] = { 0, };
 #define IO0_IO1
 #endif
 #ifdef IO0_IO1
+static int nr_io0, nr_io1;
 static int io0[HISAX_MAX_CARDS] = { 0, };
 static int io1[HISAX_MAX_CARDS] = { 0, };
 #endif
 static int irq[HISAX_MAX_CARDS] = { 0, };
+static int nr_mem;
 static int mem[HISAX_MAX_CARDS] = { 0, };
 static char *id = HiSaxID;
 
@@ -350,13 +353,13 @@ MODULE_AUTHOR("Karsten Keil");
 MODULE_LICENSE("GPL");
 module_param_array(type, int, NULL, 0);
 module_param_array(protocol, int, NULL, 0);
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
+module_param_array(mem, int, &nr_mem, 0);
 module_param(id, charp, 0);
 #ifdef IO0_IO1
-module_param_array(io0, int, NULL, 0);
-module_param_array(io1, int, NULL, 0);
+module_param_array(io0, int, &nr_io0, 0);
+module_param_array(io1, int, &nr_io1, 0);
 #endif
 #endif /* MODULE */
 
@@ -1338,6 +1341,15 @@ static int __init HiSax_init(void)
 	int nzproto = 0;
 #endif
 
+	if ((nr_io > 0 || nr_mem > 0
+#ifdef IO0_IO1
+	     || nr_io0 > 0 || nr_io1 > 0
+#endif
+	     ) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	HiSaxVersion();
 	retval = CallcNew();
 	if (retval)
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index 9d2697f5b455..6576df6ae4fd 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -1466,6 +1466,11 @@ static int __init zoran_init(void)
 {
 	int res;
 
+	if (vidmem && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "Zoran MJPEG board driver version %s\n",
 	       ZORAN_VERSION);
 
diff --git a/drivers/misc/dummy-irq.c b/drivers/misc/dummy-irq.c
index acbbe0390be4..88a56e38d615 100644
--- a/drivers/misc/dummy-irq.c
+++ b/drivers/misc/dummy-irq.c
@@ -40,6 +40,12 @@ static int __init dummy_irq_init(void)
 		printk(KERN_ERR "dummy-irq: no IRQ given.  Use irq=N\n");
 		return -EIO;
 	}
+
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
 		printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
 		return -EIO;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index c3fd16d997ca..860e0452fd70 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1939,6 +1939,12 @@ static int __init wbsd_drv_init(void)
 {
 	int result;
 
+	if ((param_io != 0x248 || param_irq != 6 || param_dma != 2) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	pr_info(DRIVER_NAME
 		": Winbond W83L51xD SD/MMC card interface driver\n");
 	pr_info(DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 1b2e9217ec78..819120cd7f0d 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -992,6 +992,12 @@ module_param(board_type, int, 0);
 
 static int __init cops_module_init(void)
 {
+	if ((io != 0x240 || irq != 5) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (io == 0)
 		printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
 			cardname);
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index 01e2ac55c137..25a4c244bb1d 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -1238,6 +1238,11 @@ module_param(dma, int, 0);
 
 static int __init ltpc_module_init(void)
 {
+	if ((io || irq || dma) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
         if(io == 0)
 		printk(KERN_NOTICE
 		       "ltpc: Autoprobing is not recommended for modules\n");
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index b9e9931353b2..9578bc7bbee4 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -146,6 +146,11 @@ static int __init com20020_init(void)
 	struct net_device *dev;
 	struct arcnet_local *lp;
 
+	if ((io || irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	dev = alloc_arcdev(device);
 	if (!dev)
 		return -ENOMEM;
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index b57863df5bf5..49b43df591ec 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -382,6 +382,11 @@ static int __init com90io_init(void)
 	struct net_device *dev;
 	int err;
 
+	if ((io || irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	dev = alloc_arcdev(device);
 	if (!dev)
 		return -ENOMEM;
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
index 81f90c4703ae..567fc40ed272 100644
--- a/drivers/net/arcnet/com90xx.c
+++ b/drivers/net/arcnet/com90xx.c
@@ -648,6 +648,11 @@ MODULE_LICENSE("GPL");
 
 static int __init com90xx_init(void)
 {
+	if ((io || irq || shmem) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (irq == 2)
 		irq = 9;
 	com90xx_probe();
diff --git a/drivers/net/can/cc770/cc770_isa.c b/drivers/net/can/cc770/cc770_isa.c
index e0d15711e9ac..355b15850406 100644
--- a/drivers/net/can/cc770/cc770_isa.c
+++ b/drivers/net/can/cc770/cc770_isa.c
@@ -73,6 +73,7 @@ MODULE_LICENSE("GPL v2");
 #define COR_DEFAULT	0x00
 #define BCR_DEFAULT	BUSCFG_CBY
 
+static unsigned int nr_port, nr_mem;
 static unsigned long port[MAXDEV];
 static unsigned long mem[MAXDEV];
 static int irq[MAXDEV];
@@ -82,10 +83,10 @@ static u8 cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
 static u8 bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
 static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
 
-module_param_array(port, ulong, NULL, S_IRUGO);
+module_param_array(port, ulong, &nr_port, S_IRUGO);
 MODULE_PARM_DESC(port, "I/O port number");
 
-module_param_array(mem, ulong, NULL, S_IRUGO);
+module_param_array(mem, ulong, &nr_mem, S_IRUGO);
 MODULE_PARM_DESC(mem, "I/O memory address");
 
 module_param_array(indirect, int, NULL, S_IRUGO);
@@ -325,6 +326,11 @@ static int __init cc770_isa_init(void)
 {
 	int idx, err;
 
+	if ((nr_port > 0 || nr_mem > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (idx = 0; idx < ARRAY_SIZE(cc770_isa_devs); idx++) {
 		if ((port[idx] || mem[idx]) && irq[idx]) {
 			cc770_isa_devs[idx] =
diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c
index e97e6d35b300..9cd0ffca6aad 100644
--- a/drivers/net/can/sja1000/sja1000_isa.c
+++ b/drivers/net/can/sja1000/sja1000_isa.c
@@ -39,6 +39,7 @@ MODULE_LICENSE("GPL v2");
 #define CDR_DEFAULT	(CDR_CBP | CDR_CLK_OFF)
 #define OCR_DEFAULT	OCR_TX0_PUSHPULL
 
+static unsigned int nr_port, nr_mem;
 static unsigned long port[MAXDEV];
 static unsigned long mem[MAXDEV];
 static int irq[MAXDEV];
@@ -48,10 +49,10 @@ static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
 static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
 static spinlock_t indirect_lock[MAXDEV];  /* lock for indirect access mode */
 
-module_param_array(port, ulong, NULL, S_IRUGO);
+module_param_array(port, ulong, &nr_port, S_IRUGO);
 MODULE_PARM_DESC(port, "I/O port number");
 
-module_param_array(mem, ulong, NULL, S_IRUGO);
+module_param_array(mem, ulong, &nr_mem, S_IRUGO);
 MODULE_PARM_DESC(mem, "I/O memory address");
 
 module_param_array(indirect, int, NULL, S_IRUGO);
@@ -266,6 +267,11 @@ static int __init sja1000_isa_init(void)
 {
 	int idx, err;
 
+	if ((nr_port > 0 || nr_mem > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (idx = 0; idx < MAXDEV; idx++) {
 		if ((port[idx] || mem[idx]) && irq[idx]) {
 			sja1000_isa_devs[idx] =
diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c
index 91ada52f776b..8f5a4915dac9 100644
--- a/drivers/net/ethernet/3com/3c509.c
+++ b/drivers/net/ethernet/3com/3c509.c
@@ -177,6 +177,7 @@ static struct net_device *el3_devs[EL3_MAX_CARDS];
 
 /* Parameters that may be passed into the module. */
 static int debug = -1;
+static unsigned int nr_irq;
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 10;
@@ -1369,7 +1370,7 @@ el3_resume(struct device *pdev)
 #endif /* CONFIG_PM */
 
 module_param(debug,int, 0);
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
@@ -1385,6 +1386,11 @@ static int __init el3_init_module(void)
 {
 	int ret = 0;
 
+	if (nr_irq > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (debug >= 0)
 		el3_debug = debug;
 
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 9133e7926da5..02fc41e9d3d0 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -3330,6 +3330,11 @@ static int __init vortex_init(void)
 {
 	int pci_rc, eisa_rc;
 
+	if ((compaq_ioaddr || compaq_irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	pci_rc = pci_register_driver(&vortex_driver);
 	eisa_rc = vortex_eisa_init();
 
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index c063b410a163..ee2945c17ceb 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -74,8 +74,9 @@ static int bad[MAX_NE_CARDS];
 static u32 ne_msg_enable;
 
 #ifdef MODULE
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+static unsigned int nr_io, nr_irq;
+module_param_array(io, int, &nr_io, 0);
+module_param_array(irq, int, &nr_irq, 0);
 module_param_array(bad, int, NULL, 0);
 module_param_named(msg_enable, ne_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
 MODULE_PARM_DESC(io, "I/O base address(es),required");
@@ -943,6 +944,12 @@ static void __init ne_add_devices(void)
 int __init init_module(void)
 {
 	int retval;
+
+	if ((nr_io > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	ne_add_devices();
 	retval = platform_driver_probe(&ne_driver, ne_drv_probe);
 	if (retval) {
diff --git a/drivers/net/ethernet/8390/smc-ultra.c b/drivers/net/ethernet/8390/smc-ultra.c
index 139385dcdaa7..f469e008ad78 100644
--- a/drivers/net/ethernet/8390/smc-ultra.c
+++ b/drivers/net/ethernet/8390/smc-ultra.c
@@ -559,10 +559,11 @@ ultra_close_card(struct net_device *dev)
 #ifdef MODULE
 #define MAX_ULTRA_CARDS	4	/* Max number of Ultra cards per module */
 static struct net_device *dev_ultra[MAX_ULTRA_CARDS];
+static unsigned int nr_io;
 static int io[MAX_ULTRA_CARDS];
 static int irq[MAX_ULTRA_CARDS];
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(irq, int, NULL, 0);
 module_param_named(msg_enable, ultra_msg_enable, uint, (S_IRUSR|S_IRGRP|S_IROTH));
 MODULE_PARM_DESC(io, "I/O base address(es)");
@@ -579,6 +580,11 @@ init_module(void)
 	struct net_device *dev;
 	int this_dev, found = 0;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
 		if (io[this_dev] == 0)  {
 			if (this_dev != 0) break; /* only autoprobe 1st one */
diff --git a/drivers/net/ethernet/8390/wd.c b/drivers/net/ethernet/8390/wd.c
index dd7d816bde52..fefa27e42865 100644
--- a/drivers/net/ethernet/8390/wd.c
+++ b/drivers/net/ethernet/8390/wd.c
@@ -499,12 +499,13 @@ wd_close(struct net_device *dev)
 #ifdef MODULE
 #define MAX_WD_CARDS	4	/* Max number of wd cards per module */
 static struct net_device *dev_wd[MAX_WD_CARDS];
+static int nr_io;
 static int io[MAX_WD_CARDS];
 static int irq[MAX_WD_CARDS];
 static int mem[MAX_WD_CARDS];
 static int mem_end[MAX_WD_CARDS];	/* for non std. mem size */
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(irq, int, NULL, 0);
 module_param_array(mem, int, NULL, 0);
 module_param_array(mem_end, int, NULL, 0);
@@ -525,6 +526,11 @@ int __init init_module(void)
 	struct net_device *dev;
 	int this_dev, found = 0;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
 		if (io[this_dev] == 0)  {
 			if (this_dev != 0) break; /* only autoprobe 1st one */
diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
index abb1ba228b26..80d860bcb4ea 100644
--- a/drivers/net/ethernet/amd/lance.c
+++ b/drivers/net/ethernet/amd/lance.c
@@ -314,11 +314,12 @@ static void lance_tx_timeout (struct net_device *dev);
 #define MAX_CARDS		8	/* Max number of interfaces (cards) per module */
 
 static struct net_device *dev_lance[MAX_CARDS];
+static int nr_io;
 static int io[MAX_CARDS];
 static int dma[MAX_CARDS];
 static int irq[MAX_CARDS];
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 module_param_array(dma, int, NULL, 0);
 module_param_array(irq, int, NULL, 0);
 module_param(lance_debug, int, 0);
@@ -332,6 +333,11 @@ int __init init_module(void)
 	struct net_device *dev;
 	int this_dev, found = 0;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
 		if (io[this_dev] == 0)  {
 			if (this_dev != 0) /* only complain once */
diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c
index cda53db75f17..33b724658bb0 100644
--- a/drivers/net/ethernet/amd/ni65.c
+++ b/drivers/net/ethernet/amd/ni65.c
@@ -1237,6 +1237,11 @@ MODULE_PARM_DESC(dma, "ni6510 ISA DMA channel (ignored for some cards)");
 
 int __init init_module(void)
 {
+	if ((irq || io || dma) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
  	dev_ni65 = ni65_probe(-1);
 	return PTR_ERR_OR_ZERO(dev_ni65);
 }
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index c363b58552e9..8b069d25461f 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -1765,6 +1765,11 @@ int __init init_module(void)
 	struct net_local *lp;
 	int ret = 0;
 
+	if ((io || irq || dma) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #if DEBUGGING
 	net_debug = debug;
 #else
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
index 6620fc861c47..64c312c81fe4 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -5554,6 +5554,11 @@ static int __init de4x5_module_init (void)
 {
 	int err = 0;
 
+	if (io && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PCI
 	err = pci_register_driver(&de4x5_pci_driver);
 #endif
diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c
index 631dbc7b4dbb..c420e8e077d9 100644
--- a/drivers/net/ethernet/hp/hp100.c
+++ b/drivers/net/ethernet/hp/hp100.c
@@ -2967,8 +2967,9 @@ MODULE_DESCRIPTION("HP CASCADE Architecture Driver for 100VG-AnyLan Network Adap
 #if defined(MODULE) && defined(CONFIG_ISA)
 #define HP100_DEVICES 5
 /* Parameters set by insmod */
+static int hp100_nr_ports;
 static int hp100_port[HP100_DEVICES] = { 0, [1 ... (HP100_DEVICES-1)] = -1 };
-module_param_array(hp100_port, int, NULL, 0);
+module_param_array(hp100_port, int, &hp100_nr_ports, 0);
 
 /* List of devices */
 static struct net_device *hp100_devlist[HP100_DEVICES];
@@ -2978,6 +2979,11 @@ static int __init hp100_isa_init(void)
 	struct net_device *dev;
 	int i, err, cards = 0;
 
+	if (hp100_nr_ports > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	/* Don't autoprobe ISA bus */
 	if (hp100_port[0] == 0)
 		return -ENODEV;
diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c
index 5cb96785fb63..8296397d5697 100644
--- a/drivers/net/ethernet/realtek/atp.c
+++ b/drivers/net/ethernet/realtek/atp.c
@@ -45,6 +45,7 @@ static int max_interrupt_work = 15;
 
 #define NUM_UNITS 2
 /* The standard set of ISA module parameters. */
+static unsigned int nr_io, nr_irq;
 static int io[NUM_UNITS];
 static int irq[NUM_UNITS];
 static int xcvr[NUM_UNITS]; 			/* The data transfer mode. */
@@ -151,8 +152,8 @@ MODULE_LICENSE("GPL");
 
 module_param(max_interrupt_work, int, 0);
 module_param(debug, int, 0);
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
+module_param_array(irq, int, &nr_irq, 0);
 module_param_array(xcvr, int, NULL, 0);
 MODULE_PARM_DESC(max_interrupt_work, "ATP maximum events handled per interrupt");
 MODULE_PARM_DESC(debug, "ATP debug level (0-7)");
@@ -860,7 +861,13 @@ static void set_rx_mode(struct net_device *dev)
 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
 }
 
-static int __init atp_init_module(void) {
+static int __init atp_init_module(void)
+{
+	if ((nr_io > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (debug)					/* Emit version even if no cards detected. */
 		printk(KERN_INFO "%s", version);
 	return atp_init();
diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c
index d496888b85d3..1de9203dc29e 100644
--- a/drivers/net/ethernet/smsc/smc9194.c
+++ b/drivers/net/ethernet/smsc/smc9194.c
@@ -1511,6 +1511,11 @@ MODULE_PARM_DESC(ifport, "SMC 99194 interface port (0-default, 1-TP, 2-AUI)");
 
 int __init init_module(void)
 {
+	if ((io || irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (io == 0)
 		printk(KERN_WARNING
 		CARDNAME": You shouldn't use auto-probing with insmod!\n" );
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 78dbc44540f6..4b60b617fdf4 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -1167,12 +1167,13 @@ static void baycom_probe(struct net_device *dev)
 /*
  * command line settable parameters
  */
+static unsigned int nr_iobase;
 static char *mode[NR_PORTS] = { "", };
 static int iobase[NR_PORTS] = { 0x378, };
 
 module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode");
-module_param_array(iobase, int, NULL, 0);
+module_param_array(iobase, int, &nr_iobase, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
@@ -1203,6 +1204,11 @@ static int __init init_baycomepp(void)
 	int i, found = 0;
 	char set_hw = 1;
 
+	if (nr_iobase > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	printk(bc_drvinfo);
 	/*
 	 * register net devices
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index 072cddce9264..c696d32a848a 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -476,12 +476,13 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 /*
  * command line settable parameters
  */
+static unsigned int nr_iobase;
 static char *mode[NR_PORTS] = { "picpar", };
 static int iobase[NR_PORTS] = { 0x378, };
 
 module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar");
-module_param_array(iobase, int, NULL, 0);
+module_param_array(iobase, int, &nr_iobase, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
@@ -495,6 +496,11 @@ static int __init init_baycompar(void)
 	int i, found = 0;
 	char set_hw = 1;
 
+	if (nr_iobase > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(bc_drvinfo);
 	/*
 	 * register net devices
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 7b916d5b14b9..4712fb402cef 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -607,6 +607,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 /*
  * command line settable parameters
  */
+static unsigned int nr_iobase, nr_irq;
 static char *mode[NR_PORTS] = { "ser12*", };
 static int iobase[NR_PORTS] = { 0x3f8, };
 static int irq[NR_PORTS] = { 4, };
@@ -614,9 +615,9 @@ static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 };
 
 module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-module_param_array(iobase, int, NULL, 0);
+module_param_array(iobase, int, &nr_iobase, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "baycom irq number");
 module_param_array(baud, int, NULL, 0);
 MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)");
@@ -632,6 +633,11 @@ static int __init init_baycomserfdx(void)
 	int i, found = 0;
 	char set_hw = 1;
 
+	if ((nr_iobase > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(bc_drvinfo);
 	/*
 	 * register net devices
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
index f9a8976195ba..354fdf24cd06 100644
--- a/drivers/net/hamradio/baycom_ser_hdx.c
+++ b/drivers/net/hamradio/baycom_ser_hdx.c
@@ -636,15 +636,16 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 /*
  * command line settable parameters
  */
+static unsigned int nr_iobase, nr_irq;
 static char *mode[NR_PORTS] = { "ser12*", };
 static int iobase[NR_PORTS] = { 0x3f8, };
 static int irq[NR_PORTS] = { 4, };
 
 module_param_array(mode, charp, NULL, 0);
 MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
-module_param_array(iobase, int, NULL, 0);
+module_param_array(iobase, int, &nr_iobase, 0);
 MODULE_PARM_DESC(iobase, "baycom io base address");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "baycom irq number");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
@@ -658,6 +659,11 @@ static int __init init_baycomserhdx(void)
 	int i, found = 0;
 	char set_hw = 1;
 
+	if ((nr_iobase > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(bc_drvinfo);
 	/*
 	 * register net devices
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index e4137c1b3df9..39071fe8dd0a 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -259,7 +259,7 @@ static void tm_isr(struct scc_priv *priv);
 
 
 /* Initialization variables */
-
+static unsigned int nr_io;
 static int io[MAX_NUM_DEVS] __initdata = { 0, };
 
 /* Beware! hw[] is also used in dmascc_exit(). */
@@ -274,7 +274,7 @@ static unsigned long rand;
 
 MODULE_AUTHOR("Klaus Kudielka");
 MODULE_DESCRIPTION("Driver for high-speed SCC boards");
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_LICENSE("GPL");
 
 static void __exit dmascc_exit(void)
@@ -314,6 +314,11 @@ static int __init dmascc_init(void)
 	unsigned long time, start[MAX_NUM_DEVS], delay[MAX_NUM_DEVS],
 	    counting[MAX_NUM_DEVS];
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	/* Initialize random number generator */
 	rand = jiffies;
 	/* Cards found = 0 */
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index c285eafd3f1c..bcd0f6298c78 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -68,6 +68,7 @@ static struct platform_driver ali_ircc_driver = {
 static int qos_mtt_bits = 0x07;  /* 1 ms or more */
 
 /* Use BIOS settions by default, but user may supply module parameters */
+static unsigned int nr_io, nr_irq, nr_dma;
 static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
 static unsigned int irq[] = { 0, 0, 0, 0 };
 static unsigned int dma[] = { 0, 0, 0, 0 };
@@ -152,6 +153,12 @@ static int __init ali_ircc_init(void)
 	int cfg, cfg_base;
 	int reg, revision;
 	int i = 0;
+
+	if ((nr_io > 0 || nr_irq > 0 || nr_dma > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
 	
 	ret = platform_driver_register(&ali_ircc_driver);
         if (ret) {
@@ -2207,11 +2214,11 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" ALI_IRCC_DRIVER_NAME);
 
 
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
-module_param_array(dma, int, NULL, 0);
+module_param_array(dma, int, &nr_dma, 0);
 MODULE_PARM_DESC(dma, "DMA channels");
 
 module_init(ali_ircc_init);
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index aaecc3baaf30..9a076437fc2c 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -91,6 +91,7 @@ static int qos_mtt_bits = 0x07;  /* 1 ms or more */
 static int dongle_id;
 
 /* Use BIOS settions by default, but user may supply module parameters */
+static unsigned int nr_io, nr_irq, nr_dma;
 static unsigned int io[]  = { ~0, ~0, ~0, ~0, ~0 };
 static unsigned int irq[] = {  0,  0,  0,  0,  0 };
 static unsigned int dma[] = {  0,  0,  0,  0,  0 };
@@ -209,6 +210,12 @@ static int __init nsc_ircc_init(void)
 	int reg;
 	int i = 0;
 
+	if ((nr_io > 0 || nr_irq > 0 || nr_dma > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	ret = platform_driver_register(&nsc_ircc_driver);
         if (ret) {
 		net_err_ratelimited("%s, Can't register driver!\n",
@@ -2396,11 +2403,11 @@ MODULE_LICENSE("GPL");
 
 module_param(qos_mtt_bits, int, 0);
 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
-module_param_array(dma, int, NULL, 0);
+module_param_array(dma, int, &nr_dma, 0);
 MODULE_PARM_DESC(dma, "DMA channels");
 module_param(dongle_id, int, 0);
 MODULE_PARM_DESC(dongle_id, "Type-id of used dongle");
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dcf92ba80872..2cbeb63000de 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -463,6 +463,13 @@ static int __init smsc_ircc_init(void)
 
 	pr_debug("%s\n", __func__);
 
+	if ((ircc_fir || ircc_sir || ircc_cfg ||
+	     ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	ret = platform_driver_register(&smsc_ircc_driver);
 	if (ret) {
 		net_err_ratelimited("%s, Can't register driver!\n",
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index 4e3d2e7c697c..78786bd6ed12 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -70,6 +70,7 @@ static int  qos_mtt_bits = 0x07;   /* 1 ms or more */
 
 #define CHIP_IO_EXTENT 8
 
+static unsigned int nr_io, nr_irq;
 static unsigned int io[] = { 0x180, ~0, ~0, ~0 };
 #ifdef CONFIG_ARCH_NETWINDER             /* Adjust to NetWinder differences */
 static unsigned int irq[] = { 6, 0, 0, 0 };
@@ -110,6 +111,12 @@ static int __init w83977af_init(void)
 {
         int i;
 
+	if ((nr_io > 0 || nr_irq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (i=0; i < ARRAY_SIZE(dev_self) && io[i] < 2000; i++) {
 		if (w83977af_open(i, io[i], irq[i], dma[i]) == 0)
 			return 0;
@@ -1264,9 +1271,9 @@ MODULE_LICENSE("GPL");
 
 module_param(qos_mtt_bits, int, 0);
 MODULE_PARM_DESC(qos_mtt_bits, "Mimimum Turn Time");
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io, "Base I/O addresses");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "IRQ lines");
 
 /*
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index b87fe0a01c69..fe835b110371 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -232,11 +232,12 @@ static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, };
 static struct class *cosa_class;
 
 #ifdef MODULE
-module_param_array(io, int, NULL, 0);
+static unsigned int nr_io, nr_dma, nr_irq;
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io, "The I/O bases of the COSA or SRP cards");
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "The IRQ lines of the COSA or SRP cards");
-module_param_array(dma, int, NULL, 0);
+module_param_array(dma, int, &nr_dma, 0);
 MODULE_PARM_DESC(dma, "The DMA channels of the COSA or SRP cards");
 
 MODULE_AUTHOR("Jan \"Yenya\" Kasprzak, <kas@fi.muni.cz>");
@@ -361,6 +362,12 @@ static int __init cosa_init(void)
 {
 	int i, err = 0;
 
+	if ((nr_io > 0 || nr_irq > 0 || nr_dma > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (cosa_major > 0) {
 		if (register_chrdev(cosa_major, "cosa", &cosa_fops)) {
 			pr_warn("unable to get major %d\n", cosa_major);
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 3d741663fd67..286b4a75e038 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -340,6 +340,12 @@ static struct z8530_dev *sv11_unit;
 
 int init_module(void)
 {
+	if ((io || irq || dma) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((sv11_unit = sv11_init(io, irq)) == NULL)
 		return -ENODEV;
 	return 0;
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 3a421ca8a4d0..ad75e698a68c 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -1464,8 +1464,9 @@ set_multicast_list( struct net_device  *dev )
 
 
 #ifdef MODULE
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+unsigned int nr_io, nr_irq;
+module_param_array(io, int, &nr_io, 0);
+module_param_array(irq, int, &nr_irq, 0);
 module_param_array(baud, int, NULL, 0);
 module_param_array(rxl, int, NULL, 0);
 module_param_array(mac, int, NULL, 0);
@@ -1479,6 +1480,12 @@ int __init init_module( void )
 	struct net_device  *dev;
 	int err;
 
+	if ((nr_io > 0 || nr_irq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	while( num < SBNI_MAX_NUM_CARDS ) {
 		dev = alloc_netdev(sizeof(struct net_local), "sbni%d",
 				   NET_NAME_UNKNOWN, sbni_devsetup);
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 27860b4f5908..678027db1fe6 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -383,6 +383,12 @@ static struct slvl_board *slvl_unit;
 
 static int __init slvl_init_module(void)
 {
+	if ((io != 0x238 || irq != 5 || tx_dma != 1 || rx_dma != 3) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
 
 	return slvl_unit ? 0 : -ENODEV;
diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
index 69b826d229c5..d5212e6def04 100644
--- a/drivers/net/wireless/cisco/airo.c
+++ b/drivers/net/wireless/cisco/airo.c
@@ -246,8 +246,9 @@ MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
 		   "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+static unsigned int nr_io, nr_irq;
+module_param_array(io, int, &nr_io, 0);
+module_param_array(irq, int, &nr_irq, 0);
 module_param_array(rates, int, NULL, 0);
 module_param_array(ssids, charp, NULL, 0);
 module_param(auto_wep, int, 0);
@@ -5649,6 +5650,12 @@ static int __init airo_init_module( void )
 {
 	int i;
 
+	if ((nr_io > 0 || nr_irq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	proc_kuid = make_kuid(&init_user_ns, proc_uid);
 	proc_kgid = make_kgid(&init_user_ns, proc_gid);
 	if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid))
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 78530d1714dc..5501656fedfa 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -3149,14 +3149,15 @@ static int __init parport_init_mode_setup(char *str)
 static char *irq[PARPORT_PC_MAX_PORTS];
 static char *dma[PARPORT_PC_MAX_PORTS];
 
+static unsigned int nr_io, nr_io_hi, nr_irq, nr_dma;
 MODULE_PARM_DESC(io, "Base I/O address (SPP regs)");
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)");
-module_param_array(io_hi, int, NULL, 0);
+module_param_array(io_hi, int, &nr_io_hi, 0);
 MODULE_PARM_DESC(irq, "IRQ line");
-module_param_array(irq, charp, NULL, 0);
+module_param_array(irq, charp, &nr_irq, 0);
 MODULE_PARM_DESC(dma, "DMA channel");
-module_param_array(dma, charp, NULL, 0);
+module_param_array(dma, charp, &nr_dma, 0);
 #if defined(CONFIG_PARPORT_PC_SUPERIO) || \
        (defined(CONFIG_PARPORT_1284) && defined(CONFIG_PARPORT_PC_FIFO))
 MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation");
@@ -3174,6 +3175,12 @@ static int __init parse_parport_params(void)
 	unsigned int i;
 	int val;
 
+	if ((nr_io > 0 || nr_io_hi > 0 || nr_irq > 0 || nr_dma > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PCI
 	if (init_mode)
 		parport_init_mode_setup(init_mode);
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index 88a44a707b96..f21fbde49ffa 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -145,6 +145,11 @@ static int __init cpcihp_generic_init(void)
 	struct resource *r;
 	struct pci_dev *dev;
 
+	if ((port || irq_mask != 0xffff) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	info(DRIVER_DESC " version: " DRIVER_VERSION);
 	status = validate_parameters();
 	if (status)
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index eb0d80a429e4..5229734e60e9 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -757,7 +757,15 @@ static void __init isa_probe(void)
 #ifdef CONFIG_PNP
     struct isapnp_device_id *devid;
     struct pnp_dev *dev;
+#endif
+
+    if ((i365_base != 0x3e0 || irq_list_count > 0) &&
+	kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
 
+#ifdef CONFIG_PNP
     for (devid = id_table; devid->vendor; devid++) {
 	if ((dev = pnp_find_dev(NULL, devid->vendor, devid->function, NULL))) {
 	
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 1ee63e5f0550..f412fb4e4e1f 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -782,6 +782,12 @@ static int tcic_init(struct pcmcia_socket *s)
 	pccard_io_map io = { 0, 0, 0, 0, 1 };
 	pccard_mem_map mem = { .res = &res, };
 
+	if ((tcic_base != TCIC_BASE || irq_mask != 0xffff || irq_list_count > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	for (i = 0; i < 2; i++) {
 		io.map = i;
 		tcic_set_io_map(s, &io);
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index f44d0487236e..d56d1d478d55 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -330,10 +330,12 @@ MODULE_LICENSE("GPL");
 
 #if !defined(PCMCIA)
 #if defined(MODULE)
+static unsigned int nr_io;
 static int io[] = {0, 0};
 module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io,"base io address of controller");
 
+static unsigned int nr_irq;
 static int irq[] = {0, 0};
 module_param_array(irq, int, NULL, 0);
 MODULE_PARM_DESC(irq,"interrupt for controller");
@@ -3083,6 +3085,11 @@ static int __init aha152x_init(void)
 	struct pnp_dev *dev=NULL, *pnpdev[2] = {NULL, NULL};
 #endif
 
+	if ((nr_io > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ( setup_count ) {
 		printk(KERN_INFO "aha152x: processing commandline: ");
 
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 7db448ec8beb..ff3ccedd5208 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -30,8 +30,9 @@ static bool isapnp = 1;
 module_param(isapnp, bool, 0);
 MODULE_PARM_DESC(isapnp, "enable PnP support (default=1)");
 
+static unsigned int nr_io;
 static int io[MAXBOARDS] = { 0x330, 0x334, 0, 0 };
-module_param_array(io, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
 MODULE_PARM_DESC(io, "base IO address of controller (0x130,0x134,0x230,0x234,0x330,0x334, default=0x330,0x334)");
 
 /* time AHA spends on the AT-bus during data transfer */
@@ -1039,6 +1040,11 @@ static int __init aha1542_init(void)
 {
 	int ret = 0;
 
+	if (nr_io > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PNP
 	if (isapnp) {
 		ret = pnp_register_driver(&aha1542_pnp_driver);
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index 227dd2c2ec2f..0f289ec14a8c 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1552,8 +1552,13 @@ static int eata2x_detect(struct scsi_host_template *tpnt)
 
 	tpnt->proc_name = "eata2x";
 
-	if (strlen(boot_options))
+	if (strlen(boot_options)) {
+		if (kernel_is_locked_down()) {
+			pr_err("Kernel is locked down\n");
+			return -EPERM;
+		}
 		option_setup(boot_options);
+	}
 
 #if defined(MODULE)
 	/* io_port could have been modified when loading as a module */
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index cbf010324c18..971dc37d0b59 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -52,12 +52,14 @@ module_param(ncr_53c400a, int, 0);
 module_param(dtc_3181e, int, 0);
 module_param(hp_c2502, int, 0);
 
+unsigned int nr_irq;
 static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 
+unsigned int nr_base;
 static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-module_param_array(base, int, NULL, 0);
+module_param_array(base, int, &nr_base, 0);
 MODULE_PARM_DESC(base, "base address(es)");
 
 static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
@@ -608,6 +610,12 @@ static int __init generic_NCR5380_init(void)
 {
 	int ret = 0;
 
+	if ((nr_base > 0 || nr_irq > 0 || ncr_addr || ncr_irq) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	/* compatibility with old-style parameters */
 	if (irq[0] == 0 && base[0] == 0 && card[0] == -1) {
 		irq[0] = ncr_irq;
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 0a767740bf02..6a3b0d756591 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -325,6 +325,7 @@ static u8 gdth_direction_tab[0x100] = {
 
 /* LILO and modprobe/insmod parameters */
 /* IRQ list for GDT3000/3020 EISA controllers */
+static unsigned int nr_irq;
 static int irq[MAXHA] __initdata = 
 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
@@ -353,7 +354,7 @@ static int probe_eisa_isa = 0;
 static int force_dma32 = 0;
 
 /* parameters for modprobe/insmod */
-module_param_array(irq, int, NULL, 0);
+module_param_array(irq, int, &irq, 0);
 module_param(disable, int, 0);
 module_param(reserve_mode, int, 0);
 module_param_array(reserve_list, int, NULL, 0);
@@ -5153,6 +5154,11 @@ static struct notifier_block gdth_notifier = {
 
 static int __init gdth_init(void)
 {
+	if (nr_irq > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (disable) {
 		printk("GDT-HA: Controller driver disabled from"
                        " command line !\n");
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
index 61cac87fb86f..d64a38627a73 100644
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -135,10 +135,11 @@ static struct Scsi_Host *__qlogicfas_detect(struct scsi_host_template *host,
 
 #define MAX_QLOGICFAS	8
 static struct qlogicfas408_priv *cards;
+static unsigned int nr_iobase, nr_irq;
 static int iobase[MAX_QLOGICFAS];
 static int irq[MAX_QLOGICFAS] = { [0 ... MAX_QLOGICFAS-1] = -1 };
-module_param_array(iobase, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+module_param_array(iobase, int, &nr_iobase, 0);
+module_param_array(irq, int, &nr_irq, 0);
 MODULE_PARM_DESC(iobase, "I/O address");
 MODULE_PARM_DESC(irq, "IRQ");
 
@@ -198,6 +199,11 @@ static struct scsi_host_template qlogicfas_driver_template = {
 
 static __init int qlogicfas_init(void)
 {
+	if ((nr_iobase > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!qlogicfas_detect(&qlogicfas_driver_template)) {
 		/* no cards found */
 		printk(KERN_INFO "%s: no cards were found, please specify "
diff --git a/drivers/staging/i4l/act2000/module.c b/drivers/staging/i4l/act2000/module.c
index 99c9c0a1c63e..70558e9e3319 100644
--- a/drivers/staging/i4l/act2000/module.c
+++ b/drivers/staging/i4l/act2000/module.c
@@ -795,6 +795,13 @@ static void __exit act2000_exit(void)
 {
 	act2000_card *card = cards;
 	act2000_card *last;
+
+	if ((act_bus || act_port != -1 || act_irq != -1) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	while (card) {
 		unregister_card(card);
 		del_timer_sync(&card->ptimer);
diff --git a/drivers/staging/i4l/icn/icn.c b/drivers/staging/i4l/icn/icn.c
index 514bfc2c5b53..f124288ceaf4 100644
--- a/drivers/staging/i4l/icn/icn.c
+++ b/drivers/staging/i4l/icn/icn.c
@@ -1659,6 +1659,12 @@ static void __exit icn_exit(void)
 	int i;
 	unsigned long flags;
 
+	if ((portbase != ICN_BASEADDR || membase != ICN_MEMADDR) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	icn_stopallcards();
 	while (card) {
 		cmd.command = ISDN_STAT_UNLOAD;
diff --git a/drivers/staging/i4l/pcbit/module.c b/drivers/staging/i4l/pcbit/module.c
index 0a59bd0b8210..dfce874c03b5 100644
--- a/drivers/staging/i4l/pcbit/module.c
+++ b/drivers/staging/i4l/pcbit/module.c
@@ -22,11 +22,12 @@ MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
 MODULE_AUTHOR("Pedro Roque Marques");
 MODULE_LICENSE("GPL");
 
+static unsigned int nr_mem, nr_irq;
 static int mem[MAX_PCBIT_CARDS];
 static int irq[MAX_PCBIT_CARDS];
 
-module_param_array(mem, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, &nr_mem, 0);
+module_param_array(irq, int, &nr_irq, 0);
 
 static int num_boards;
 struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
@@ -35,6 +36,11 @@ static int __init pcbit_init(void)
 {
 	int board;
 
+	if ((nr_mem > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	num_boards = 0;
 
 	printk(KERN_NOTICE
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index bfb76a45bfbf..4c2f27e78f01 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -630,6 +630,11 @@ static int __init lirc_parallel_init(void)
 {
 	int result;
 
+	if ((io || irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	result = platform_driver_register(&lirc_parallel_driver);
 	if (result) {
 		pr_notice("platform_driver_register returned %d\n", result);
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index b798b311d32c..38c3e80524a7 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -1030,6 +1030,11 @@ static int __init lirc_serial_init_module(void)
 {
 	int result;
 
+	if ((io || irq || ioshift || iommap) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	switch (type) {
 	case LIRC_HOMEBREW:
 	case LIRC_IRDEO:
diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 4f326e97ad75..e10d50c2f829 100644
--- a/drivers/staging/media/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
@@ -917,6 +917,11 @@ static int __init lirc_sir_init(void)
 {
 	int retval;
 
+	if ((io || irq) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	retval = platform_driver_register(&lirc_sir_driver);
 	if (retval) {
 		pr_err("Platform driver register failed!\n");
diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c
index efb791bb642b..6d1d4d8f10c5 100644
--- a/drivers/staging/speakup/speakup_acntpc.c
+++ b/drivers/staging/speakup/speakup_acntpc.c
@@ -313,6 +313,8 @@ module_param_named(start, synth_acntpc.startup, short, S_IRUGO);
 MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
 MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded.");
 
+#undef define module_lockdown_check
+#define module_lockdown_check() (port_forced)
 module_spk_synth(synth_acntpc);
 
 MODULE_AUTHOR("Kirk Reiser <kirk@braille.uwo.ca>");
diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c
index 38aa4013bf62..dfdc54434b28 100644
--- a/drivers/staging/speakup/speakup_dtlk.c
+++ b/drivers/staging/speakup/speakup_dtlk.c
@@ -384,6 +384,8 @@ module_param_named(start, synth_dtlk.startup, short, S_IRUGO);
 MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
 MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded.");
 
+#undef define module_lockdown_check
+#define module_lockdown_check() (port_forced)
 module_spk_synth(synth_dtlk);
 
 MODULE_AUTHOR("Kirk Reiser <kirk@braille.uwo.ca>");
diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c
index 5e2170bf4a8b..156922c3d0cd 100644
--- a/drivers/staging/speakup/speakup_keypc.c
+++ b/drivers/staging/speakup/speakup_keypc.c
@@ -315,6 +315,8 @@ module_param_named(start, synth_keypc.startup, short, S_IRUGO);
 MODULE_PARM_DESC(port, "Set the port for the synthesizer (override probing).");
 MODULE_PARM_DESC(start, "Start the synthesizer once it is loaded.");
 
+#undef define module_lockdown_check
+#define module_lockdown_check() (port_forced)
 module_spk_synth(synth_keypc);
 
 MODULE_AUTHOR("David Borowski");
diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c
index 8e66a520266c..36e33e8783f3 100644
--- a/drivers/staging/vme/devices/vme_pio2_core.c
+++ b/drivers/staging/vme/devices/vme_pio2_core.c
@@ -158,6 +158,12 @@ static struct vme_driver pio2_driver = {
 
 static int __init pio2_init(void)
 {
+	if ((bus_num > 0 || base_num > 0 || vector_num > 0 || level_num > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (bus_num == 0) {
 		pr_err("No cards, skipping registration\n");
 		return -ENODEV;
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index 5e4fa9206861..fffae49cc489 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -153,11 +153,12 @@ static unsigned int cy_isa_addresses[] = {
 
 #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
 
+static unsigned int nr_maddr, nr_irq;
 static long maddr[NR_CARDS];
 static int irq[NR_CARDS];
 
-module_param_array(maddr, long, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+module_param_array(maddr, long, &nr_maddr, 0);
+module_param_array(irq, int, &nr_irq, 0);
 
 #endif				/* CONFIG_ISA */
 
@@ -4038,6 +4039,13 @@ static int __init cy_init(void)
 	unsigned int nboards;
 	int retval = -ENOMEM;
 
+#ifdef CONFIG_ISA
+	if ((nr_maddr > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+#endif
+
 	cy_serial_driver = alloc_tty_driver(NR_PORTS);
 	if (!cy_serial_driver)
 		goto err;
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index 60d37b225589..9630fbe62403 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -165,6 +165,7 @@ static unsigned int moxaLowWaterChk;
 static DEFINE_MUTEX(moxa_openlock);
 static DEFINE_SPINLOCK(moxa_lock);
 
+unsigned int nr_baseaddr, nr_numports;
 static unsigned long baseaddr[MAX_BOARDS];
 static unsigned int type[MAX_BOARDS];
 static unsigned int numports[MAX_BOARDS];
@@ -179,9 +180,9 @@ MODULE_FIRMWARE("c320tunx.cod");
 
 module_param_array(type, uint, NULL, 0);
 MODULE_PARM_DESC(type, "card type: C218=2, C320=4");
-module_param_array(baseaddr, ulong, NULL, 0);
+module_param_array(baseaddr, ulong, &nr_baseaddr, 0);
 MODULE_PARM_DESC(baseaddr, "base address");
-module_param_array(numports, uint, NULL, 0);
+module_param_array(numports, uint, &nr_numports, 0);
 MODULE_PARM_DESC(numports, "numports (ignored for C218)");
 
 module_param(ttymajor, int, 0);
@@ -1039,6 +1040,11 @@ static int __init moxa_init(void)
 	struct moxa_board_conf *brd = moxa_boards;
 	unsigned int i;
 
+	if ((nr_baseaddr > 0 || nr_numports > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "MOXA Intellio family driver version %s\n",
 			MOXA_VERSION);
 
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 69294ae154be..1493bc7efda8 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -176,6 +176,7 @@ static struct pci_device_id mxser_pcibrds[] = {
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
 
+static unsigned int nr_ioaddr;
 static unsigned long ioaddr[MXSER_BOARDS];
 static int ttymajor = MXSERMAJOR;
 
@@ -183,7 +184,7 @@ static int ttymajor = MXSERMAJOR;
 
 MODULE_AUTHOR("Casper Yang");
 MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver");
-module_param_array(ioaddr, ulong, NULL, 0);
+module_param_array(ioaddr, ulong, &nr_ioaddr, 0);
 MODULE_PARM_DESC(ioaddr, "ISA io addresses to look for a moxa board");
 module_param(ttymajor, int, 0);
 MODULE_LICENSE("GPL");
@@ -2699,6 +2700,11 @@ static int __init mxser_module_init(void)
 	unsigned int b, i, m;
 	int retval;
 
+	if (nr_ioaddr > 0 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
 	if (!mxvar_sdriver)
 		return -ENOMEM;
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c
index b0cc47c77b40..2656407a2a6e 100644
--- a/drivers/tty/rocket.c
+++ b/drivers/tty/rocket.c
@@ -2363,6 +2363,12 @@ static int __init rp_init(void)
 {
 	int ret = -ENOMEM, pci_boards_found, isa_boards_found, i;
 
+	if ((board1 || board2 || board3 || board4 || conroller) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
 	       ROCKET_VERSION, ROCKET_DATE);
 
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 240a361b674f..f6f828f81e5e 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -645,6 +645,11 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 	if (strncmp(name, match, 4) != 0)
 		return -ENODEV;
 
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (uart_parse_earlycon(options, &iotype, &addr, &options))
 		return -ENODEV;
 
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index c13e27ecb0b7..8a3ad24f3a0a 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -859,6 +859,7 @@ static int ttymajor;
 /*
  * Array of user specified options for ISA adapters.
  */
+static unsigned int nr_io, nr_irq, nr_dma;
 static int io[MAX_ISA_DEVICES];
 static int irq[MAX_ISA_DEVICES];
 static int dma[MAX_ISA_DEVICES];
@@ -869,9 +870,9 @@ static int txholdbufs[MAX_TOTAL_DEVICES];
 	
 module_param(break_on_load, bool, 0);
 module_param(ttymajor, int, 0);
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
+module_param_array(io, int, &nr_io, 0);
+module_param_array(irq, int, &nr_irq, 0);
+module_param_array(dma, int, &nr_dma, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
 module_param_array(txdmabufs, int, NULL, 0);
@@ -4417,6 +4418,11 @@ static int __init synclink_init(void)
   		BREAKPOINT();
 	}
 
+	if ((nr_io > 0 || nr_irq > 0 || nr_dma > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
  	printk("%s %s\n", driver_name, driver_version);
 
 	mgsl_enum_isa_devices();
diff --git a/drivers/video/fbdev/arcfb.c b/drivers/video/fbdev/arcfb.c
index 1928cb2b5386..4e4e029e9b15 100644
--- a/drivers/video/fbdev/arcfb.c
+++ b/drivers/video/fbdev/arcfb.c
@@ -611,6 +611,12 @@ static int __init arcfb_init(void)
 {
 	int ret;
 
+	if ((dio_addr || cio_addr || c2io_addr || irq) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!arcfb_enable)
 		return -ENXIO;
 
diff --git a/drivers/video/fbdev/n411.c b/drivers/video/fbdev/n411.c
index 053deacad7cc..29375b7cd916 100644
--- a/drivers/video/fbdev/n411.c
+++ b/drivers/video/fbdev/n411.c
@@ -153,6 +153,12 @@ static struct platform_device *n411_device;
 static int __init n411_init(void)
 {
 	int ret;
+
+	if ((dio_addr || cio_addr || c2io_addr) &&  kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (!dio_addr || !cio_addr || !c2io_addr) {
 		printk(KERN_WARNING "no IO addresses supplied\n");
 		return -EINVAL;
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 6d03e8e30f8b..ac23f37445f8 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -257,6 +257,10 @@ static int cpu5wdt_init(void)
 
 static int cpu5wdt_init_module(void)
 {
+	if (port != 0x91 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
 	return cpu5wdt_init();
 }
 
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 23ee53240c4c..c214cb5893c7 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -427,6 +427,11 @@ static int __init eurwdt_init(void)
 {
 	int ret;
 
+	if ((io != 0x3f0 || irq != 10) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	ret = request_irq(irq, eurwdt_interrupt, 0, "eurwdt", NULL);
 	if (ret) {
 		pr_err("IRQ %d is not free\n", irq);
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 9f15dd9435d1..af00cc846eee 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -505,6 +505,11 @@ static int __init pc87413_init(void)
 {
 	int ret;
 
+	if (io != IO_DEFAULT && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	pr_info("Version " VERSION " at io 0x%X\n",
 							WDT_INDEX_IO_PORT);
 
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index 131193a7acdf..91e68dd63238 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -390,6 +390,11 @@ static int __init sc1200wdt_init(void)
 {
 	int ret;
 
+	if (io != -1 && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	pr_info("%s\n", SC1200_MODULE_VER);
 
 #if defined CONFIG_PNP
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index e0206b5b7d89..fa99480a1e8b 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -592,6 +592,11 @@ static int __init wdt_init(void)
 {
 	int ret;
 
+	if ((io != 0x240 || irq != 11) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if (type != 500 && type != 501) {
 		pr_err("unknown card type '%d'\n", type);
 		return -ENODEV;
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 6ad831b9d1b8..00a76f5cccb6 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -757,6 +757,11 @@ static void ramoops_register_dummy(void)
 
 static int __init ramoops_init(void)
 {
+	if ((mem_address || mem_size) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	ramoops_register_dummy();
 	return platform_driver_register(&ramoops_driver);
 }
diff --git a/include/linux/device.h b/include/linux/device.h
index bc41e87a969b..4fb2a9c3deb0 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1332,6 +1332,14 @@ extern long sysfs_deprecated;
 #endif
 
 /**
+ * module_lockdown_check() - Called to check module params for lockdown mode
+ *
+ * This should return true if the module mustn't be allowed to load in lockdown
+ * mode and false otherwise.
+ */
+#define module_lockdown_check() (false)
+
+/**
  * module_driver() - Helper macro for drivers that don't do anything
  * special in module init/exit. This eliminates a lot of boilerplate.
  * Each module may only use this macro once, and calling it replaces
@@ -1348,6 +1356,10 @@ extern long sysfs_deprecated;
 #define module_driver(__driver, __register, __unregister, ...) \
 static int __init __driver##_init(void) \
 { \
+	if (module_lockdown_check() && kernel_is_locked_down()) {	\
+		pr_err("Kernel is locked down\n");			\
+		return -EPERM;						\
+	}								\
 	return __register(&(__driver) , ##__VA_ARGS__); \
 } \
 module_init(__driver##_init); \
diff --git a/include/linux/isa.h b/include/linux/isa.h
index f2d0258414cf..88700e1ef765 100644
--- a/include/linux/isa.h
+++ b/include/linux/isa.h
@@ -41,14 +41,17 @@ static inline void isa_unregister_driver(struct isa_driver *d)
  * module_isa_driver() - Helper macro for registering a ISA driver
  * @__isa_driver: isa_driver struct
  * @__num_isa_dev: number of devices to register
+ * @__lockdown: return -EPERM if this is true and lockdown is in effect
  *
  * Helper macro for ISA drivers which do not do anything special in module
  * init/exit. This eliminates a lot of boilerplate code. Each module may only
  * use this macro once, and calling it replaces module_init and module_exit.
  */
-#define module_isa_driver(__isa_driver, __num_isa_dev) \
+#define module_isa_driver(__isa_driver, __num_isa_dev, __lockdown) \
 static int __init __isa_driver##_init(void) \
 { \
+	if ((__lockdown) && kernel_is_locked_down())		    \
+		return -EPERM;					    \
 	return isa_register_driver(&(__isa_driver), __num_isa_dev); \
 } \
 module_init(__isa_driver##_init); \
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index bc6ed52a39b9..8ab309d3fb11 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -268,6 +268,15 @@ extern int oops_may_print(void);
 void do_exit(long error_code) __noreturn;
 void complete_and_exit(struct completion *, long) __noreturn;
 
+#ifdef CONFIG_LOCK_DOWN_KERNEL
+extern bool kernel_is_locked_down(void);
+#else
+static inline bool kernel_is_locked_down(void)
+{
+	return 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/include/linux/security.h b/include/linux/security.h
index 785868b44364..41a732598f24 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1687,7 +1687,6 @@ static inline void free_secdata(void *secdata)
 
 #ifdef CONFIG_LOCK_DOWN_KERNEL
 extern void lock_kernel_down(void);
-extern bool kernel_is_locked_down(void);
 #ifdef CONFIG_ALLOW_LOCKDOWN_LIFT
 extern void lift_kernel_lockdown(void);
 #endif
@@ -1695,10 +1694,6 @@ extern void lift_kernel_lockdown(void);
 static inline void lock_kernel_down(void)
 {
 }
-static inline bool kernel_is_locked_down(void)
-{
-	return false;
-}
 #endif
 
 #endif /* ! __LINUX_SECURITY_H */
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index fed7e7e2177b..5b959ae50c0e 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -39,6 +39,7 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
 #ifdef CONFIG_PNP
 static bool pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
+static unsigned int nr_port, nr_irq;
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* MPU-401 port number */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* MPU-401 IRQ */
 static bool uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
@@ -53,9 +54,9 @@ MODULE_PARM_DESC(enable, "Enable MPU-401 device.");
 module_param_array(pnp, bool, NULL, 0444);
 MODULE_PARM_DESC(pnp, "PnP detection for MPU-401 device.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for MPU-401 device.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
 module_param_array(uart_enter, bool, NULL, 0444);
 MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open.");
@@ -242,6 +243,11 @@ static int __init alsa_card_mpu401_init(void)
 {
 	int i, err;
 
+	if ((nr_port > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
 		return err;
 
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 30e8a1d5bc87..ead24e3d01a3 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -762,6 +762,13 @@ static int __init alsa_card_mtpav_init(void)
 {
 	int err;
 
+	if ((port != MTPAV_IOBASE || irq != MTPAV_IRQ ||
+	     hwports != MTPAV_MAX_PORTS) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
 		return err;
 
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 1927b89e1d1f..ac6a47663899 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -69,6 +69,7 @@ static char *adaptor_names[] = {
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
+static unsigned int nr_port, nr_irq;
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; 	/* 3,4,5,7,9,10,11,14,15 */
 static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */
@@ -84,9 +85,9 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for Serial MIDI.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable UART16550A chip.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for UART16550A chip.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for UART16550A chip.");
 module_param_array(speed, int, NULL, 0444);
 MODULE_PARM_DESC(speed, "Speed in bauds.");
@@ -1007,6 +1008,11 @@ static int __init alsa_card_serial_init(void)
 {
 	int i, cards, err;
 
+	if ((nr_port > 0 || nr_irq > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	if ((err = platform_driver_register(&snd_serial_driver)) < 0)
 		return err;
 
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index a302d1f8d14f..4f2b277f36c9 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -44,6 +44,7 @@ MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848},"
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
+static unsigned int nr_port, nr_irq, nr_dma1;
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 5,7,9,11,12,15 */
 static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* 0,1,3,5,6,7 */
@@ -55,11 +56,11 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
@@ -170,4 +171,5 @@ static struct isa_driver snd_ad1848_driver = {
 	}
 };
 
-module_isa_driver(snd_ad1848_driver, SNDRV_CARDS);
+module_isa_driver(snd_ad1848_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_dma1 > 0);
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index 8d3060fd7ad7..b5f12f4ea6c0 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -16,6 +16,7 @@ MODULE_DESCRIPTION(CRD_NAME);
 MODULE_AUTHOR("Rene Herman");
 MODULE_LICENSE("GPL");
 
+static unsigned int nr_port;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
@@ -27,7 +28,7 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
 
 static int snd_adlib_match(struct device *dev, unsigned int n)
@@ -112,4 +113,4 @@ static struct isa_driver snd_adlib_driver = {
 	}
 };
 
-module_isa_driver(snd_adlib_driver, SNDRV_CARDS);
+module_isa_driver(snd_adlib_driver, SNDRV_CARDS, nr_port > 0);
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
index 787475084f46..6f4d546b7c48 100644
--- a/sound/isa/cmi8328.c
+++ b/sound/isa/cmi8328.c
@@ -34,6 +34,7 @@ MODULE_LICENSE("GPL");
 static int cmi8328_ports[] = { 0x530, 0xe80, 0xf40, 0x604 };
 #define CMI8328_MAX	ARRAY_SIZE(cmi8328_ports)
 
+static unsigned int nr_port, nr_irq, nr_dma1, nr_dma2, nr_mpuport, nr_mpuirq;
 static int index[CMI8328_MAX] =     {[0 ... (CMI8328_MAX-1)] = -1};
 static char *id[CMI8328_MAX] =      {[0 ... (CMI8328_MAX-1)] = NULL};
 static long port[CMI8328_MAX] =     {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
@@ -51,18 +52,18 @@ MODULE_PARM_DESC(index, "Index value for CMI8328 soundcard.");
 module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for CMI8328 soundcard.");
 
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for CMI8328 driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for CMI8328 driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 for CMI8328 driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 for CMI8328 driver.");
 
-module_param_array(mpuport, long, NULL, 0444);
+module_param_array(mpuport, long, &nr_mpuport, 0444);
 MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8328 driver.");
-module_param_array(mpuirq, int, NULL, 0444);
+module_param_array(mpuirq, int, &nr_mpuirq, 0444);
 MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8328 MPU-401 port.");
 #ifdef SUPPORT_JOYSTICK
 module_param_array(gameport, bool, NULL, 0444);
@@ -469,4 +470,6 @@ static struct isa_driver snd_cmi8328_driver = {
 	},
 };
 
-module_isa_driver(snd_cmi8328_driver, CMI8328_MAX);
+module_isa_driver(snd_cmi8328_driver, CMI8328_MAX,
+		  nr_port > 0 || nr_irq > 0 || nr_dma1 > 0 || nr_dma2 > 0 ||
+		  nr_mpuport > 0 || nr_mpuirq > 0);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index dfedfd85f205..461263872c07 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -67,6 +67,9 @@ MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}");
 
+static unsigned int nr_sbport, nr_sbirq, nr_sbdma8, nr_sbdma16;
+static unsigned int nr_wssport, nr_wssirq, nr_wssdma;
+static unsigned int nr_fmport, nr_mpuport, nr_mpuirq;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
@@ -95,27 +98,27 @@ module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
 #endif
 
-module_param_array(sbport, long, NULL, 0444);
+module_param_array(sbport, long, &nr_sbport, 0444);
 MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
-module_param_array(sbirq, int, NULL, 0444);
+module_param_array(sbirq, int, &nr_sbirq, 0444);
 MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
-module_param_array(sbdma8, int, NULL, 0444);
+module_param_array(sbdma8, int, &nr_sbdma8, 0444);
 MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
-module_param_array(sbdma16, int, NULL, 0444);
+module_param_array(sbdma16, int, &nr_sbdma16, 0444);
 MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
 
-module_param_array(wssport, long, NULL, 0444);
+module_param_array(wssport, long, &nr_wssport, 0444);
 MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
-module_param_array(wssirq, int, NULL, 0444);
+module_param_array(wssirq, int, &nr_wssirq, 0444);
 MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
-module_param_array(wssdma, int, NULL, 0444);
+module_param_array(wssdma, int, &nr_wssdma, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
 
-module_param_array(fmport, long, NULL, 0444);
+module_param_array(fmport, long, &nr_fmport, 0444);
 MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
-module_param_array(mpuport, long, NULL, 0444);
+module_param_array(mpuport, long, &nr_mpuport, 0444);
 MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
-module_param_array(mpuirq, int, NULL, 0444);
+module_param_array(mpuirq, int, &nr_mpuirq, 0444);
 MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
 #ifdef CONFIG_PNP
 static int isa_registered;
@@ -750,6 +753,14 @@ static int __init alsa_card_cmi8330_init(void)
 {
 	int err;
 
+	if ((nr_sbport > 0 || nr_sbirq > 0 || nr_sbdma8 > 0 || nr_sbdma16 > 0 ||
+	     nr_wssport > 0 || nr_wssirq > 0 || nr_wssdma > 0 ||
+	     nr_fmport > 0 || nr_mpuport > 0 || nr_mpuirq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index ef7448e9f813..647fc086034c 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -39,6 +39,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}");
 
+static unsigned int nr_port, nr_irq, nr_dma1, nr_dma2;
+static unsigned int nr_mpuport, nr_mpuirq;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -55,17 +57,17 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpuport, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpuirq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 
 static int snd_cs4231_match(struct device *dev, unsigned int n)
@@ -186,4 +188,6 @@ static struct isa_driver snd_cs4231_driver = {
 	}
 };
 
-module_isa_driver(snd_cs4231_driver, SNDRV_CARDS);
+module_isa_driver(snd_cs4231_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_dma1 > 0 || nr_dma2 > 0 ||
+		  nr_mpuport > 0 || nr_mpuirq > 0);
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 9d7582c90a95..1527bd7364b2 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -72,6 +72,8 @@ MODULE_ALIAS("snd_cs4232");
 #define IDENT "CS4232+"
 #define DEV_NAME "cs4232+"
 
+static unsigned int nr_port, nr_cport, nr_irq, nr_fm_port, nr_sb_port;
+static unsigned int nr_mpuport, nr_mpuirq, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
@@ -98,23 +100,23 @@ MODULE_PARM_DESC(enable, "Enable " IDENT " soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " IDENT " driver.");
-module_param_array(cport, long, NULL, 0444);
+module_param_array(cport, long, &nr_cport, 0444);
 MODULE_PARM_DESC(cport, "Control port # for " IDENT " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpuport, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " IDENT " driver.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for " IDENT " driver.");
-module_param_array(sb_port, long, NULL, 0444);
+module_param_array(sb_port, long, &nr_sb_port, 0444);
 MODULE_PARM_DESC(sb_port, "SB port # for " IDENT " driver (optional).");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " IDENT " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " IDENT " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
 #ifdef CONFIG_PNP
@@ -689,6 +691,15 @@ static int __init alsa_card_cs423x_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_cport > 0 || nr_irq > 0 ||
+	     nr_fm_port > 0 || nr_sb_port > 0 ||
+	     nr_dma1 > 0 || nr_dma2 > 0 ||
+	     nr_mpuport > 0 || nr_mpuirq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 1901c2bb6c3b..cdfc023538d4 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -48,6 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
 
 MODULE_ALIAS("snd_es968");
 
+static unsigned int nr_port, nr_irq, nr_fm_port;
+static unsigned int nr_mpu_port, nr_mpu_irq, nr_dma8;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 #ifdef CONFIG_PNP
@@ -71,17 +73,17 @@ module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
 #endif
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for ES1688 driver.");
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma8, int, NULL, 0444);
+module_param_array(dma8, int, &nr_dma8, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
 
 #ifdef CONFIG_PNP
@@ -344,6 +346,14 @@ static struct pnp_card_driver es968_pnpc_driver = {
 
 static int __init alsa_card_es1688_init(void)
 {
+	if ((nr_port > 0 || nr_irq > 0 ||
+	     nr_fm_port > 0 || nr_dma8 > 0 ||
+	     nr_mpuport > 0 || nr_mpuirq > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PNP
 	pnp_register_card_driver(&es968_pnpc_driver);
 	if (snd_es968_pnp_is_probed)
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 5094b62d8f77..0e44d26d2eca 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -1972,6 +1972,8 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1868 PnP AudioDrive},"
 		"{ESS,ES1887 AudioDrive},"
 		"{ESS,ES1888 AudioDrive}}");
 
+static unsigned int nr_port, nr_irq, nr_fm_port;
+static unsigned int nr_mpu_port, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
@@ -1999,17 +2001,17 @@ MODULE_PARM_DESC(enable, "Enable ES18xx soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for ES18xx driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ES18xx driver.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for ES18xx driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for ES18xx driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
 #ifdef CONFIG_PNP
@@ -2405,6 +2407,14 @@ static int __init alsa_card_es18xx_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_irq > 0 ||
+	     nr_dma1 > 0 || nr_dma2 > 0 ||
+	     nr_fm_port > 0 || nr_mpuport > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index 379abe2cbeb2..8c8299abbb69 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -44,6 +44,8 @@ MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
 
+static unsigned int nr_port, nr_wss_port, nr_mpu_port, nr_fm_port;
+static unsigned int nr_irq, nr_mpu_irq, nr_dma1, nr_dma2;
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
@@ -53,21 +55,21 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
 static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
 
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(wss_port, long, NULL, 0444);
+module_param_array(wss_port, long, &nr_wss_port, 0444);
 MODULE_PARM_DESC(wss_port, "WSS port # for " CRD_NAME " driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "Playback DMA # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "Capture DMA # for " CRD_NAME " driver.");
 
 /*
@@ -634,4 +636,7 @@ static struct isa_driver snd_galaxy_driver = {
 	}
 };
 
-module_isa_driver(snd_galaxy_driver, SNDRV_CARDS);
+module_isa_driver(snd_galaxy_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_wss_port > 0 || nr_mpuport > 0 ||
+		  nr_fm_port > 0 || nr_irq > 0 || nr_mpuirq > 0 ||
+		  nr_dma1 > 0 || nr_dma2 > 0);
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index c169be49ed71..c2815f6adf7a 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -40,6 +40,7 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}");
 
+static unsigned int nr_port, nr_irq, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -58,13 +59,13 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
 MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
@@ -229,4 +230,5 @@ static struct isa_driver snd_gusclassic_driver = {
 	}
 };
 
-module_isa_driver(snd_gusclassic_driver, SNDRV_CARDS);
+module_isa_driver(snd_gusclassic_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_dma1 > 0 || nr_dma2 > 0);
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 77ac2fd723b4..7b8b5bf51e00 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -44,6 +44,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}");
 
+static unsigned int nr_port, nr_gf1_port, nr_mpu_port;
+static unsigned int nr_irq, nr_mpu_irq, nr_gf1_irq, nr_dma8, nr_dma1;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -66,21 +68,21 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
-module_param_array(gf1_port, long, NULL, 0444);
+module_param_array(gf1_port, long, &nr_gf1_port, 0444);
 MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional).");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
-module_param_array(gf1_irq, int, NULL, 0444);
+module_param_array(gf1_irq, int, &nr_gf1_irq, 0444);
 MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver.");
-module_param_array(dma8, int, NULL, 0444);
+module_param_array(dma8, int, &nr_dma8, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
 MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver.");
@@ -358,4 +360,7 @@ static struct isa_driver snd_gusextreme_driver = {
 	}
 };
 
-module_isa_driver(snd_gusextreme_driver, SNDRV_CARDS);
+module_isa_driver(snd_gusextreme_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_gf1_port > 0 || nr_mpu_irq > 0 ||
+		  nr_irq > 0 || nr_mpu_irq > 0 || nr_gf1_irq > 0 ||
+		  nr_dma8 > 0 || nr_dma1 > 0);
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index dd88c9d33492..32914b7854f4 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -50,19 +50,20 @@ static int joystick_dac[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 29};
 static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24};
 static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
 
+static unsigned int nr_port, nr_irq, nr_dma1, nr_dma2;
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for GUS MAX soundcard.");
 module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for GUS MAX soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable GUS MAX soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for GUS MAX driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for GUS MAX driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for GUS MAX driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for GUS MAX driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
 MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS MAX driver.");
@@ -370,4 +371,5 @@ static struct isa_driver snd_gusmax_driver = {
 	},
 };
 
-module_isa_driver(snd_gusmax_driver, SNDRV_CARDS);
+module_isa_driver(snd_gusmax_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_dma1 > 0 || nr_dma2 > 0);
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 70d0040484c8..8ab68e0ca6de 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -53,6 +53,7 @@ MODULE_DESCRIPTION("AMD InterWave STB with TEA6330T");
 MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}");
 #endif
 
+static unsigned int nr_port, nr_irq, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
@@ -61,6 +62,7 @@ static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
 #endif
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x210,0x220,0x230,0x240,0x250,0x260 */
 #ifdef SNDRV_STB
+static unsigned int nr_port_tc;
 static long port_tc[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* 0x350,0x360,0x370,0x380 */
 #endif
 static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* 2,3,5,9,11,12,15 */
@@ -92,17 +94,17 @@ MODULE_PARM_DESC(enable, "Enable InterWave soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for InterWave driver.");
 #ifdef SNDRV_STB
-module_param_array(port_tc, long, NULL, 0444);
+module_param_array(port_tc, long, &nr_port_tc, 0444);
 MODULE_PARM_DESC(port_tc, "Tone control (TEA6330T - i2c bus) port # for InterWave driver.");
 #endif
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_port_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for InterWave driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_port_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for InterWave driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_port_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for InterWave driver.");
 module_param_array(joystick_dac, int, NULL, 0444);
 MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for InterWave driver.");
@@ -908,6 +910,15 @@ static int __init alsa_card_interwave_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_irq > 0 || nr_dma1 > 0 || nr_dma2 > 0
+#ifdef SNDRV_STB
+	     || nr_port_tc > 0
+#endif
+	     ) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 4c072666115d..fa389122bc0b 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -800,22 +800,25 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(INITCODEFILE);
 MODULE_FIRMWARE(PERMCODEFILE);
 
-module_param_array(io, long, NULL, S_IRUGO);
+static unsigned int nr_io, nr_irq, nr_mem;
+static unsigned int nr_mpu_io, nr_mpu_irq;
+static unsigned int nr_ide_io0, nr_ide_io1, nr_ide_irq, nr_joystick_io;
+module_param_array(io, long, &nr_io, S_IRUGO);
 MODULE_PARM_DESC(io, "IO port #");
-module_param_array(irq, int, NULL, S_IRUGO);
-module_param_array(mem, long, NULL, S_IRUGO);
+module_param_array(irq, int, &nr_irq, S_IRUGO);
+module_param_array(mem, long, &nr_mem, S_IRUGO);
 module_param_array(write_ndelay, int, NULL, S_IRUGO);
 module_param(calibrate_signal, int, S_IRUGO);
 #ifndef MSND_CLASSIC
 module_param_array(digital, int, NULL, S_IRUGO);
 module_param_array(cfg, long, NULL, S_IRUGO);
 module_param_array(reset, int, 0, S_IRUGO);
-module_param_array(mpu_io, long, NULL, S_IRUGO);
-module_param_array(mpu_irq, int, NULL, S_IRUGO);
-module_param_array(ide_io0, long, NULL, S_IRUGO);
-module_param_array(ide_io1, long, NULL, S_IRUGO);
-module_param_array(ide_irq, int, NULL, S_IRUGO);
-module_param_array(joystick_io, long, NULL, S_IRUGO);
+module_param_array(mpu_io, long, &nr_mpu_io, S_IRUGO);
+module_param_array(mpu_irq, int, &nr_mpu_irq, S_IRUGO);
+module_param_array(ide_io0, long, &nr_ide_io0, S_IRUGO);
+module_param_array(ide_io1, long, &nr_ide_io1, S_IRUGO);
+module_param_array(ide_irq, int, &nr_ide_irq, S_IRUGO);
+module_param_array(joystick_io, long, &nr_joystick_io, S_IRUGO);
 #endif
 
 
@@ -1212,6 +1215,17 @@ static int __init snd_msnd_init(void)
 {
 	int err;
 
+	if ((nr_io > 0 || nr_irq > 0 || nr_mem > 0
+#ifndef MSND_CLASSIC
+	     || nr_mpu_io > 0 || nr_mpu_irq > 0 ||
+	     nr_ide_io0 > 0 || nr_ide_io1 > 0 || nr_ide_irq > 0 ||
+	     nr_joystick_io > 0
+#endif
+	     ) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index ae133633a420..7ad1c357cbb8 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -43,6 +43,8 @@ MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF719E-S},"
 		"{Intel,AL440LX sound},"
 	        "{NeoMagic,MagicWave 3DX}}");
 
+static unsigned int nr_port, nr_sb_port, nr_wss_port, nr_fm_port, nr_midi_port;
+static unsigned int nr_irq, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
@@ -69,21 +71,21 @@ MODULE_PARM_DESC(enable, "Enable OPL3-SA soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for OPL3-SA driver.");
-module_param_array(sb_port, long, NULL, 0444);
+module_param_array(sb_port, long, &nr_sb_port, 0444);
 MODULE_PARM_DESC(sb_port, "SB port # for OPL3-SA driver.");
-module_param_array(wss_port, long, NULL, 0444);
+module_param_array(wss_port, long, &nr_wss_port, 0444);
 MODULE_PARM_DESC(wss_port, "WSS port # for OPL3-SA driver.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for OPL3-SA driver.");
-module_param_array(midi_port, long, NULL, 0444);
+module_param_array(midi_port, long, &nr_midi_port, 0444);
 MODULE_PARM_DESC(midi_port, "MIDI port # for OPL3-SA driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for OPL3-SA driver.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for OPL3-SA driver.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver.");
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
@@ -931,6 +933,14 @@ static int __init alsa_card_opl3sa2_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_sb_port > 0 || nr_wss_port > 0 ||
+	     nr_fm_port > 0 || nr_midi_port > 0 ||
+	     nr_irq > 0 || nr_dma1 > 0 || nr_dma2) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 3a9067db1a84..c88a34d62705 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1636,6 +1636,18 @@ static struct pnp_card_driver miro_pnpc_driver = {
 
 static int __init alsa_card_miro_init(void)
 {
+	if ((port != SNDRV_DEFAULT_PORT1 ||
+	     mpu_port != SNDRV_DEFAULT_PORT1 ||
+	     fm_port != SNDRV_DEFAULT_PORT1 ||
+	     irq != SNDRV_DEFAULT_IRQ1 ||
+	     mpu_irq != SNDRV_DEFAULT_IRQ1 ||
+	     dma1 != SNDRV_DEFAULT_DMA1 ||
+	     dma2 != SNDRV_DEFAULT_DMA1) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PNP
 	pnp_register_card_driver(&miro_pnpc_driver);
 	if (snd_miro_pnp_is_probed)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 0a5266003786..8408a381c8b9 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -1177,6 +1177,21 @@ static struct pnp_card_driver opti9xx_pnpc_driver = {
 
 static int __init alsa_card_opti9xx_init(void)
 {
+	if ((port != SNDRV_DEFAULT_PORT1 ||
+	     mpu_port != SNDRV_DEFAULT_PORT1 ||
+	     fm_port != SNDRV_DEFAULT_PORT1 ||
+	     irq != SNDRV_DEFAULT_IRQ1 ||
+	     mpu_irq != SNDRV_DEFAULT_IRQ1 ||
+	     dma1 != SNDRV_DEFAULT_DMA1
+#if defined(CS4231) || defined(OPTi93X)
+	     || dma2 != SNDRV_DEFAULT_DMA1
+#endif
+	     ) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 #ifdef CONFIG_PNP
 	pnp_register_card_driver(&opti9xx_pnpc_driver);
 	if (snd_opti9xx_pnp_is_probed)
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 4d909971eedb..80d2db12a355 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -34,6 +34,7 @@ MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
 MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
 MODULE_LICENSE("GPL");
 
+static unsigned int nr_port, nr_mpu_port, nr_irq, nr_mpu_irq, nr_dma8, nr_dma16;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -50,17 +51,17 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
-module_param_array(dma8, int, NULL, 0444);
+module_param_array(dma8, int, &nr_dma8, 0444);
 MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
-module_param_array(dma16, int, NULL, 0444);
+module_param_array(dma16, int, &nr_dma16, 0444);
 MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
 
 #define SB_JAZZ16_WAKEUP	0xaf
@@ -387,4 +388,6 @@ static struct isa_driver snd_jazz16_driver = {
 	},
 };
 
-module_isa_driver(snd_jazz16_driver, SNDRV_CARDS);
+module_isa_driver(snd_jazz16_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_mpu_port > 0 ||
+		  nr_irq > 0 || nr_mpu_irq > 0 || nr_dma8 > 0 || nr_dma16);
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index 4a7d7c89808f..55f0f2bafefc 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -66,6 +66,11 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB AWE 32},"
 #define SNDRV_SBAWE_EMU8000
 #endif
 
+static unsigned int nr_port, nr_mpu_port, nr_fm_port;
+#ifdef SNDRV_SBAWE_EMU8000
+static unsigned int nr_awe_port;
+#endif
+static unsigned int nr_irq, nr_mpu_irq, nr_dma8, nr_dma16;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
@@ -99,21 +104,21 @@ MODULE_PARM_DESC(enable, "Enable SoundBlaster 16 soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
 #endif
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for SB16 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for SB16 driver.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port # for SB16 PnP driver.");
 #ifdef SNDRV_SBAWE_EMU8000
-module_param_array(awe_port, long, NULL, 0444);
+module_param_array(awe_port, long, &nr_awe_port, 0444);
 MODULE_PARM_DESC(awe_port, "AWE port # for SB16 PnP driver.");
 #endif
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for SB16 driver.");
-module_param_array(dma8, int, NULL, 0444);
+module_param_array(dma8, int, &nr_dma8, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB16 driver.");
-module_param_array(dma16, int, NULL, 0444);
+module_param_array(dma16, int, &nr_dma16, 0444);
 MODULE_PARM_DESC(dma16, "16-bit DMA # for SB16 driver.");
 module_param_array(mic_agc, int, NULL, 0444);
 MODULE_PARM_DESC(mic_agc, "Mic Auto-Gain-Control switch.");
@@ -668,6 +673,16 @@ static int __init alsa_card_sb16_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_mpu_port > 0 || nr_fm_port > 0 ||
+	     nr_irq > 0 || nr_mpu_irq > 0 || nr_dma8 > 0 || nr_dma16 > 0
+#ifdef SNDRV_SBAWE_EMU8000
+	     || nr_awe_port > 0
+#endif
+	     ) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index ad42d2364199..38988a2ae59c 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -34,6 +34,7 @@ MODULE_DESCRIPTION("Sound Blaster 1.0/2.0/Pro");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 1.0/SB 2.0/SB Pro}}");
 
+static unsigned int nr_port, nr_irq, nr_dma8;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -47,11 +48,11 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for Sound Blaster soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable Sound Blaster soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for SB8 driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
-module_param_array(dma8, int, NULL, 0444);
+module_param_array(dma8, int, &nr_dma8, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
 
 struct snd_sb8 {
@@ -251,4 +252,5 @@ static struct isa_driver snd_sb8_driver = {
 	},
 };
 
-module_isa_driver(snd_sb8_driver, SNDRV_CARDS);
+module_isa_driver(snd_sb8_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_dma8 > 0);
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index b61a6633d8f2..b5ac04f34497 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -46,6 +46,8 @@ MODULE_SUPPORTED_DEVICE("{{Gallant, SC-6000},"
 			"{AudioExcel, Audio Excel DSP 16},"
 			"{Zoltrix, AV302}}");
 
+static unsigned int nr_port, nr_irq, nr_mss_port;
+static unsigned int nr_mpu_port, nr_mpu_irq, nr_dma;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
@@ -64,17 +66,17 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for sc-6000 based soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable sc-6000 based soundcard.");
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for sc-6000 driver.");
-module_param_array(mss_port, long, NULL, 0444);
+module_param_array(mss_port, long, &nr_mss_port, 0444);
 MODULE_PARM_DESC(mss_port, "MSS Port # for sc-6000 driver.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port # for sc-6000 driver.");
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for sc-6000 driver.");
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for sc-6000 driver.");
-module_param_array(dma, int, NULL, 0444);
+module_param_array(dma, int, &nr_dma, 0444);
 MODULE_PARM_DESC(dma, "DMA # for sc-6000 driver.");
 module_param_array(joystick, bool, NULL, 0444);
 MODULE_PARM_DESC(joystick, "Enable gameport.");
@@ -711,4 +713,7 @@ static struct isa_driver snd_sc6000_driver = {
 };
 
 
-module_isa_driver(snd_sc6000_driver, SNDRV_CARDS);
+module_isa_driver(snd_sc6000_driver, SNDRV_CARDS,
+		  nr_port > 0 || nr_irq > 0 || nr_mss_port > 0 ||
+		  nr_mpu_port > 0 || nr_mpu_irq > 0 || nr_dma > 0);
+
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index fdcfa29e2205..2dce17ff0b5b 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -47,6 +47,7 @@ MODULE_FIRMWARE("sndscape.co3");
 MODULE_FIRMWARE("sndscape.co4");
 MODULE_FIRMWARE("scope.cod");
 
+static unsigned int nr_port, nr_wss_port, nr_irq, nr_mpu_irq, nr_dma, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
@@ -63,22 +64,22 @@ MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
 module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "Description for SoundScape card");
 
-module_param_array(port, long, NULL, 0444);
+module_param_array(port, long, &nr_port, 0444);
 MODULE_PARM_DESC(port, "Port # for SoundScape driver.");
 
-module_param_array(wss_port, long, NULL, 0444);
+module_param_array(wss_port, &nr_wss_port, NULL, 0444);
 MODULE_PARM_DESC(wss_port, "WSS Port # for SoundScape driver.");
 
-module_param_array(irq, int, NULL, 0444);
+module_param_array(irq, int, &nr_irq, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");
 
-module_param_array(mpu_irq, int, NULL, 0444);
+module_param_array(mpu_irq, int, &nr_mpu_irq, 0444);
 MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
 
-module_param_array(dma, int, NULL, 0444);
+module_param_array(dma, int, &nr_dma, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
 
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for SoundScape driver.");
 
 module_param_array(joystick, bool, NULL, 0444);
@@ -1328,6 +1329,12 @@ static int __init sscape_init(void)
 {
 	int err;
 
+	if ((nr_port > 0 || nr_wss_port > 0 || nr_irq > 0 || nr_mpu_irq > 0 ||
+	     nr_dma > 0 || nr_dma2 > 0) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+	
 	err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index a0987a57c8a9..8300528ea918 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -36,6 +36,10 @@ MODULE_DESCRIPTION("Turtle Beach Wavefront");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}");
 
+static unsigned int nr_cs4232_pcm_port, nr_cs4232_pcm_irq;
+static unsigned int nr_cs4232_mpu_port, nr_cs4232_mpu_irq;
+static unsigned int nr_ics2115_port, nr_ics2115_irq;
+static unsigned int nr_fm_port, nr_dma1, nr_dma2;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	    /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	    /* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	    /* Enable this card */
@@ -63,23 +67,23 @@ MODULE_PARM_DESC(enable, "Enable WaveFront soundcard.");
 module_param_array(isapnp, bool, NULL, 0444);
 MODULE_PARM_DESC(isapnp, "ISA PnP detection for WaveFront soundcards.");
 #endif
-module_param_array(cs4232_pcm_port, long, NULL, 0444);
+module_param_array(cs4232_pcm_port, long, &nr_cs4232_pcm_port, 0444);
 MODULE_PARM_DESC(cs4232_pcm_port, "Port # for CS4232 PCM interface.");
-module_param_array(cs4232_pcm_irq, int, NULL, 0444);
+module_param_array(cs4232_pcm_irq, int, &nr_cs4232_pcm_irq, 0444);
 MODULE_PARM_DESC(cs4232_pcm_irq, "IRQ # for CS4232 PCM interface.");
-module_param_array(dma1, int, NULL, 0444);
+module_param_array(dma1, int, &nr_dma1, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for CS4232 PCM interface.");
-module_param_array(dma2, int, NULL, 0444);
+module_param_array(dma2, int, &nr_dma2, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for CS4232 PCM interface.");
-module_param_array(cs4232_mpu_port, long, NULL, 0444);
+module_param_array(cs4232_mpu_port, long, &nr_cs4232_mpu_port, 0444);
 MODULE_PARM_DESC(cs4232_mpu_port, "port # for CS4232 MPU-401 interface.");
-module_param_array(cs4232_mpu_irq, int, NULL, 0444);
+module_param_array(cs4232_mpu_irq, int, &nr_cs4232_mpu_irq, 0444);
 MODULE_PARM_DESC(cs4232_mpu_irq, "IRQ # for CS4232 MPU-401 interface.");
-module_param_array(ics2115_irq, int, NULL, 0444);
+module_param_array(ics2115_irq, int, &nr_ics2115_irq, 0444);
 MODULE_PARM_DESC(ics2115_irq, "IRQ # for ICS2115.");
-module_param_array(ics2115_port, long, NULL, 0444);
+module_param_array(ics2115_port, long, &nr_ics2115_port, 0444);
 MODULE_PARM_DESC(ics2115_port, "Port # for ICS2115.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port #.");
 module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
@@ -653,6 +657,15 @@ static int __init alsa_card_wavefront_init(void)
 {
 	int err;
 
+	if ((nr_cs4232_pcm_port > 0 || nr_cs4232_pcm_irq > 0 ||
+	     nr_cs4232_mpu_port > 0 || nr_cs4232_mpu_irq > 0 ||
+	     nr_ics2115_port > 0 || nr_ics2115_irq > 0 ||
+	     nr_fm_port > 0 || nr_dma1 > 0 || nr_dma2 > 0) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
 	if (!err)
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 6368e5c7d0ba..a10371be4343 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -2983,6 +2983,12 @@ static int __init ad1848_isapnp_probe(struct address_info *hw_config)
 
 static int __init init_ad1848(void)
 {
+	if ((io != -1 || irq != -1 || dma != -1 || dma2 != -1) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
 #ifdef CONFIG_PNP
diff --git a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
index bb477d5c8528..527d4bf4af49 100644
--- a/sound/oss/aedsp16.c
+++ b/sound/oss/aedsp16.c
@@ -1319,7 +1319,13 @@ MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
 MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
 MODULE_LICENSE("GPL");
 
-static int __init do_init_aedsp16(void) {
+static int __init do_init_aedsp16(void)
+{
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
 	if (io == -1 || dma == -1 || irq == -1) {
 		printk(KERN_INFO "aedsp16: I/O, IRQ and DMA are mandatory\n");
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 862735005b43..e13299f1ac8e 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -1758,6 +1758,12 @@ static int __init init_mpu401(void)
 	   to others */
 	if (io != -1 && irq != -1) {
 		struct resource *ports;
+
+		if (kernel_is_locked_down()) {
+			pr_err("Kernel is locked down\n");
+			return -EPERM;
+		}
+
 	        cfg.irq = irq;
 		cfg.io_base = io;
 		ports = request_region(io, 2, "mpu401");
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index a8bb4a06ba6f..3a78506ee7b9 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -1750,6 +1750,29 @@ static int __init msnd_init(void)
 	static msnd_pinnacle_cfg_t pinnacle_devs;
 #endif /* MSND_CLASSIC */
 
+	if ((
+#ifdef MSND_CLASSIC
+		    io != CONFIG_MSNDCLAS_IO ||
+		    irq != CONFIG_MSNDCLAS_IRQ ||
+		    mem != CONFIG_MSNDCLAS_MEM
+#else
+		    io != CONFIG_MSNDPIN_IO ||
+		    irq != CONFIG_MSNDPIN_IRQ ||
+		    mem != CONFIG_MSNDPIN_MEM ||
+		    cfg != CONFIG_MSNDPIN_CFG ||
+		    mpu_io != CONFIG_MSNDPIN_MPU_IO ||
+		    mpu_irq != CONFIG_MSNDPIN_MPU_IRQ ||
+		    ide_io0 != CONFIG_MSNDPIN_IDE_IO0 ||
+		    ide_io1 != CONFIG_MSNDPIN_IDE_IO1 ||
+		    ide_irq != CONFIG_MSNDPIN_IDE_IRQ ||
+		    joystick_io != CONFIG_MSNDPIN_JOYSTICK_IO
+#endif
+	     ) && kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
+	
 	printk(KERN_INFO LOGNAME ": Turtle Beach " LONGNAME " Linux Driver Version "
 	       VERSION ", Copyright (C) 1998 Andrew Veliath\n");
 
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index b6d19adf8f41..3e017dd58746 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -1208,6 +1208,11 @@ static int __init init_opl3 (void)
 
 	if (io != -1)	/* User loading pure OPL3 module */
 	{
+		if (kernel_is_locked_down()) {
+			pr_err("Kernel is locked down\n");
+			return -EPERM;
+		}
+
 		if (!opl3_detect(io))
 		{
 			return -ENODEV;
diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
index b07954a79536..16c1a4c731ca 100644
--- a/sound/oss/pas2_card.c
+++ b/sound/oss/pas2_card.c
@@ -401,6 +401,11 @@ MODULE_LICENSE("GPL");
 
 static int __init init_pas2(void)
 {
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "Pro Audio Spectrum driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
 	cfg.io_base = io;
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 81314f9e2ccb..aee8bba44191 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -1177,6 +1177,10 @@ static int pssmpu = 0, pssmss = 0;
 
 static int __init init_pss(void)
 {
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
 
 	if(pss_no_sound)		/* If configuring only nonsound components */
 	{
diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c
index fb5d7250de38..dd65111c77f8 100644
--- a/sound/oss/sb_card.c
+++ b/sound/oss/sb_card.c
@@ -304,6 +304,13 @@ static int __init sb_init(void)
 	int lres = 0;
 	int pres = 0;
 
+	if ((mpu_io != 0 || io != -1 || irq != -1 ||
+	     dma != -1 || dma16	!= -1) &&
+	    kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "sb: Init: Starting Probe...\n");
 
 	if(io != -1 && irq != -1 && dma != -1) {
diff --git a/sound/oss/trix.c b/sound/oss/trix.c
index 3c494dc93b93..32a094d501bd 100644
--- a/sound/oss/trix.c
+++ b/sound/oss/trix.c
@@ -426,6 +426,11 @@ module_param(joystick, bool, 0);
 
 static int __init init_trix(void)
 {
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
 	cfg.io_base = io;
diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c
index dae4d4344407..0709caa63163 100644
--- a/sound/oss/uart401.c
+++ b/sound/oss/uart401.c
@@ -441,6 +441,11 @@ static int __init init_uart401(void)
 	/* Can be loaded either for module use or to provide functions
 	   to others */
 	if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
+		if (kernel_is_locked_down()) {
+			pr_err("Kernel is locked down\n");
+			return -EPERM;
+		}
+
 		printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
 		if (!probe_uart401(&cfg_mpu, THIS_MODULE))
 			return -ENODEV;
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index 1079133dd6ab..7e59460890c0 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -320,6 +320,11 @@ module_param(irq, int, 0);
 
 static int __init init_uart6850(void)
 {
+	if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	cfg_mpu.io_base = io;
 	cfg_mpu.irq = irq;
 
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index 0b8d0de87273..912ba3d3094d 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -1986,6 +1986,9 @@ static int __init init_waveartist(void)
 		irq  = 12;
 		dma  = 3;
 		dma2 = 7;
+	} else if (kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
 	}
 
 	mix = &waveartist_mixer;
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index edabe1371660..cca148be0c84 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -88,6 +88,7 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}");
 #define SUPPORT_JOYSTICK 1
 #endif
 
+static unsigned int nr_joystick_port;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
@@ -102,7 +103,7 @@ MODULE_PARM_DESC(id, "ID string for ALS4000 soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable ALS4000 soundcard.");
 #ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, int, NULL, 0444);
+module_param_array(joystick_port, int, &nr_joystick_port, 0444);
 MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
 #endif
 
@@ -1034,4 +1035,6 @@ static struct pci_driver als4000_driver = {
 	},
 };
 
+#undef module_lockdown_check
+#define module_lockdown_check() (nr_joystick_port > 0)
 module_pci_driver(als4000_driver);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 73f593526b2d..2a7105abef23 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -52,6 +52,7 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738},"
 #define SUPPORT_JOYSTICK 1
 #endif
 
+static unsigned int nr_mpu_port, nr_fm_port, nr_joystick_port;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
@@ -68,9 +69,9 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for C-Media PCI soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable C-Media PCI soundcard.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM port.");
 module_param_array(soft_ac3, bool, NULL, 0444);
 MODULE_PARM_DESC(soft_ac3, "Software-conversion of raw SPDIF packets (model 033 only).");
@@ -3401,4 +3402,6 @@ static struct pci_driver cmipci_driver = {
 	},
 };
 	
+#undef module_lockdown_check
+#define module_lockdown_check() (nr_mpu_port > 0 || nr_fm_port > 0 || nr_joystick_port > 0)
 module_pci_driver(cmipci_driver);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 7e760fed0728..72fd3f2319c0 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -83,6 +83,7 @@ MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI ES1371/73},"
 #define SUPPORT_JOYSTICK
 #endif
 
+static unsigned int nr_joystick_port;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable switches */
@@ -106,7 +107,7 @@ module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable Ensoniq AudioPCI soundcard.");
 #ifdef SUPPORT_JOYSTICK
 #ifdef CHIP1371
-module_param_array(joystick_port, int, NULL, 0444);
+module_param_array(joystick_port, int, &nr_joystick_port, 0444);
 MODULE_PARM_DESC(joystick_port, "Joystick port address.");
 #else
 module_param_array(joystick, bool, NULL, 0444);
@@ -2475,4 +2476,6 @@ static struct pci_driver ens137x_driver = {
 	},
 };
 	
+#undef module_lockdown_check
+#define module_lockdown_check() (nr_joystick_port > 0)
 module_pci_driver(ens137x_driver);
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index ada5f01d479c..4c41a6f6a9d7 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -124,9 +124,11 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
 
+static unsigned int nr_joystick_port;
 #ifdef SUPPORT_JOYSTICK
 static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };
 #endif
+static unsigned int nr_mpu_port, nr_opl3_port;
 static int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 };
 static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 };
 
@@ -137,12 +139,12 @@ MODULE_PARM_DESC(id, "ID string for Riptide soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable Riptide soundcard.");
 #ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, int, NULL, 0444);
+module_param_array(joystick_port, int, &nr_joystick_port, 0444);
 MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard.");
 #endif
-module_param_array(mpu_port, int, NULL, 0444);
+module_param_array(mpu_port, int, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver.");
-module_param_array(opl3_port, int, NULL, 0444);
+module_param_array(opl3_port, int, &nr_opl3_port, 0444);
 MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
 
 /*
@@ -2193,6 +2195,17 @@ static struct pci_driver joystick_driver = {
 static int __init alsa_card_riptide_init(void)
 {
 	int err;
+
+	if ((
+#ifdef SUPPORT_JOYSTICK
+		    nr_joystick_port > 0 ||
+#endif
+		    nr_mpu_port > 0 || nr_opl3_port > 0)) &&
+		kernel_is_locked_down()) {
+		pr_err("Kernel is locked down\n");
+		return -EPERM;
+	}
+
 	err = pci_register_driver(&driver);
 	if (err < 0)
 		return err;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index e1a13870bb80..d7b248aab5a3 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1539,4 +1539,6 @@ static struct pci_driver sonicvibes_driver = {
 	.remove = snd_sonic_remove,
 };
 
+#undef module_lockdown_check
+#define module_lockdown_check() (dmaio != 0x7a00)
 module_pci_driver(sonicvibes_driver);
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 38a17b4342a6..e9dc57571155 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2645,4 +2645,6 @@ static struct pci_driver via82xx_driver = {
 	},
 };
 
+#undef module_lockdown_check
+#define module_lockdown_check() (mpu_port)
 module_pci_driver(via82xx_driver);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 812e27a1bcbc..f3e646b1df64 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -39,12 +39,14 @@ MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"
 		"{Yamaha,YMF744},"
 		"{Yamaha,YMF754}}");
 
+static unsigned int nr_fm_port, nr_mpu_port;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
 static long fm_port[SNDRV_CARDS];
 static long mpu_port[SNDRV_CARDS];
 #ifdef SUPPORT_JOYSTICK
+static unsigned int nr_joystick_port;
 static long joystick_port[SNDRV_CARDS];
 #endif
 static bool rear_switch[SNDRV_CARDS];
@@ -55,12 +57,12 @@ module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for the Yamaha DS-1 PCI soundcard.");
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable Yamaha DS-1 soundcard.");
-module_param_array(mpu_port, long, NULL, 0444);
+module_param_array(mpu_port, long, &nr_mpu_port, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 Port.");
-module_param_array(fm_port, long, NULL, 0444);
+module_param_array(fm_port, long, &nr_fm_port, 0444);
 MODULE_PARM_DESC(fm_port, "FM OPL-3 Port.");
 #ifdef SUPPORT_JOYSTICK
-module_param_array(joystick_port, long, NULL, 0444);
+module_param_array(joystick_port, long, &nr_joystick_port, 0444);
 MODULE_PARM_DESC(joystick_port, "Joystick port address");
 #endif
 module_param_array(rear_switch, bool, NULL, 0444);
@@ -370,4 +372,10 @@ static struct pci_driver ymfpci_driver = {
 #endif
 };
 
+#undef module_lockdown_check
+#ifdef SUPPORT_JOYSTICK
+#define module_lockdown_check() (nr_mpu_port > 0 || nr_fm_port > 0 || nr_joystick_port > 0)
+#else
+#define module_lockdown_check() (nr_mpu_port > 0 || nr_fm_port > 0)
+#endif
 module_pci_driver(ymfpci_driver);

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

* [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
       [not found]   ` <20161117123731.GA11573-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
  2016-11-21 11:42     ` David Howells
@ 2016-11-22  0:31     ` David Howells
       [not found]       ` <147977469914.6360.17194649697208113702.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-22 14:17       ` David Howells
  1 sibling, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-22  0:31 UTC (permalink / raw)
  To: lukas-JFq808J9C/izQB+pC5nmwQ
  Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Provide the ability to perform mixed-mode runtime service calls for x86 in
the same way that commit 0a637ee61247bd4bed9b2a07568ef7a1cfc76187 provides
the ability to invoke arbitrary boot services.

Suggested-by: Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---

 arch/x86/boot/compressed/eboot.c   |    1 +
 arch/x86/boot/compressed/head_32.S |    6 +++---
 arch/x86/boot/compressed/head_64.S |    8 ++++----
 arch/x86/include/asm/efi.h         |    5 +++++
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index ff01c8fc76f7..c8c32ebcdfdb 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -32,6 +32,7 @@ static void setup_boot_services##bits(struct efi_config *c)		\
 									\
 	table = (typeof(table))sys_table;				\
 									\
+	c->runtime_services = table->runtime;				\
 	c->boot_services = table->boottime;				\
 	c->text_output = table->con_out;				\
 }
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index fd0b6a272dd5..d85b9625e836 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -82,7 +82,7 @@ ENTRY(efi_pe_entry)
 
 	/* Relocate efi_config->call() */
 	leal	efi32_config(%esi), %eax
-	add	%esi, 32(%eax)
+	add	%esi, 40(%eax)
 	pushl	%eax
 
 	call	make_boot_params
@@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry)
 
 	/* Relocate efi_config->call() */
 	leal	efi32_config(%esi), %eax
-	add	%esi, 32(%eax)
+	add	%esi, 40(%eax)
 	pushl	%eax
 2:
 	call	efi_main
@@ -264,7 +264,7 @@ relocated:
 #ifdef CONFIG_EFI_STUB
 	.data
 efi32_config:
-	.fill 4,8,0
+	.fill 5,8,0
 	.long efi_call_phys
 	.long 0
 	.byte 0
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index efdfba21a5b2..beab8322f72a 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -265,7 +265,7 @@ ENTRY(efi_pe_entry)
 	/*
 	 * Relocate efi_config->call().
 	 */
-	addq	%rbp, efi64_config+32(%rip)
+	addq	%rbp, efi64_config+40(%rip)
 
 	movq	%rax, %rdi
 	call	make_boot_params
@@ -285,7 +285,7 @@ handover_entry:
 	 * Relocate efi_config->call().
 	 */
 	movq	efi_config(%rip), %rax
-	addq	%rbp, 32(%rax)
+	addq	%rbp, 40(%rax)
 2:
 	movq	efi_config(%rip), %rdi
 	call	efi_main
@@ -457,14 +457,14 @@ efi_config:
 #ifdef CONFIG_EFI_MIXED
 	.global efi32_config
 efi32_config:
-	.fill	4,8,0
+	.fill	5,8,0
 	.quad	efi64_thunk
 	.byte	0
 #endif
 
 	.global efi64_config
 efi64_config:
-	.fill	4,8,0
+	.fill	5,8,0
 	.quad	efi_call
 	.byte	1
 #endif /* CONFIG_EFI_STUB */
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index e99675b9c861..2f77bcefe6b4 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -191,6 +191,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
 struct efi_config {
 	u64 image_handle;
 	u64 table;
+	u64 runtime_services;
 	u64 boot_services;
 	u64 text_output;
 	efi_status_t (*call)(unsigned long, ...);
@@ -226,6 +227,10 @@ static inline bool efi_is_64bit(void)
 #define __efi_call_early(f, ...)					\
 	__efi_early()->call((unsigned long)f, __VA_ARGS__);
 
+#define efi_call_runtime(f, ...)					\
+	__efi_early()->call(efi_table_attr(efi_runtime_services, f,	\
+		__efi_early()->runtime_services), __VA_ARGS__)
+
 extern bool efi_reboot_required(void);
 
 #else

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

* [PATCH 2/6] arm/efi: Allow invocation of arbitrary runtime services
  2016-11-17 12:37   ` Lukas Wunner
@ 2016-11-22  0:31     ` David Howells
  2016-11-22  0:31     ` [PATCH 3/6] efi: Add SHIM and image security database GUID definitions David Howells
                       ` (3 subsequent siblings)
  4 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-22  0:31 UTC (permalink / raw)
  To: lukas; +Cc: linux-efi, dhowells, linux-security-module, keyrings, linux-kernel

Provide the ability to perform mixed-mode runtime service calls for arm in
the same way that commit 0a637ee61247bd4bed9b2a07568ef7a1cfc76187 provides
the ability to invoke arbitrary boot services.

Suggested-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/arm/include/asm/efi.h   |    1 +
 arch/arm64/include/asm/efi.h |    1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 0b06f5341b45..e4e6a9d6a825 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -55,6 +55,7 @@ void efi_virtmap_unload(void);
 
 #define efi_call_early(f, ...)		sys_table_arg->boottime->f(__VA_ARGS__)
 #define __efi_call_early(f, ...)	f(__VA_ARGS__)
+#define efi_call_runtime(f, ...)	sys_table_arg->runtime->f(__VA_ARGS__)
 #define efi_is_64bit()			(false)
 
 #define efi_call_proto(protocol, f, instance, ...)			\
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 771b3f0bc757..d74ae223d89f 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -49,6 +49,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
 
 #define efi_call_early(f, ...)		sys_table_arg->boottime->f(__VA_ARGS__)
 #define __efi_call_early(f, ...)	f(__VA_ARGS__)
+#define efi_call_runtime(f, ...)	sys_table_arg->runtime->f(__VA_ARGS__)
 #define efi_is_64bit()			(true)
 
 #define efi_call_proto(protocol, f, instance, ...)			\

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

* [PATCH 3/6] efi: Add SHIM and image security database GUID definitions
  2016-11-17 12:37   ` Lukas Wunner
  2016-11-22  0:31     ` [PATCH 2/6] arm/efi: Allow invocation of arbitrary runtime services David Howells
@ 2016-11-22  0:31     ` David Howells
  2016-11-22  0:32     ` [PATCH 4/6] efi: Get the secure boot status David Howells
                       ` (2 subsequent siblings)
  4 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-22  0:31 UTC (permalink / raw)
  To: lukas
  Cc: linux-efi, Ard Biesheuvel, linux-kernel, dhowells,
	linux-security-module, Josh Boyer, keyrings

Add the definitions for shim and image security database, both of which
are used widely in various Linux distros.

Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---

 include/linux/efi.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/efi.h b/include/linux/efi.h
index a07a476178cd..24db4e5ec817 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -610,6 +610,9 @@ void efi_native_runtime_setup(void);
 #define EFI_CONSOLE_OUT_DEVICE_GUID		EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4,  0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 #define APPLE_PROPERTIES_PROTOCOL_GUID		EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb,  0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0)
 
+#define EFI_IMAGE_SECURITY_DATABASE_GUID	EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
+#define EFI_SHIM_LOCK_GUID			EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
 /*
  * This GUID is used to pass to the kernel proper the struct screen_info
  * structure that was populated by the stub based on the GOP protocol instance

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

* [PATCH 4/6] efi: Get the secure boot status
  2016-11-17 12:37   ` Lukas Wunner
  2016-11-22  0:31     ` [PATCH 2/6] arm/efi: Allow invocation of arbitrary runtime services 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     ` David Howells
  2016-11-22 10:44       ` Lukas Wunner
                         ` (2 more replies)
  2016-11-22  0:32     ` [PATCH 5/6] efi: Disable secure boot if shim is in insecure mode David Howells
  2016-11-22  0:32     ` [PATCH 6/6] efi: Add EFI_SECURE_BOOT bit David Howells
  4 siblings, 3 replies; 76+ messages in thread
From: David Howells @ 2016-11-22  0:32 UTC (permalink / raw)
  To: lukas
  Cc: Matthew Garrett, linux-efi, linux-kernel, dhowells,
	linux-security-module, keyrings

Get the firmware's secure-boot status in the kernel boot wrapper and stash
it somewhere that the main kernel image can find.

Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 Documentation/x86/zero-page.txt           |    2 +
 arch/x86/boot/compressed/eboot.c          |    5 ++
 arch/x86/include/uapi/asm/bootparam.h     |    3 +
 drivers/firmware/efi/libstub/Makefile     |    2 -
 drivers/firmware/efi/libstub/arm-stub.c   |   46 --------------------
 drivers/firmware/efi/libstub/secureboot.c |   66 +++++++++++++++++++++++++++++
 include/linux/efi.h                       |    2 +
 7 files changed, 78 insertions(+), 48 deletions(-)
 create mode 100644 drivers/firmware/efi/libstub/secureboot.c

diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
index 95a4d34af3fd..b8527c6b7646 100644
--- 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
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index c8c32ebcdfdb..fd6506de480d 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -12,6 +12,7 @@
 #include <asm/efi.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/bootparam_utils.h>
 
 #include "../string.h"
 #include "eboot.h"
@@ -1158,6 +1159,10 @@ struct boot_params *efi_main(struct efi_config *c,
 	else
 		setup_boot_services32(efi_early);
 
+	sanitize_boot_params(boot_params);
+
+	boot_params->secure_boot = efi_get_secureboot();
+
 	setup_graphics(boot_params);
 
 	setup_efi_pci(boot_params);
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index b10bf319ed20..5138dacf8bb8 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -135,7 +135,8 @@ struct boot_params {
 	__u8  eddbuf_entries;				/* 0x1e9 */
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
 	__u8  kbd_status;				/* 0x1eb */
-	__u8  _pad5[3];					/* 0x1ec */
+	__u8  secure_boot;				/* 0x1ec */
+	__u8  _pad5[2];					/* 0x1ed */
 	/*
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
 	 *
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 6621b13c370f..9af966863612 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -28,7 +28,7 @@ OBJECT_FILES_NON_STANDARD	:= y
 # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
 KCOV_INSTRUMENT			:= n
 
-lib-y				:= efi-stub-helper.o gop.o
+lib-y				:= efi-stub-helper.o gop.o secureboot.o
 
 # include the stub's generic dependencies from lib/ when building for ARM/arm64
 arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index b4f7d78f9e8b..552ee61ddbed 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,52 +20,6 @@
 
 bool __nokaslr;
 
-static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
-{
-	static efi_char16_t const sb_var_name[] = {
-		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
-	static efi_char16_t const sm_var_name[] = {
-		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
-
-	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
-	efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-	u8 val;
-	unsigned long size = sizeof(val);
-	efi_status_t status;
-
-	status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
-			  NULL, &size, &val);
-
-	if (status != EFI_SUCCESS)
-		goto out_efi_err;
-
-	if (val == 0)
-		return 0;
-
-	status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
-			  NULL, &size, &val);
-
-	if (status != EFI_SUCCESS)
-		goto out_efi_err;
-
-	if (val == 1)
-		return 0;
-
-	return 1;
-
-out_efi_err:
-	switch (status) {
-	case EFI_NOT_FOUND:
-		return 0;
-	case EFI_DEVICE_ERROR:
-		return -EIO;
-	case EFI_SECURITY_VIOLATION:
-		return -EACCES;
-	default:
-		return -EINVAL;
-	}
-}
-
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
 			     void *__image, void **__fh)
 {
diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
new file mode 100644
index 000000000000..e44d8c9ee150
--- /dev/null
+++ b/drivers/firmware/efi/libstub/secureboot.c
@@ -0,0 +1,66 @@
+/*
+ * Secure boot handling.
+ *
+ * Copyright (C) 2013,2014 Linaro Limited
+ *     Roy Franz <roy.franz@linaro.org
+ * Copyright (C) 2013 Red Hat, Inc.
+ *     Mark Salter <msalter@redhat.com>
+ *
+ * This file is part of the Linux kernel, and is made available under the
+ * terms of the GNU General Public License version 2.
+ *
+ */
+
+#include <linux/efi.h>
+#include <linux/sort.h>
+#include <asm/efi.h>
+
+#include "efistub.h"
+
+int efi_get_secureboot(void)
+{
+	static const efi_char16_t const sb_var_name[] = {
+		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+	static const efi_char16_t const sm_var_name[] = {
+		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
+
+	static const efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+
+	u8 val;
+	unsigned long size = sizeof(val);
+	efi_status_t status;
+
+#define f_getvar(...) efi_call_runtime(get_variable, __VA_ARGS__)
+
+	status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
+			  NULL, &size, &val);
+
+	if (status != EFI_SUCCESS)
+		goto out_efi_err;
+
+	if (val == 0)
+		return 0;
+
+	status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
+			  NULL, &size, &val);
+
+	if (status != EFI_SUCCESS)
+		goto out_efi_err;
+
+	if (val == 1)
+		return 0;
+
+	return 1;
+
+out_efi_err:
+	switch (status) {
+	case EFI_NOT_FOUND:
+		return 0;
+	case EFI_DEVICE_ERROR:
+		return -EIO;
+	case EFI_SECURITY_VIOLATION:
+		return -EACCES;
+	default:
+		return -EINVAL;
+	}
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 24db4e5ec817..615d8704f048 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1477,6 +1477,8 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
 bool efi_runtime_disabled(void);
 extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
 
+int efi_get_secureboot(void);
+
 /*
  * Arch code can implement the following three template macros, avoiding
  * reptition for the void/non-void return cases of {__,}efi_call_virt():

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

* [PATCH 5/6] efi: Disable secure boot if shim is in insecure mode
  2016-11-17 12:37   ` Lukas Wunner
                       ` (2 preceding siblings ...)
  2016-11-22  0:32     ` [PATCH 4/6] efi: Get the secure boot status David Howells
@ 2016-11-22  0:32     ` 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
  4 siblings, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-22  0:32 UTC (permalink / raw)
  To: lukas
  Cc: linux-efi, linux-kernel, dhowells, linux-security-module,
	Josh Boyer, keyrings

From: Josh Boyer <jwboyer@fedoraproject.org>

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>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/firmware/efi/libstub/secureboot.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
index e44d8c9ee150..d928398a3a52 100644
--- a/drivers/firmware/efi/libstub/secureboot.c
+++ b/drivers/firmware/efi/libstub/secureboot.c
@@ -23,10 +23,14 @@ int efi_get_secureboot(void)
 		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
 	static const efi_char16_t const sm_var_name[] = {
 		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
+	static efi_char16_t const MokSBState_var_name[] = {
+		'M', 'o', 'k', 'S', 'B', 'S', 't', 'a', 't', 'e', 0 };
 
 	static const efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+	static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
 
-	u8 val;
+	u32 attr;
+	u8 val, moksbstate;
 	unsigned long size = sizeof(val);
 	efi_status_t status;
 
@@ -50,6 +54,22 @@ int efi_get_secureboot(void)
 	if (val == 1)
 		return 0;
 
+	/* See if a user has put shim into insecure mode.  If so, and if the
+	 * variable doesn't have the runtime attribute set, we might as well
+	 * honor that.
+	 */
+	size = sizeof(moksbstate);
+	status = f_getvar((efi_char16_t *)MokSBState_var_name, &shim_guid,
+			  &attr, &size, &moksbstate);
+
+	/* If it fails, we don't care why.  Default to secure */
+	if (status != EFI_SUCCESS)
+		return 1;
+
+	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) &&
+	    moksbstate == 1)
+		return 0;
+
 	return 1;
 
 out_efi_err:

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

* [PATCH 6/6] efi: Add EFI_SECURE_BOOT bit
  2016-11-17 12:37   ` Lukas Wunner
                       ` (3 preceding siblings ...)
  2016-11-22  0:32     ` [PATCH 5/6] efi: Disable secure boot if shim is in insecure mode David Howells
@ 2016-11-22  0:32     ` David Howells
  2016-11-22 13:04       ` Lukas Wunner
  4 siblings, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-22  0:32 UTC (permalink / raw)
  To: lukas
  Cc: linux-efi, linux-kernel, dhowells, linux-security-module,
	Josh Boyer, keyrings

From: Josh Boyer <jwboyer@fedoraproject.org>

UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
for use with efi_enabled.

Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/x86/kernel/setup.c |    5 +++++
 include/linux/efi.h     |    1 +
 2 files changed, 6 insertions(+)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 9c337b0e8ba7..a197221a451b 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1160,6 +1160,11 @@ void __init setup_arch(char **cmdline_p)
 
 	io_delay_init();
 
+	if (boot_params.secure_boot) {
+		set_bit(EFI_SECURE_BOOT, &efi.flags);
+		pr_info("Secure boot enabled\n");
+	}
+
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 615d8704f048..3864de3b40ad 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1066,6 +1066,7 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_ARCH_1		7	/* First arch-specific bit */
 #define EFI_DBG			8	/* Print additional debug info at runtime */
 #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
+#define EFI_SECURE_BOOT		10	/* Are we in Secure Boot mode? */
 
 #ifdef CONFIG_EFI
 /*

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  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
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 76+ messages in thread
From: Dominik Brodowski @ 2016-11-22  6:12 UTC (permalink / raw)
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel, gnomes

On Mon, Nov 21, 2016 at 11:10:52PM +0000, David Howells wrote:
> One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> wrote:
> 
> > You need to filter or lock down kernel module options because a lot of
> > modules let you set the I/O port or similar (eg mmio) which means you can
> > hack the entire machine with say the 8250 driver just by using it with an
> > mmio of the right location to patch the secure state to zero just by
> > getting the ability to write to the modules conf file.
> 
> Is the attached patch the right sort of idea?  [Note that I haven't actually
> compiled most of these drivers to check my changes yet.]
> 
> David
> ---
> commit 8613a9655dad98c3358d82a9c4310cebdcb852ae
> Author: David Howells <dhowells@redhat.com>
> Date:   Mon Nov 21 22:43:27 2016 +0000
> 
>     Lock down drivers that can have io ports, io mem, irqs and dma changed
>     
>     Lock down drivers that can have io ports, io mem, irqs and dma channels
>     changed so that they can't be used to cause hardware to access the kernel
>     image.
>     
>     Notes:
>     
>      (1) module_isa_driver() gets an extra parameter that, if true, will cause
>          the module load to be rejected if the kernel is locked down.
>     
>      (2) module_driver() calls module_lockdown_check() to ask if the module
>          load should be rejected if the kernel is locked down.  This is a macro
>          that should be #undef'd and then redefined right before
>          module_driver() is called.
>     
>      (3) module_pci_driver() is a wrapper around module_driver(), so the same
>          macro is used as in (2).
>     
>      (4) A number of drivers use parport 'ports' - so I haven't touched those.

You might also need to disable CIS overrides and CIS firmware loading for PCMCIA
drivers, I presume. That needs two changes:

	- Abort in drivers/pcmcia/ds.c::pcmcia_load_firmware() or disable
	  the CONFIG_PCMCIA_LOAD_CIS config option permanently.

	- Abort in drivers/pcmcia/cistpl.c::pccard_store_cis() or remove
	  write access to the "cis" file in
	  drivers/pcmcia/cistpl.c::pccard_cis_attr

Best,
	Dominik

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
       [not found]       ` <147977469914.6360.17194649697208113702.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 10:20         ` Lukas Wunner
  0 siblings, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 10:20 UTC (permalink / raw)
  To: David Howells
  Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, Nov 22, 2016 at 12:31:39AM +0000, David Howells wrote:
> Provide the ability to perform mixed-mode runtime service calls for x86 in
> the same way that commit 0a637ee61247bd4bed9b2a07568ef7a1cfc76187 provides

Small nit, checkpatch usually complains that this should be written as
12-character SHA-1 followed by the commit subject, i.e.

0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")

Other than that LGTM.  Same for patch 2 of this series.

Thanks,

Lukas

> the ability to invoke arbitrary boot services.
> 
> Suggested-by: Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
> Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> 
>  arch/x86/boot/compressed/eboot.c   |    1 +
>  arch/x86/boot/compressed/head_32.S |    6 +++---
>  arch/x86/boot/compressed/head_64.S |    8 ++++----
>  arch/x86/include/asm/efi.h         |    5 +++++
>  4 files changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index ff01c8fc76f7..c8c32ebcdfdb 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -32,6 +32,7 @@ static void setup_boot_services##bits(struct efi_config *c)		\
>  									\
>  	table = (typeof(table))sys_table;				\
>  									\
> +	c->runtime_services = table->runtime;				\
>  	c->boot_services = table->boottime;				\
>  	c->text_output = table->con_out;				\
>  }
> diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
> index fd0b6a272dd5..d85b9625e836 100644
> --- a/arch/x86/boot/compressed/head_32.S
> +++ b/arch/x86/boot/compressed/head_32.S
> @@ -82,7 +82,7 @@ ENTRY(efi_pe_entry)
>  
>  	/* Relocate efi_config->call() */
>  	leal	efi32_config(%esi), %eax
> -	add	%esi, 32(%eax)
> +	add	%esi, 40(%eax)
>  	pushl	%eax
>  
>  	call	make_boot_params
> @@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry)
>  
>  	/* Relocate efi_config->call() */
>  	leal	efi32_config(%esi), %eax
> -	add	%esi, 32(%eax)
> +	add	%esi, 40(%eax)
>  	pushl	%eax
>  2:
>  	call	efi_main
> @@ -264,7 +264,7 @@ relocated:
>  #ifdef CONFIG_EFI_STUB
>  	.data
>  efi32_config:
> -	.fill 4,8,0
> +	.fill 5,8,0
>  	.long efi_call_phys
>  	.long 0
>  	.byte 0
> diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
> index efdfba21a5b2..beab8322f72a 100644
> --- a/arch/x86/boot/compressed/head_64.S
> +++ b/arch/x86/boot/compressed/head_64.S
> @@ -265,7 +265,7 @@ ENTRY(efi_pe_entry)
>  	/*
>  	 * Relocate efi_config->call().
>  	 */
> -	addq	%rbp, efi64_config+32(%rip)
> +	addq	%rbp, efi64_config+40(%rip)
>  
>  	movq	%rax, %rdi
>  	call	make_boot_params
> @@ -285,7 +285,7 @@ handover_entry:
>  	 * Relocate efi_config->call().
>  	 */
>  	movq	efi_config(%rip), %rax
> -	addq	%rbp, 32(%rax)
> +	addq	%rbp, 40(%rax)
>  2:
>  	movq	efi_config(%rip), %rdi
>  	call	efi_main
> @@ -457,14 +457,14 @@ efi_config:
>  #ifdef CONFIG_EFI_MIXED
>  	.global efi32_config
>  efi32_config:
> -	.fill	4,8,0
> +	.fill	5,8,0
>  	.quad	efi64_thunk
>  	.byte	0
>  #endif
>  
>  	.global efi64_config
>  efi64_config:
> -	.fill	4,8,0
> +	.fill	5,8,0
>  	.quad	efi_call
>  	.byte	1
>  #endif /* CONFIG_EFI_STUB */
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index e99675b9c861..2f77bcefe6b4 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -191,6 +191,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
>  struct efi_config {
>  	u64 image_handle;
>  	u64 table;
> +	u64 runtime_services;
>  	u64 boot_services;
>  	u64 text_output;
>  	efi_status_t (*call)(unsigned long, ...);
> @@ -226,6 +227,10 @@ static inline bool efi_is_64bit(void)
>  #define __efi_call_early(f, ...)					\
>  	__efi_early()->call((unsigned long)f, __VA_ARGS__);
>  
> +#define efi_call_runtime(f, ...)					\
> +	__efi_early()->call(efi_table_attr(efi_runtime_services, f,	\
> +		__efi_early()->runtime_services), __VA_ARGS__)
> +
>  extern bool efi_reboot_required(void);
>  
>  #else
> 

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

* Re: [PATCH 4/6] efi: Get the secure boot status
  2016-11-22  0:32     ` [PATCH 4/6] efi: Get the secure boot status David Howells
@ 2016-11-22 10:44       ` Lukas Wunner
       [not found]         ` <20161122104401.GC1552-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
  2016-11-22 14:47       ` David Howells
       [not found]       ` <7199.1479826047-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2 siblings, 1 reply; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 10:44 UTC (permalink / raw)
  To: David Howells
  Cc: Matthew Garrett, linux-efi, linux-kernel, linux-security-module,
	keyrings

On Tue, Nov 22, 2016 at 12:32:01AM +0000, David Howells wrote:
> Get the firmware's secure-boot status in the kernel boot wrapper and stash
> it somewhere that the main kernel image can find.

That's a bit terse.  You could write here that you're moving the
existing ARM function to generic stub code to be able to reuse it
on x86.

Further comments below.


> 
> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  Documentation/x86/zero-page.txt           |    2 +
>  arch/x86/boot/compressed/eboot.c          |    5 ++
>  arch/x86/include/uapi/asm/bootparam.h     |    3 +
>  drivers/firmware/efi/libstub/Makefile     |    2 -
>  drivers/firmware/efi/libstub/arm-stub.c   |   46 --------------------
>  drivers/firmware/efi/libstub/secureboot.c |   66 +++++++++++++++++++++++++++++
>  include/linux/efi.h                       |    2 +
>  7 files changed, 78 insertions(+), 48 deletions(-)
>  create mode 100644 drivers/firmware/efi/libstub/secureboot.c
> 
> diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
> index 95a4d34af3fd..b8527c6b7646 100644
> --- 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
> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
> index c8c32ebcdfdb..fd6506de480d 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -12,6 +12,7 @@
>  #include <asm/efi.h>
>  #include <asm/setup.h>
>  #include <asm/desc.h>
> +#include <asm/bootparam_utils.h>
>  
>  #include "../string.h"
>  #include "eboot.h"
> @@ -1158,6 +1159,10 @@ struct boot_params *efi_main(struct efi_config *c,
>  	else
>  		setup_boot_services32(efi_early);
>  
> +	sanitize_boot_params(boot_params);

What is the connection of this change to the rest of the patch?
Needs an explanation in the commit message.


> +
> +	boot_params->secure_boot = efi_get_secureboot();
> +
>  	setup_graphics(boot_params);
>  
>  	setup_efi_pci(boot_params);
> diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
> index b10bf319ed20..5138dacf8bb8 100644
> --- a/arch/x86/include/uapi/asm/bootparam.h
> +++ b/arch/x86/include/uapi/asm/bootparam.h
> @@ -135,7 +135,8 @@ struct boot_params {
>  	__u8  eddbuf_entries;				/* 0x1e9 */
>  	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
>  	__u8  kbd_status;				/* 0x1eb */
> -	__u8  _pad5[3];					/* 0x1ec */
> +	__u8  secure_boot;				/* 0x1ec */
> +	__u8  _pad5[2];					/* 0x1ed */
>  	/*
>  	 * The sentinel is set to a nonzero value (0xff) in header.S.
>  	 *
> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
> index 6621b13c370f..9af966863612 100644
> --- a/drivers/firmware/efi/libstub/Makefile
> +++ b/drivers/firmware/efi/libstub/Makefile
> @@ -28,7 +28,7 @@ OBJECT_FILES_NON_STANDARD	:= y
>  # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
>  KCOV_INSTRUMENT			:= n
>  
> -lib-y				:= efi-stub-helper.o gop.o
> +lib-y				:= efi-stub-helper.o gop.o secureboot.o
>  
>  # include the stub's generic dependencies from lib/ when building for ARM/arm64
>  arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
> diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
> index b4f7d78f9e8b..552ee61ddbed 100644
> --- a/drivers/firmware/efi/libstub/arm-stub.c
> +++ b/drivers/firmware/efi/libstub/arm-stub.c
> @@ -20,52 +20,6 @@
>  
>  bool __nokaslr;
>  
> -static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
> -{
> -	static efi_char16_t const sb_var_name[] = {
> -		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
> -	static efi_char16_t const sm_var_name[] = {
> -		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
> -
> -	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
> -	efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
> -	u8 val;
> -	unsigned long size = sizeof(val);
> -	efi_status_t status;
> -
> -	status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
> -			  NULL, &size, &val);
> -
> -	if (status != EFI_SUCCESS)
> -		goto out_efi_err;
> -
> -	if (val == 0)
> -		return 0;
> -
> -	status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
> -			  NULL, &size, &val);
> -
> -	if (status != EFI_SUCCESS)
> -		goto out_efi_err;
> -
> -	if (val == 1)
> -		return 0;
> -
> -	return 1;
> -
> -out_efi_err:
> -	switch (status) {
> -	case EFI_NOT_FOUND:
> -		return 0;
> -	case EFI_DEVICE_ERROR:
> -		return -EIO;
> -	case EFI_SECURITY_VIOLATION:
> -		return -EACCES;
> -	default:
> -		return -EINVAL;
> -	}
> -}
> -
>  efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
>  			     void *__image, void **__fh)
>  {
> diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
> new file mode 100644
> index 000000000000..e44d8c9ee150
> --- /dev/null
> +++ b/drivers/firmware/efi/libstub/secureboot.c
> @@ -0,0 +1,66 @@
> +/*
> + * Secure boot handling.
> + *
> + * Copyright (C) 2013,2014 Linaro Limited
> + *     Roy Franz <roy.franz@linaro.org
> + * Copyright (C) 2013 Red Hat, Inc.
> + *     Mark Salter <msalter@redhat.com>
> + *
> + * This file is part of the Linux kernel, and is made available under the
> + * terms of the GNU General Public License version 2.
> + *
> + */
> +
> +#include <linux/efi.h>
> +#include <linux/sort.h>

You don't need sort.h.


> +#include <asm/efi.h>
> +
> +#include "efistub.h"

>From a cursory look at efistub.h, you don't seem to need this either.


> +
> +int efi_get_secureboot(void)

It looks like you didn't compile-test this on ARM.

You dropped the efi_system_table_t *sys_table_arg argument but this
isn't defined anywhere as a static global.


> +{
> +	static const efi_char16_t const sb_var_name[] = {
> +		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
> +	static const efi_char16_t const sm_var_name[] = {
> +		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
> +
> +	static const efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
> +

Gratuitous newline in-between variable declarations.

> +	u8 val;
> +	unsigned long size = sizeof(val);
> +	efi_status_t status;
> +
> +#define f_getvar(...) efi_call_runtime(get_variable, __VA_ARGS__)
> +
> +	status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
> +			  NULL, &size, &val);

Just replace the f_getvar yourself instead of having cpp do it:

	status = efi_call_runtime(get_variable, (efi_char16_t *)sb_var_name,
				  (efi_guid_t *)&var_guid, NULL, &size, &val);


> +
> +	if (status != EFI_SUCCESS)
> +		goto out_efi_err;
> +
> +	if (val == 0)
> +		return 0;
> +
> +	status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
> +			  NULL, &size, &val);

Same here.


> +
> +	if (status != EFI_SUCCESS)
> +		goto out_efi_err;
> +
> +	if (val == 1)
> +		return 0;
> +
> +	return 1;
> +
> +out_efi_err:
> +	switch (status) {
> +	case EFI_NOT_FOUND:
> +		return 0;
> +	case EFI_DEVICE_ERROR:
> +		return -EIO;
> +	case EFI_SECURITY_VIOLATION:
> +		return -EACCES;
> +	default:
> +		return -EINVAL;
> +	}

The "out_efi_err" portion differs from the previous version of this
patch.  Setting a __u8 to a negative value, is this really what you
want?

Thanks,

Lukas

> +}
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 24db4e5ec817..615d8704f048 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1477,6 +1477,8 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
>  bool efi_runtime_disabled(void);
>  extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
>  
> +int efi_get_secureboot(void);
> +
>  /*
>   * Arch code can implement the following three template macros, avoiding
>   * reptition for the void/non-void return cases of {__,}efi_call_virt():
> 

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

* Re: [PATCH 4/6] efi: Get the secure boot status
       [not found]         ` <20161122104401.GC1552-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
@ 2016-11-22 10:49           ` Ard Biesheuvel
  2016-11-22 14:52           ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: Ard Biesheuvel @ 2016-11-22 10:49 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: David Howells, Matthew Garrett, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-security-module,
	keyrings-u79uwXL29TY76Z2rM5mHXA

On 22 November 2016 at 10:44, Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org> wrote:
> On Tue, Nov 22, 2016 at 12:32:01AM +0000, David Howells wrote:
>> Get the firmware's secure-boot status in the kernel boot wrapper and stash
>> it somewhere that the main kernel image can find.
>
> That's a bit terse.  You could write here that you're moving the
> existing ARM function to generic stub code to be able to reuse it
> on x86.
>
> Further comments below.
>
>
>>
>> Signed-off-by: Matthew Garrett <matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA@public.gmane.org>
>> Signed-off-by: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>>
>>  Documentation/x86/zero-page.txt           |    2 +
>>  arch/x86/boot/compressed/eboot.c          |    5 ++
>>  arch/x86/include/uapi/asm/bootparam.h     |    3 +
>>  drivers/firmware/efi/libstub/Makefile     |    2 -
>>  drivers/firmware/efi/libstub/arm-stub.c   |   46 --------------------
>>  drivers/firmware/efi/libstub/secureboot.c |   66 +++++++++++++++++++++++++++++
>>  include/linux/efi.h                       |    2 +
>>  7 files changed, 78 insertions(+), 48 deletions(-)
>>  create mode 100644 drivers/firmware/efi/libstub/secureboot.c
>>
>> diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
>> index 95a4d34af3fd..b8527c6b7646 100644
>> --- 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
>> diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
>> index c8c32ebcdfdb..fd6506de480d 100644
>> --- a/arch/x86/boot/compressed/eboot.c
>> +++ b/arch/x86/boot/compressed/eboot.c
>> @@ -12,6 +12,7 @@
>>  #include <asm/efi.h>
>>  #include <asm/setup.h>
>>  #include <asm/desc.h>
>> +#include <asm/bootparam_utils.h>
>>
>>  #include "../string.h"
>>  #include "eboot.h"
>> @@ -1158,6 +1159,10 @@ struct boot_params *efi_main(struct efi_config *c,
>>       else
>>               setup_boot_services32(efi_early);
>>
>> +     sanitize_boot_params(boot_params);
>
> What is the connection of this change to the rest of the patch?
> Needs an explanation in the commit message.
>
>
>> +
>> +     boot_params->secure_boot = efi_get_secureboot();
>> +
>>       setup_graphics(boot_params);
>>
>>       setup_efi_pci(boot_params);
>> diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
>> index b10bf319ed20..5138dacf8bb8 100644
>> --- a/arch/x86/include/uapi/asm/bootparam.h
>> +++ b/arch/x86/include/uapi/asm/bootparam.h
>> @@ -135,7 +135,8 @@ struct boot_params {
>>       __u8  eddbuf_entries;                           /* 0x1e9 */
>>       __u8  edd_mbr_sig_buf_entries;                  /* 0x1ea */
>>       __u8  kbd_status;                               /* 0x1eb */
>> -     __u8  _pad5[3];                                 /* 0x1ec */
>> +     __u8  secure_boot;                              /* 0x1ec */
>> +     __u8  _pad5[2];                                 /* 0x1ed */
>>       /*
>>        * The sentinel is set to a nonzero value (0xff) in header.S.
>>        *
>> diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
>> index 6621b13c370f..9af966863612 100644
>> --- a/drivers/firmware/efi/libstub/Makefile
>> +++ b/drivers/firmware/efi/libstub/Makefile
>> @@ -28,7 +28,7 @@ OBJECT_FILES_NON_STANDARD   := y
>>  # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
>>  KCOV_INSTRUMENT                      := n
>>
>> -lib-y                                := efi-stub-helper.o gop.o
>> +lib-y                                := efi-stub-helper.o gop.o secureboot.o
>>
>>  # include the stub's generic dependencies from lib/ when building for ARM/arm64
>>  arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
>> diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
>> index b4f7d78f9e8b..552ee61ddbed 100644
>> --- a/drivers/firmware/efi/libstub/arm-stub.c
>> +++ b/drivers/firmware/efi/libstub/arm-stub.c
>> @@ -20,52 +20,6 @@
>>
>>  bool __nokaslr;
>>
>> -static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
>> -{
>> -     static efi_char16_t const sb_var_name[] = {
>> -             'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
>> -     static efi_char16_t const sm_var_name[] = {
>> -             'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
>> -
>> -     efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
>> -     efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
>> -     u8 val;
>> -     unsigned long size = sizeof(val);
>> -     efi_status_t status;
>> -
>> -     status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
>> -                       NULL, &size, &val);
>> -
>> -     if (status != EFI_SUCCESS)
>> -             goto out_efi_err;
>> -
>> -     if (val == 0)
>> -             return 0;
>> -
>> -     status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
>> -                       NULL, &size, &val);
>> -
>> -     if (status != EFI_SUCCESS)
>> -             goto out_efi_err;
>> -
>> -     if (val == 1)
>> -             return 0;
>> -
>> -     return 1;
>> -
>> -out_efi_err:
>> -     switch (status) {
>> -     case EFI_NOT_FOUND:
>> -             return 0;
>> -     case EFI_DEVICE_ERROR:
>> -             return -EIO;
>> -     case EFI_SECURITY_VIOLATION:
>> -             return -EACCES;
>> -     default:
>> -             return -EINVAL;
>> -     }
>> -}
>> -
>>  efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
>>                            void *__image, void **__fh)
>>  {
>> diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
>> new file mode 100644
>> index 000000000000..e44d8c9ee150
>> --- /dev/null
>> +++ b/drivers/firmware/efi/libstub/secureboot.c
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Secure boot handling.
>> + *
>> + * Copyright (C) 2013,2014 Linaro Limited
>> + *     Roy Franz <roy.franz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org
>> + * Copyright (C) 2013 Red Hat, Inc.
>> + *     Mark Salter <msalter-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> + *
>> + * This file is part of the Linux kernel, and is made available under the
>> + * terms of the GNU General Public License version 2.
>> + *
>> + */
>> +
>> +#include <linux/efi.h>
>> +#include <linux/sort.h>
>
> You don't need sort.h.
>
>
>> +#include <asm/efi.h>
>> +
>> +#include "efistub.h"
>
> From a cursory look at efistub.h, you don't seem to need this either.
>
>
>> +
>> +int efi_get_secureboot(void)
>
> It looks like you didn't compile-test this on ARM.
>
> You dropped the efi_system_table_t *sys_table_arg argument but this
> isn't defined anywhere as a static global.
>

That is actually a thing that has been annoying me: the efi_call_xxx
macros on ARM/arm64 rely on sys_table_arg being defined in the current
scope, which hides this dependency from users of the macro, and is
also a pain given that you are forced to use the exact name
'sys_table_arg'. Patches that clean that up are gladly accepted, or I
may take a stab at this myself (but not for a week or two)

>
>> +{
>> +     static const efi_char16_t const sb_var_name[] = {
>> +             'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
>> +     static const efi_char16_t const sm_var_name[] = {
>> +             'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
>> +
>> +     static const efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
>> +
>
> Gratuitous newline in-between variable declarations.
>
>> +     u8 val;
>> +     unsigned long size = sizeof(val);
>> +     efi_status_t status;
>> +
>> +#define f_getvar(...) efi_call_runtime(get_variable, __VA_ARGS__)
>> +
>> +     status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
>> +                       NULL, &size, &val);
>
> Just replace the f_getvar yourself instead of having cpp do it:
>
>         status = efi_call_runtime(get_variable, (efi_char16_t *)sb_var_name,
>                                   (efi_guid_t *)&var_guid, NULL, &size, &val);
>
>
>> +
>> +     if (status != EFI_SUCCESS)
>> +             goto out_efi_err;
>> +
>> +     if (val == 0)
>> +             return 0;
>> +
>> +     status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid,
>> +                       NULL, &size, &val);
>
> Same here.
>
>
>> +
>> +     if (status != EFI_SUCCESS)
>> +             goto out_efi_err;
>> +
>> +     if (val == 1)
>> +             return 0;
>> +
>> +     return 1;
>> +
>> +out_efi_err:
>> +     switch (status) {
>> +     case EFI_NOT_FOUND:
>> +             return 0;
>> +     case EFI_DEVICE_ERROR:
>> +             return -EIO;
>> +     case EFI_SECURITY_VIOLATION:
>> +             return -EACCES;
>> +     default:
>> +             return -EINVAL;
>> +     }
>
> The "out_efi_err" portion differs from the previous version of this
> patch.  Setting a __u8 to a negative value, is this really what you
> want?
>
> Thanks,
>
> Lukas
>
>> +}
>> diff --git a/include/linux/efi.h b/include/linux/efi.h
>> index 24db4e5ec817..615d8704f048 100644
>> --- a/include/linux/efi.h
>> +++ b/include/linux/efi.h
>> @@ -1477,6 +1477,8 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
>>  bool efi_runtime_disabled(void);
>>  extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
>>
>> +int efi_get_secureboot(void);
>> +
>>  /*
>>   * Arch code can implement the following three template macros, avoiding
>>   * reptition for the void/non-void return cases of {__,}efi_call_virt():
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-efi" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 5/6] efi: Disable secure boot if shim is in insecure mode
  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
  0 siblings, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 13:03 UTC (permalink / raw)
  To: David Howells
  Cc: linux-efi, linux-kernel, linux-security-module, Josh Boyer, keyrings

On Tue, Nov 22, 2016 at 12:32:08AM +0000, David Howells wrote:
> From: Josh Boyer <jwboyer@fedoraproject.org>
> 
> 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>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  drivers/firmware/efi/libstub/secureboot.c |   22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
> index e44d8c9ee150..d928398a3a52 100644
> --- a/drivers/firmware/efi/libstub/secureboot.c
> +++ b/drivers/firmware/efi/libstub/secureboot.c
> @@ -23,10 +23,14 @@ int efi_get_secureboot(void)
>  		'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
>  	static const efi_char16_t const sm_var_name[] = {
>  		'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
> +	static efi_char16_t const MokSBState_var_name[] = {
> +		'M', 'o', 'k', 'S', 'B', 'S', 't', 'a', 't', 'e', 0 };
>  
>  	static const efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
> +	static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
>  
> -	u8 val;
> +	u32 attr;
> +	u8 val, moksbstate;
>  	unsigned long size = sizeof(val);
>  	efi_status_t status;
>  
> @@ -50,6 +54,22 @@ int efi_get_secureboot(void)
>  	if (val == 1)
>  		return 0;
>  
> +	/* See if a user has put shim into insecure mode.  If so, and if the
> +	 * variable doesn't have the runtime attribute set, we might as well
> +	 * honor that.
> +	 */
> +	size = sizeof(moksbstate);
> +	status = f_getvar((efi_char16_t *)MokSBState_var_name, &shim_guid,
> +			  &attr, &size, &moksbstate);

Please use efi_call_runtime() instead of f_getvar().

> +
> +	/* If it fails, we don't care why.  Default to secure */
> +	if (status != EFI_SUCCESS)
> +		return 1;
> +
> +	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) &&
> +	    moksbstate == 1)

This would fit on a single line.

Thanks,

Lukas

> +		return 0;
> +
>  	return 1;
>  
>  out_efi_err:
> 

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

* Re: [PATCH 6/6] efi: Add EFI_SECURE_BOOT bit
  2016-11-22  0:32     ` [PATCH 6/6] efi: Add EFI_SECURE_BOOT bit David Howells
@ 2016-11-22 13:04       ` Lukas Wunner
  0 siblings, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 13:04 UTC (permalink / raw)
  To: David Howells
  Cc: linux-efi, linux-kernel, linux-security-module, Josh Boyer, keyrings

On Tue, Nov 22, 2016 at 12:32:15AM +0000, David Howells wrote:
> From: Josh Boyer <jwboyer@fedoraproject.org>
> 
> UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
> for use with efi_enabled.

Please add an explanation what you plan to do with this bit going forward.

Thanks,

Lukas

> 
> Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  arch/x86/kernel/setup.c |    5 +++++
>  include/linux/efi.h     |    1 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 9c337b0e8ba7..a197221a451b 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -1160,6 +1160,11 @@ void __init setup_arch(char **cmdline_p)
>  
>  	io_delay_init();
>  
> +	if (boot_params.secure_boot) {
> +		set_bit(EFI_SECURE_BOOT, &efi.flags);
> +		pr_info("Secure boot enabled\n");
> +	}
> +
>  	/*
>  	 * Parse the ACPI tables for possible boot-time SMP configuration.
>  	 */
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 615d8704f048..3864de3b40ad 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -1066,6 +1066,7 @@ extern int __init efi_setup_pcdp_console(char *);
>  #define EFI_ARCH_1		7	/* First arch-specific bit */
>  #define EFI_DBG			8	/* Print additional debug info at runtime */
>  #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
> +#define EFI_SECURE_BOOT		10	/* Are we in Secure Boot mode? */
>  
>  #ifdef CONFIG_EFI
>  /*
> 

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
  2016-11-22  0:31     ` [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services David Howells
       [not found]       ` <147977469914.6360.17194649697208113702.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 14:17       ` David Howells
  2016-11-22 14:58         ` Joe Perches
       [not found]         ` <1479826691.1942.11.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
  1 sibling, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-22 14:17 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells, linux-efi, linux-security-module, keyrings, linux-kernel

Lukas Wunner <lukas@wunner.de> wrote:

> Small nit, checkpatch usually complains that this should be written as
> 12-character SHA-1 followed by the commit subject, i.e.
> 
> 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")

In this case, checkpatch is wrong.

David

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

* Re: [PATCH 4/6] efi: Get the secure boot status
  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 14:47       ` David Howells
  2016-11-22 20:30         ` Lukas Wunner
  2016-11-23  0:02         ` David Howells
       [not found]       ` <7199.1479826047-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-22 14:47 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells, Matthew Garrett, linux-efi, linux-kernel,
	linux-security-module, keyrings

Lukas Wunner <lukas@wunner.de> wrote:

> > +int efi_get_secureboot(void)
> 
> It looks like you didn't compile-test this on ARM.

Yes.  What arm config would you suggest?

> > +#define f_getvar(...) efi_call_runtime(get_variable, __VA_ARGS__)
> > +
> > +	status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid,
> > +			  NULL, &size, &val);
>
> Just replace the f_getvar yourself instead of having cpp do it:
>
> 	status = efi_call_runtime(get_variable, (efi_char16_t *)sb_var_name,
> 				  (efi_guid_t *)&var_guid, NULL, &size, &val);

That makes it less clear.  I think something like this makes it much more
obvious:

    static efi_status_t get_efi_var(const efi_char16_t *name,
				const efi_guid_t *vendor,
				u32 *attr,
				unsigned long *data_size, void *data)
    {
	return efi_call_runtime(get_variable,
				(efi_char16_t *)name, (efi_guid_t *)vendor,
				attr, data_size, data);
    }

And then doing:

	status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid,
			     NULL, &size, &val);

which the compiler will inline.

> The "out_efi_err" portion differs from the previous version of this
> patch.  Setting a __u8 to a negative value, is this really what you
> want?

Eh?  efi_get_secureboot() returns an int as before.  The out_efi_err: portions
are exactly the same:

> -static int efi_get_secureboot(...)	> +int efi_get_secureboot(...)
> ...					> ...
> -out_efi_err:				> +out_efi_err:
> -	switch (status) {		> +	switch (status) {
> -	case EFI_NOT_FOUND:		> +	case EFI_NOT_FOUND:
> -		return 0;		> +		return 0;
> -	case EFI_DEVICE_ERROR:		> +	case EFI_DEVICE_ERROR:
> -		return -EIO;		> +		return -EIO;
> -	case EFI_SECURITY_VIOLATION:	> +	case EFI_SECURITY_VIOLATION:
> -		return -EACCES;		> +		return -EACCES;
> -	default:			> +	default:
> -		return -EINVAL;		> +		return -EINVAL;
> -	}				> +	}
> -}

David

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

* Re: [PATCH 4/6] efi: Get the secure boot status
       [not found]         ` <20161122104401.GC1552-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
  2016-11-22 10:49           ` Ard Biesheuvel
@ 2016-11-22 14:52           ` David Howells
       [not found]             ` <25371.1479826321-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  1 sibling, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-22 14:52 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Matthew Garrett,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA

Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org> wrote:

> You dropped the efi_system_table_t *sys_table_arg argument but this
> isn't defined anywhere as a static global.

It seems to me that passing this value in on x86 is probably a bad idea as
it's not mixed-mode safe.  Should I just pass NULL there in that case?

David

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

* Re: [PATCH 4/6] efi: Get the secure boot status
       [not found]       ` <7199.1479826047-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 14:57         ` David Howells
  0 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-22 14:57 UTC (permalink / raw)
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Lukas Wunner, Matthew Garrett,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA

David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> That makes it less clear.  I think something like this makes it much more
> obvious:
> 
>     static efi_status_t get_efi_var(const efi_char16_t *name,
> 				const efi_guid_t *vendor,
> 				u32 *attr,
> 				unsigned long *data_size, void *data)
>     {
> 	return efi_call_runtime(get_variable,
> 				(efi_char16_t *)name, (efi_guid_t *)vendor,
> 				attr, data_size, data);
>     }
> 
> And then doing:
> 
> 	status = get_efi_var(efi_SecureBoot_name, &efi_variable_guid,
> 			     NULL, &size, &val);
> 
> which the compiler will inline.

Of course, it has to be a macro because efi_call_runtime() has an undeclared
argument on ARM...

David

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
  2016-11-22 14:17       ` David Howells
@ 2016-11-22 14:58         ` Joe Perches
       [not found]         ` <1479826691.1942.11.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
  1 sibling, 0 replies; 76+ messages in thread
From: Joe Perches @ 2016-11-22 14:58 UTC (permalink / raw)
  To: David Howells, Lukas Wunner
  Cc: linux-efi, linux-security-module, keyrings, linux-kernel

On Tue, 2016-11-22 at 14:17 +0000, David Howells wrote:
> Lukas Wunner <lukas@wunner.de> wrote:
> 
> > Small nit, checkpatch usually complains that this should be written as
> > 12-character SHA-1 followed by the commit subject, i.e.
> > 
> > 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
> 
> In this case, checkpatch is wrong.

Why do you think so?

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
       [not found]         ` <1479826691.1942.11.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
@ 2016-11-22 15:52           ` David Howells
       [not found]             ` <24973.1479829961-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-22 16:40             ` David Howells
  0 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-22 15:52 UTC (permalink / raw)
  To: Joe Perches
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, Lukas Wunner,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org> wrote:

> > > Small nit, checkpatch usually complains that this should be written as
> > > 12-character SHA-1 followed by the commit subject, i.e.
> > > 
> > > 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
> > 
> > In this case, checkpatch is wrong.
>
> Why do you think so?

Actually, checkpatch doesn't complain about embedded commit IDs anymore, so in
that case, it's just about acceptable.

Apart from that, I think we should put in the full SHA-1 commit.  The
probability of a collision in a 12-digit hex number for the >5,000,000 commits
just in Linus's tree is currently at ~4.5% and gradually increasing.  Add in
all the commits in not-yet-upstreamed trees - which might be another million
commits, say - then we're over 6%..

Oh, yes, and speaking of checkpatch, can you make it so that if it sees:

commit 12345...
Author: foo <foo@bar>
Date: blah

   Subject line

   Description lines
   ...
   ...
   ...
   ...

   Signed-off-by-and-suchline-lines

diff ...

with the all description indented by 4 spaces, then assume that it's the
output of git show and not give the warnings about signed-off-by and other
things being indented?

David

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
       [not found]             ` <24973.1479829961-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 16:25               ` Joe Perches
  0 siblings, 0 replies; 76+ messages in thread
From: Joe Perches @ 2016-11-22 16:25 UTC (permalink / raw)
  To: David Howells
  Cc: Lukas Wunner, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, 2016-11-22 at 15:52 +0000, David Howells wrote:
> Joe Perches <joe-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org> wrote:
> 
> > > > Small nit, checkpatch usually complains that this should be written as
> > > > 12-character SHA-1 followed by the commit subject, i.e.
> > > > 
> > > > 0a637ee61247 ("x86/efi: Allow invocation of arbitrary boot services")
> > > 
> > > In this case, checkpatch is wrong.
> > 
> > Why do you think so?
> 
> Actually, checkpatch doesn't complain about embedded commit IDs anymore, so in
> that case, it's just about acceptable.

checkpatch still emits warnings about the format of
commmit IDs.

What version of checkpatch are yuu using?

> Apart from that, I think we should put in the full SHA-1 commit.  The
> probability of a collision in a 12-digit hex number for the >5,000,000 commits
> just in Linus's tree is currently at ~4.5% and gradually increasing.  Add in
> all the commits in not-yet-upstreamed trees - which might be another million
> commits, say - then we're over 6%..

Umm, no, that's not correct.
SHA-1 lengths of 12 are unique for quite awhile yet.

https://blog.cuviper.com/2013/11/10/how-short-can-git-abbreviate/

Using Linus' tree today, from commit 3b404a519815
the current output of the git-uniq-abbrev script is:

$ git-uniq-abbrev 
5048673 objects
 4: 5048673 / 65536
 5: 5007413 / 998721
 6: 1312496 / 623343
 7: 94487 / 47089
 8: 6163 / 3081
 9: 416 / 208
10: 28 / 14
11: 4 / 2
12: 0 / 0
d597639e2036f04f0226761e2d818b31f2db7820
d597639e203a100156501df8a0756fd09573e2de
ef91b6e893a00d903400f8e1303efc4d52b710af
ef91b6e893afc4c4ca488453ea9f19ced5fa5861

> Oh, yes, and speaking of checkpatch, can you make it so that if it sees:
> 
> commit 12345...
> Author: foo <foo@bar>
> Date: blah
> 
>    Subject line
> 
>    Description lines
>    ...
>    ...
>    ...
>    ...
> 
>    Signed-off-by-and-suchline-lines
> 
> diff ...
> 
> with the all description indented by 4 spaces, then assume that it's the
> output of git show and not give the warnings about signed-off-by and other
> things being indented?

No.  Use --format=email as appropriate instead.

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
  2016-11-22 15:52           ` David Howells
       [not found]             ` <24973.1479829961-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 16:40             ` David Howells
  2016-11-22 16:51               ` Joe Perches
  1 sibling, 1 reply; 76+ messages in thread
From: David Howells @ 2016-11-22 16:40 UTC (permalink / raw)
  To: Joe Perches
  Cc: dhowells, Lukas Wunner, linux-efi, linux-security-module,
	keyrings, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 670 bytes --]

Joe Perches <joe@perches.com> wrote:

> Umm, no, that's not correct.
> SHA-1 lengths of 12 are unique for quite awhile yet.
> 
> https://blog.cuviper.com/2013/11/10/how-short-can-git-abbreviate/

The article says:

	1.9% at 12

which is for 3253824 objects (I get 1.86%).

However, that was three years ago, and we now have over five million objects,
so the collision possibility is 4.5% now.

If we add another 2 million over the next three years, then the probability
will be over 8% then.

I've attached my spreadsheet for you to have a look at.

> No.  Use --format=email as appropriate instead.

Fix checkpatch.  This is an entirely reasonable supposition.

David


[-- Attachment #2: birthday-problem.ods --]
[-- Type: application/vnd.oasis.opendocument.spreadsheet, Size: 10627 bytes --]

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

* Re: [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services
  2016-11-22 16:40             ` David Howells
@ 2016-11-22 16:51               ` Joe Perches
  0 siblings, 0 replies; 76+ messages in thread
From: Joe Perches @ 2016-11-22 16:51 UTC (permalink / raw)
  To: David Howells
  Cc: Lukas Wunner, linux-efi, linux-security-module, keyrings, linux-kernel

On Tue, 2016-11-22 at 16:40 +0000, David Howells wrote:
> Joe Perches <joe@perches.com> wrote:
> 
> > Umm, no, that's not correct.
> > SHA-1 lengths of 12 are unique for quite awhile yet.
> > 
> > https://blog.cuviper.com/2013/11/10/how-short-can-git-abbreviate/
> 
> The article says:
> 
> 	1.9% at 12
> 
> which is for 3253824 objects (I get 1.86%).
> 
> However, that was three years ago, and we now have over five million objects,
> so the collision possibility is 4.5% now.
> 
> If we add another 2 million over the next three years, then the probability
> will be over 8% then.
> 
> I've attached my spreadsheet for you to have a look at.
> 
> > No.  Use --format=email as appropriate instead.
> 
> Fix checkpatch.  This is an entirely reasonable supposition.

No.  There's nothing to fix there IMO.
Of course you are welcome to submit patches.

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

* Re: [PATCH 4/6] efi: Get the secure boot status
  2016-11-22 14:47       ` David Howells
@ 2016-11-22 20:30         ` Lukas Wunner
  2016-11-23  0:02         ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 20:30 UTC (permalink / raw)
  To: David Howells
  Cc: Matthew Garrett, linux-efi, linux-kernel, linux-security-module,
	keyrings

On Tue, Nov 22, 2016 at 02:47:27PM +0000, David Howells wrote:
> Lukas Wunner <lukas@wunner.de> wrote:
> > The "out_efi_err" portion differs from the previous version of this
> > patch.  Setting a __u8 to a negative value, is this really what you
> > want?
> 
> Eh?  efi_get_secureboot() returns an int as before.  The out_efi_err:
> portions are exactly the same:

By "the previous version of this patch" I was referring to your
submission of Nov 16, not the existing code in the kernel.
Your patch didn't contain the out_efi_err portion.

You're assigning a negative value to boot_params->secure_boot
(which is declared __u8).

In the next patch you're just checking if the value isn't 0
and you're considerung secure boot to be enabled even though
GetVariable failed.  Hence my question above, is this what
you want?  Likely not, perhaps this is what you really want:

	boot_params->secure_boot = (efi_get_secureboot() == 1);

Best regards,

Lukas

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

* Re: [PATCH 4/6] efi: Get the secure boot status
       [not found]             ` <25371.1479826321-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-22 20:36               ` Lukas Wunner
  0 siblings, 0 replies; 76+ messages in thread
From: Lukas Wunner @ 2016-11-22 20:36 UTC (permalink / raw)
  To: David Howells
  Cc: Matthew Garrett, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	keyrings-u79uwXL29TY76Z2rM5mHXA

On Tue, Nov 22, 2016 at 02:52:01PM +0000, David Howells wrote:
> Lukas Wunner <lukas-JFq808J9C/izQB+pC5nmwQ@public.gmane.org> wrote:
> > You dropped the efi_system_table_t *sys_table_arg argument but this
> > isn't defined anywhere as a static global.
> 
> It seems to me that passing this value in on x86 is probably a bad idea as
> it's not mixed-mode safe.  Should I just pass NULL there in that case?

It's safe, it's merely a pointer below 4 Gig.  Just on dereference it
needs to be cast to the correct variant.  Passing in sys_table_arg is
done all over the place in the EFI stub, see e.g. efi_printk().

Best regards,

Lukas

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

* Re: [PATCH 4/6] efi: Get the secure boot status
  2016-11-22 14:47       ` David Howells
  2016-11-22 20:30         ` Lukas Wunner
@ 2016-11-23  0:02         ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-23  0:02 UTC (permalink / raw)
  To: Lukas Wunner
  Cc: dhowells, Matthew Garrett, linux-efi, linux-kernel,
	linux-security-module, keyrings

Lukas Wunner <lukas@wunner.de> wrote:

> On Tue, Nov 22, 2016 at 02:47:27PM +0000, David Howells wrote:
> > Lukas Wunner <lukas@wunner.de> wrote:
> > > The "out_efi_err" portion differs from the previous version of this
> > > patch.  Setting a __u8 to a negative value, is this really what you
> > > want?
> > 
> > Eh?  efi_get_secureboot() returns an int as before.  The out_efi_err:
> > portions are exactly the same:
> 
> By "the previous version of this patch" I was referring to your
> submission of Nov 16, not the existing code in the kernel.
> Your patch didn't contain the out_efi_err portion.
> 
> You're assigning a negative value to boot_params->secure_boot
> (which is declared __u8).

Ah, yes.  Sorry, you confused me by specifying a comparison against the last
version.

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  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
       [not found]     ` <20161123192143.GA482-SGhQLRGLuNwb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
       [not found]   ` <26173.1479769852-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
                     ` (2 subsequent siblings)
  4 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-23 12:58 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel, gnomes

Dominik Brodowski <linux@dominikbrodowski.net> wrote:

> You might also need to disable CIS overrides and CIS firmware loading for
> PCMCIA drivers, I presume. That needs two changes:
> 
> 	- Abort in drivers/pcmcia/ds.c::pcmcia_load_firmware() or disable
> 	  the CONFIG_PCMCIA_LOAD_CIS config option permanently.

This really ought to be handled through signature checking in
request_firmware().

> 	- Abort in drivers/pcmcia/cistpl.c::pccard_store_cis() or remove
> 	  write access to the "cis" file in
> 	  drivers/pcmcia/cistpl.c::pccard_cis_attr

What is that doing?  Allowing the device to be reconfigured?

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-23 12:58   ` David Howells
@ 2016-11-23 19:21     ` Dominik Brodowski
       [not found]     ` <20161123192143.GA482-SGhQLRGLuNwb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
  1 sibling, 0 replies; 76+ messages in thread
From: Dominik Brodowski @ 2016-11-23 19:21 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel, gnomes

On Wed, Nov 23, 2016 at 12:58:26PM +0000, David Howells wrote:
> Dominik Brodowski <linux@dominikbrodowski.net> wrote:
> 
> > You might also need to disable CIS overrides and CIS firmware loading for
> > PCMCIA drivers, I presume. That needs two changes:
> > 
> > 	- Abort in drivers/pcmcia/ds.c::pcmcia_load_firmware() or disable
> > 	  the CONFIG_PCMCIA_LOAD_CIS config option permanently.
> 
> This really ought to be handled through signature checking in
> request_firmware().
> 
> > 	- Abort in drivers/pcmcia/cistpl.c::pccard_store_cis() or remove
> > 	  write access to the "cis" file in
> > 	  drivers/pcmcia/cistpl.c::pccard_cis_attr
> 
> What is that doing?  Allowing the device to be reconfigured?

Exactly. It is a different interface for updating the firmware -- which
includes ioports etc. In theory, any access should be limited to areas which
are registered to the bridge devices. But you never know...

Best
	Dominik


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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
       [not found]     ` <20161123192143.GA482-SGhQLRGLuNwb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
@ 2016-11-24 17:34       ` David Howells
  2016-11-24 20:19         ` Dominik Brodowski
  2016-11-25 14:49         ` David Howells
  0 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-24 17:34 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io

Dominik Brodowski <linux-X3ehHDuj6sIIGcDfoQAp7OTW4wlIGRCZ@public.gmane.org> wrote:

> > > 	- Abort in drivers/pcmcia/cistpl.c::pccard_store_cis() or remove
> > > 	  write access to the "cis" file in
> > > 	  drivers/pcmcia/cistpl.c::pccard_cis_attr
> > 
> > What is that doing?  Allowing the device to be reconfigured?
> 
> Exactly. It is a different interface for updating the firmware -- which
> includes ioports etc. In theory, any access should be limited to areas which
> are registered to the bridge devices. But you never know...

Ah, I see.  Should this be using request_firmware()?

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-24 17:34       ` David Howells
@ 2016-11-24 20:19         ` Dominik Brodowski
  2016-11-25 14:49         ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: Dominik Brodowski @ 2016-11-24 20:19 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel, gnomes

On Thu, Nov 24, 2016 at 05:34:45PM +0000, David Howells wrote:
> Dominik Brodowski <linux@dominikbrodowski.net> wrote:
> 
> > > > 	- Abort in drivers/pcmcia/cistpl.c::pccard_store_cis() or remove
> > > > 	  write access to the "cis" file in
> > > > 	  drivers/pcmcia/cistpl.c::pccard_cis_attr
> > > 
> > > What is that doing?  Allowing the device to be reconfigured?
> > 
> > Exactly. It is a different interface for updating the firmware -- which
> > includes ioports etc. In theory, any access should be limited to areas which
> > are registered to the bridge devices. But you never know...
> 
> Ah, I see.  Should this be using request_firmware()?

For most cases, request_firmware() is being used -- for some rare cases,
however, this alternative interface is provided for. It should be pretty
safe nowadays to make pccard_cis_attr read-only (and who uses PCMCIA
nowadays anyway?).

Best,
	Dominik

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-24 17:34       ` David Howells
  2016-11-24 20:19         ` Dominik Brodowski
@ 2016-11-25 14:49         ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-25 14:49 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel, gnomes

Dominik Brodowski <linux@dominikbrodowski.net> wrote:

> For most cases, request_firmware() is being used -- for some rare cases,
> however, this alternative interface is provided for. It should be pretty
> safe nowadays to make pccard_cis_attr read-only (and who uses PCMCIA
> nowadays anyway?).

Have a look at the top patch here:

	http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=efi-lock-down

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
       [not found]   ` <26173.1479769852-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-28 22:32     ` Corey Minyard
  0 siblings, 0 replies; 76+ messages in thread
From: Corey Minyard @ 2016-11-28 22:32 UTC (permalink / raw)
  To: David Howells, One Thousand Gnomes
  Cc: keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 11/21/2016 05:10 PM, David Howells wrote:
> One Thousand Gnomes <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> wrote:
>
>> You need to filter or lock down kernel module options because a lot of
>> modules let you set the I/O port or similar (eg mmio) which means you can
>> hack the entire machine with say the 8250 driver just by using it with an
>> mmio of the right location to patch the secure state to zero just by
>> getting the ability to write to the modules conf file.
> Is the attached patch the right sort of idea?  [Note that I haven't actually
> compiled most of these drivers to check my changes yet.]
>
> David
> ---

snip

> diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
> index a112c0146012..7fb9c299a183 100644
> --- a/drivers/char/ipmi/ipmi_si_intf.c
> +++ b/drivers/char/ipmi/ipmi_si_intf.c
> @@ -3725,6 +3725,12 @@ static int init_ipmi_si(void)
>   	struct smi_info *e;
>   	enum ipmi_addr_src type = SI_INVALID;
>   
> +	if ((num_addrs || num_ports || num_irqs) &&
> +	    kernel_is_locked_down()) {
> +		pr_err(PFX "Kernel is locked down\n");
> +		return -EPERM;
> +	}
> +
>   	if (initialized)
>   		return 0;
>   	initialized = 1;

This would prevent any IPMI interface from working if any address was given
on the kernel command line. I'm not sure what the best policy is, but that
sounds like a possible DOS to me.

Can you put this check in hardcode_find_bmc()?  Thats the only place where
the hardcoded addresses are used, and a check there won't affect anything
else.

Also, the error message sounds a little vague to me.  If I was a sysadmin
and got this, I wouldn't be sure what was going on.  Maybe something like:
The kernel is locked down, but hard-coded device addresses were given on
the driver command line.  Ignoring these, but this is a possible 
security issue.

That's fairly wordy, but it gets the point across.  You could also move the
pr_err() into kernel_is_locked_down() and pass in the prefix, since there is
basically the same pr_err() after every check.

Thanks,

-corey

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-21 23:10 ` [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed David Howells
                     ` (2 preceding siblings ...)
       [not found]   ` <26173.1479769852-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-29  0:11   ` David Howells
  2016-11-29  0:23     ` Corey Minyard
  2016-11-29 14:03     ` David Howells
  2016-11-29 10:40   ` David Howells
  4 siblings, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-29  0:11 UTC (permalink / raw)
  To: minyard
  Cc: dhowells, One Thousand Gnomes, keyrings, matthew.garrett,
	linux-security-module, linux-efi, linux-kernel

Corey Minyard <minyard@acm.org> wrote:

> This would prevent any IPMI interface from working if any address was given
> on the kernel command line. I'm not sure what the best policy is, but that
> sounds like a possible DOS to me.

Okay, reasonable point.

> Can you put this check in hardcode_find_bmc()?  Thats the only place where
> the hardcoded addresses are used, and a check there won't affect anything
> else.

I could do that.  I presume you'd want hardcode_find_bmc() to return 1 in that
case without doing anything else.  Another possibility is to give a warning
and then clear ports[], addrs[] and irqs[].

> Also, the error message sounds a little vague to me.  If I was a sysadmin
> and got this, I wouldn't be sure what was going on.  Maybe something like:
> The kernel is locked down, but hard-coded device addresses were given on
> the driver command line.  Ignoring these, but this is a possible security
> issue.
>
> That's fairly wordy, but it gets the point across.  You could also move the
> pr_err() into kernel_is_locked_down() and pass in the prefix, since there is
> basically the same pr_err() after every check.

I don't think your suggested summary quite gets it right.  A lot of drivers,
sound drivers, for example, that aren't really critical can simply be
disabled - and some have to be disabled because there's no other way to
configure them.

It would have to be more like pr_err("Hard-coded device addresses, irqs and
dma channels are not permitted when the kernel is locked down."), possibly
with the addition of either "The driver has been disabled" or "These settings
have been ignored".

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-29  0:11   ` David Howells
@ 2016-11-29  0:23     ` Corey Minyard
  2016-11-29 14:03     ` David Howells
  1 sibling, 0 replies; 76+ messages in thread
From: Corey Minyard @ 2016-11-29  0:23 UTC (permalink / raw)
  To: David Howells
  Cc: One Thousand Gnomes, keyrings, matthew.garrett,
	linux-security-module, linux-efi, linux-kernel

On 11/28/2016 06:11 PM, David Howells wrote:
> Corey Minyard <minyard@acm.org> wrote:
>
>> This would prevent any IPMI interface from working if any address was given
>> on the kernel command line. I'm not sure what the best policy is, but that
>> sounds like a possible DOS to me.
> Okay, reasonable point.
>
>> Can you put this check in hardcode_find_bmc()?  Thats the only place where
>> the hardcoded addresses are used, and a check there won't affect anything
>> else.
> I could do that.  I presume you'd want hardcode_find_bmc() to return 1 in that
> case without doing anything else.  Another possibility is to give a warning
> and then clear ports[], addrs[] and irqs[].
>

Just returning -EPERM from that routine is fine, without doing anything
else.  You can basically just move your check to the top of that
routine.

>> Also, the error message sounds a little vague to me.  If I was a sysadmin
>> and got this, I wouldn't be sure what was going on.  Maybe something like:
>> The kernel is locked down, but hard-coded device addresses were given on
>> the driver command line.  Ignoring these, but this is a possible security
>> issue.
>>
>> That's fairly wordy, but it gets the point across.  You could also move the
>> pr_err() into kernel_is_locked_down() and pass in the prefix, since there is
>> basically the same pr_err() after every check.
> I don't think your suggested summary quite gets it right.  A lot of drivers,
> sound drivers, for example, that aren't really critical can simply be
> disabled - and some have to be disabled because there's no other way to
> configure them.

Yeah.  My main issue was that the sysadmin would see this and not
have any idea what was going on.

>
> It would have to be more like pr_err("Hard-coded device addresses, irqs and
> dma channels are not permitted when the kernel is locked down."), possibly
> with the addition of either "The driver has been disabled" or "These settings
> have been ignored".

That sounds better than what I had.

-corey


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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-21 23:10 ` [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed David Howells
                     ` (3 preceding siblings ...)
  2016-11-29  0:11   ` David Howells
@ 2016-11-29 10:40   ` David Howells
  4 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-29 10:40 UTC (permalink / raw)
  To: minyard
  Cc: dhowells, One Thousand Gnomes, keyrings, matthew.garrett,
	linux-security-module, linux-efi, linux-kernel

David Howells <dhowells@redhat.com> wrote:

> It would have to be more like pr_err("Hard-coded device addresses, irqs and
> dma channels are not permitted when the kernel is locked down."), possibly
> with the addition of either "The driver has been disabled" or "These settings
> have been ignored".

That should be "Command line-specified" rather than "Hard-coded".  The latter
are actually okay.

A better way to do this would probably be to annotate the module parameter
declarations and have the module_param() invoker reject the locked-down
parameters.  I'm not sure how easy that would be to do, though.

David

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
  2016-11-29  0:11   ` David Howells
  2016-11-29  0:23     ` Corey Minyard
@ 2016-11-29 14:03     ` David Howells
       [not found]       ` <6973.1480428211-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
       [not found]       ` <20161130144105.2b6be4fe-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
  1 sibling, 2 replies; 76+ messages in thread
From: David Howells @ 2016-11-29 14:03 UTC (permalink / raw)
  To: minyard
  Cc: dhowells, One Thousand Gnomes, keyrings, matthew.garrett,
	linux-security-module, linux-efi, linux-kernel

How about the attached?  Obviously it need extending to other drivers.

I thought that if I'm changing the module_param annotations anyway then it's
probably worth bunging in an extra parameter that notes what the parameter
modifies (ioport, iomem, etc.) for future reference, even if we don't store
it.

David
---
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 7fb9c299a183..157e96391eca 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1375,39 +1375,39 @@ MODULE_PARM_DESC(type, "Defines the type of each interface, each"
 		 " interface separated by commas.  The types are 'kcs',"
 		 " 'smic', and 'bt'.  For example si_type=kcs,bt will set"
 		 " the first interface to kcs and the second to bt");
-module_param_array(addrs, ulong, &num_addrs, 0);
+module_param_hw_array(addrs, ulong, iomem, &num_addrs, 0);
 MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
 		 " addresses separated by commas.  Only use if an interface"
 		 " is in memory.  Otherwise, set it to zero or leave"
 		 " it blank.");
-module_param_array(ports, uint, &num_ports, 0);
+module_param_hw_array(ports, uint, ioport, &num_ports, 0);
 MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
 		 " addresses separated by commas.  Only use if an interface"
 		 " is a port.  Otherwise, set it to zero or leave"
 		 " it blank.");
-module_param_array(irqs, int, &num_irqs, 0);
+module_param_hw_array(irqs, int, irq, &num_irqs, 0);
 MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
 		 " addresses separated by commas.  Only use if an interface"
 		 " has an interrupt.  Otherwise, set it to zero or leave"
 		 " it blank.");
-module_param_array(regspacings, int, &num_regspacings, 0);
+module_param_hw_array(regspacings, int, other, &num_regspacings, 0);
 MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
 		 " and each successive register used by the interface.  For"
 		 " instance, if the start address is 0xca2 and the spacing"
 		 " is 2, then the second address is at 0xca4.  Defaults"
 		 " to 1.");
-module_param_array(regsizes, int, &num_regsizes, 0);
+module_param_hw_array(regsizes, int, other, &num_regsizes, 0);
 MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
 		 " This should generally be 1, 2, 4, or 8 for an 8-bit,"
 		 " 16-bit, 32-bit, or 64-bit register.  Use this if you"
 		 " the 8-bit IPMI register has to be read from a larger"
 		 " register.");
-module_param_array(regshifts, int, &num_regshifts, 0);
+module_param_hw_array(regshifts, int, other, &num_regshifts, 0);
 MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
 		 " IPMI register, in bits.  For instance, if the data"
 		 " is read from a 32-bit word and the IPMI data is in"
 		 " bit 8-15, then the shift would be 8");
-module_param_array(slave_addrs, int, &num_slave_addrs, 0);
+module_param_hw_array(slave_addrs, int, other, &num_slave_addrs, 0);
 MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
 		 " the controller.  Normally this is 0x20, but can be"
 		 " overridden by this parm.  This is an array indexed"
@@ -3725,12 +3725,6 @@ static int init_ipmi_si(void)
 	struct smi_info *e;
 	enum ipmi_addr_src type = SI_INVALID;
 
-	if ((num_addrs || num_ports || num_irqs) &&
-	    kernel_is_locked_down()) {
-		pr_err(PFX "Kernel is locked down\n");
-		return -EPERM;
-	}
-
 	if (initialized)
 		return 0;
 	initialized = 1;
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 52666d90ca94..bdb884fba79a 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -60,9 +60,11 @@ struct kernel_param_ops {
  * Flags available for kernel_param
  *
  * UNSAFE - the parameter is dangerous and setting it will taint the kernel
+ * HWPARAM - Hardware param not permitted in lockdown mode
  */
 enum {
-	KERNEL_PARAM_FL_UNSAFE = (1 << 0)
+	KERNEL_PARAM_FL_UNSAFE	= (1 << 0),
+	KERNEL_PARAM_FL_HWPARAM	= (1 << 1),
 };
 
 struct kernel_param {
@@ -451,6 +453,62 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
 			    perm, -1, 0);				\
 	__MODULE_PARM_TYPE(name, "array of " #type)
 
+enum hwparam_type {
+	hwparam_ioport,		/* Module parameter configures an I/O port */
+	hwparam_iomem,		/* Module parameter configures an I/O mem address */
+	hwparam_irq,		/* Module parameter configures an I/O port */
+	hwparam_dma,		/* Module parameter configures a DMA channel */
+	hwparam_dma_addr,	/* Module parameter configures a DMA buffer address */
+	hwparam_other,		/* Module parameter configures some other value */
+};
+
+/**
+ * module_param_hw - A parameter representing a hw parameters
+ * @name: a valid C identifier which is the parameter name.
+ * @type: the type of the parameter
+ * @hwtype: what the value represents (enum hwparam_type)
+ * @perm: visibility in sysfs.
+ *
+ * Usually it's a good idea to have variable names and user-exposed names the
+ * same, but that's harder if the variable must be non-static or is inside a
+ * structure.  This allows exposure under a different name.
+ */
+#define module_param_hw(name, type, hwtype, perm)			\
+	param_check_##type(name, &(name));				\
+	__module_param_call(MODULE_PARAM_PREFIX, name,			\
+			    &param_ops_##type, &name,			\
+			    perm, -1,					\
+			    KERNEL_PARAM_FL_HWPARAM | (hwparam_##hwtype & 0));	\
+	__MODULE_PARM_TYPE(name, #type)
+
+/**
+ * module_param_hw_array - A parameter representing an array of hw parameters
+ * @name: the name of the array variable
+ * @type: the type, as per module_param()
+ * @hwtype: what the value represents (enum hwparam_type)
+ * @nump: optional pointer filled in with the number written
+ * @perm: visibility in sysfs
+ *
+ * Input and output are as comma-separated values.  Commas inside values
+ * don't work properly (eg. an array of charp).
+ *
+ * ARRAY_SIZE(@name) is used to determine the number of elements in the
+ * array, so the definition must be visible.
+ */
+#define module_param_hw_array(name, type, hwtype, nump, perm)		\
+	param_check_##type(name, &(name)[0]);				\
+	static const struct kparam_array __param_arr_##name		\
+	= { .max = ARRAY_SIZE(name), .num = nump,			\
+	    .ops = &param_ops_##type,					\
+	    .elemsize = sizeof(name[0]), .elem = name };		\
+	__module_param_call(MODULE_PARAM_PREFIX, name,			\
+			    &param_array_ops,				\
+			    .arr = &__param_arr_##name,			\
+			    perm, -1,					\
+			    KERNEL_PARAM_FL_HWPARAM | (hwparam_##hwtype & 0));	\
+	__MODULE_PARM_TYPE(name, "array of " #type)
+
+
 extern const struct kernel_param_ops param_array_ops;
 
 extern const struct kernel_param_ops param_ops_string;
diff --git a/kernel/params.c b/kernel/params.c
index a6d6149c0fe6..2b68e6dad677 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -108,13 +108,20 @@ bool parameq(const char *a, const char *b)
 	return parameqn(a, b, strlen(a)+1);
 }
 
-static void param_check_unsafe(const struct kernel_param *kp)
+static bool param_check_unsafe(const struct kernel_param *kp,
+			       const char *doing)
 {
 	if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
 		pr_warn("Setting dangerous option %s - tainting kernel\n",
 			kp->name);
 		add_taint(TAINT_USER, LOCKDEP_STILL_OK);
 	}
+
+	if (kp->flags & KERNEL_PARAM_FL_HWPARAM && kernel_is_locked_down()) {
+		pr_err("Command line-specified device addresses, irqs and dma channels are not permitted when the kernel is locked down (%s.%s)\n", doing, kp->name);
+		return false;
+	}
+	return true;
 }
 
 static int parse_one(char *param,
@@ -144,8 +151,10 @@ static int parse_one(char *param,
 			pr_debug("handling %s with %p\n", param,
 				params[i].ops->set);
 			kernel_param_lock(params[i].mod);
-			param_check_unsafe(&params[i]);
-			err = params[i].ops->set(val, &params[i]);
+			if (param_check_unsafe(&params[i], doing))
+				err = params[i].ops->set(val, &params[i]);
+			else
+				err = -EPERM;
 			kernel_param_unlock(params[i].mod);
 			return err;
 		}
@@ -620,8 +629,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
 		return -EPERM;
 
 	kernel_param_lock(mk->mod);
-	param_check_unsafe(attribute->param);
-	err = attribute->param->ops->set(buf, attribute->param);
+	if (param_check_unsafe(attribute->param, mk->mod->name))
+		err = attribute->param->ops->set(buf, attribute->param);
+	else
+		err = -EPERM;
 	kernel_param_unlock(mk->mod);
 	if (!err)
 		return len;

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
       [not found]       ` <6973.1480428211-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
@ 2016-11-29 14:35         ` Corey Minyard
  2016-11-30 14:41         ` One Thousand Gnomes
  1 sibling, 0 replies; 76+ messages in thread
From: Corey Minyard @ 2016-11-29 14:35 UTC (permalink / raw)
  To: David Howells
  Cc: One Thousand Gnomes, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 11/29/2016 08:03 AM, David Howells wrote:
> How about the attached?  Obviously it need extending to other drivers.

This is great, I like it a lot better.

Reviewed-by: Corey Minyard <cminyard-Igf4POYTYCDQT0dZR+AlfA@public.gmane.org>

-corey

> I thought that if I'm changing the module_param annotations anyway then it's
> probably worth bunging in an extra parameter that notes what the parameter
> modifies (ioport, iomem, etc.) for future reference, even if we don't store
> it.
>
> David
> ---
> diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
> index 7fb9c299a183..157e96391eca 100644
> --- a/drivers/char/ipmi/ipmi_si_intf.c
> +++ b/drivers/char/ipmi/ipmi_si_intf.c
> @@ -1375,39 +1375,39 @@ MODULE_PARM_DESC(type, "Defines the type of each interface, each"
>   		 " interface separated by commas.  The types are 'kcs',"
>   		 " 'smic', and 'bt'.  For example si_type=kcs,bt will set"
>   		 " the first interface to kcs and the second to bt");
> -module_param_array(addrs, ulong, &num_addrs, 0);
> +module_param_hw_array(addrs, ulong, iomem, &num_addrs, 0);
>   MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
>   		 " addresses separated by commas.  Only use if an interface"
>   		 " is in memory.  Otherwise, set it to zero or leave"
>   		 " it blank.");
> -module_param_array(ports, uint, &num_ports, 0);
> +module_param_hw_array(ports, uint, ioport, &num_ports, 0);
>   MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
>   		 " addresses separated by commas.  Only use if an interface"
>   		 " is a port.  Otherwise, set it to zero or leave"
>   		 " it blank.");
> -module_param_array(irqs, int, &num_irqs, 0);
> +module_param_hw_array(irqs, int, irq, &num_irqs, 0);
>   MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
>   		 " addresses separated by commas.  Only use if an interface"
>   		 " has an interrupt.  Otherwise, set it to zero or leave"
>   		 " it blank.");
> -module_param_array(regspacings, int, &num_regspacings, 0);
> +module_param_hw_array(regspacings, int, other, &num_regspacings, 0);
>   MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
>   		 " and each successive register used by the interface.  For"
>   		 " instance, if the start address is 0xca2 and the spacing"
>   		 " is 2, then the second address is at 0xca4.  Defaults"
>   		 " to 1.");
> -module_param_array(regsizes, int, &num_regsizes, 0);
> +module_param_hw_array(regsizes, int, other, &num_regsizes, 0);
>   MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
>   		 " This should generally be 1, 2, 4, or 8 for an 8-bit,"
>   		 " 16-bit, 32-bit, or 64-bit register.  Use this if you"
>   		 " the 8-bit IPMI register has to be read from a larger"
>   		 " register.");
> -module_param_array(regshifts, int, &num_regshifts, 0);
> +module_param_hw_array(regshifts, int, other, &num_regshifts, 0);
>   MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
>   		 " IPMI register, in bits.  For instance, if the data"
>   		 " is read from a 32-bit word and the IPMI data is in"
>   		 " bit 8-15, then the shift would be 8");
> -module_param_array(slave_addrs, int, &num_slave_addrs, 0);
> +module_param_hw_array(slave_addrs, int, other, &num_slave_addrs, 0);
>   MODULE_PARM_DESC(slave_addrs, "Set the default IPMB slave address for"
>   		 " the controller.  Normally this is 0x20, but can be"
>   		 " overridden by this parm.  This is an array indexed"
> @@ -3725,12 +3725,6 @@ static int init_ipmi_si(void)
>   	struct smi_info *e;
>   	enum ipmi_addr_src type = SI_INVALID;
>   
> -	if ((num_addrs || num_ports || num_irqs) &&
> -	    kernel_is_locked_down()) {
> -		pr_err(PFX "Kernel is locked down\n");
> -		return -EPERM;
> -	}
> -
>   	if (initialized)
>   		return 0;
>   	initialized = 1;
> diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
> index 52666d90ca94..bdb884fba79a 100644
> --- a/include/linux/moduleparam.h
> +++ b/include/linux/moduleparam.h
> @@ -60,9 +60,11 @@ struct kernel_param_ops {
>    * Flags available for kernel_param
>    *
>    * UNSAFE - the parameter is dangerous and setting it will taint the kernel
> + * HWPARAM - Hardware param not permitted in lockdown mode
>    */
>   enum {
> -	KERNEL_PARAM_FL_UNSAFE = (1 << 0)
> +	KERNEL_PARAM_FL_UNSAFE	= (1 << 0),
> +	KERNEL_PARAM_FL_HWPARAM	= (1 << 1),
>   };
>   
>   struct kernel_param {
> @@ -451,6 +453,62 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
>   			    perm, -1, 0);				\
>   	__MODULE_PARM_TYPE(name, "array of " #type)
>   
> +enum hwparam_type {
> +	hwparam_ioport,		/* Module parameter configures an I/O port */
> +	hwparam_iomem,		/* Module parameter configures an I/O mem address */
> +	hwparam_irq,		/* Module parameter configures an I/O port */
> +	hwparam_dma,		/* Module parameter configures a DMA channel */
> +	hwparam_dma_addr,	/* Module parameter configures a DMA buffer address */
> +	hwparam_other,		/* Module parameter configures some other value */
> +};
> +
> +/**
> + * module_param_hw - A parameter representing a hw parameters
> + * @name: a valid C identifier which is the parameter name.
> + * @type: the type of the parameter
> + * @hwtype: what the value represents (enum hwparam_type)
> + * @perm: visibility in sysfs.
> + *
> + * Usually it's a good idea to have variable names and user-exposed names the
> + * same, but that's harder if the variable must be non-static or is inside a
> + * structure.  This allows exposure under a different name.
> + */
> +#define module_param_hw(name, type, hwtype, perm)			\
> +	param_check_##type(name, &(name));				\
> +	__module_param_call(MODULE_PARAM_PREFIX, name,			\
> +			    &param_ops_##type, &name,			\
> +			    perm, -1,					\
> +			    KERNEL_PARAM_FL_HWPARAM | (hwparam_##hwtype & 0));	\
> +	__MODULE_PARM_TYPE(name, #type)
> +
> +/**
> + * module_param_hw_array - A parameter representing an array of hw parameters
> + * @name: the name of the array variable
> + * @type: the type, as per module_param()
> + * @hwtype: what the value represents (enum hwparam_type)
> + * @nump: optional pointer filled in with the number written
> + * @perm: visibility in sysfs
> + *
> + * Input and output are as comma-separated values.  Commas inside values
> + * don't work properly (eg. an array of charp).
> + *
> + * ARRAY_SIZE(@name) is used to determine the number of elements in the
> + * array, so the definition must be visible.
> + */
> +#define module_param_hw_array(name, type, hwtype, nump, perm)		\
> +	param_check_##type(name, &(name)[0]);				\
> +	static const struct kparam_array __param_arr_##name		\
> +	= { .max = ARRAY_SIZE(name), .num = nump,			\
> +	    .ops = &param_ops_##type,					\
> +	    .elemsize = sizeof(name[0]), .elem = name };		\
> +	__module_param_call(MODULE_PARAM_PREFIX, name,			\
> +			    &param_array_ops,				\
> +			    .arr = &__param_arr_##name,			\
> +			    perm, -1,					\
> +			    KERNEL_PARAM_FL_HWPARAM | (hwparam_##hwtype & 0));	\
> +	__MODULE_PARM_TYPE(name, "array of " #type)
> +
> +
>   extern const struct kernel_param_ops param_array_ops;
>   
>   extern const struct kernel_param_ops param_ops_string;
> diff --git a/kernel/params.c b/kernel/params.c
> index a6d6149c0fe6..2b68e6dad677 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -108,13 +108,20 @@ bool parameq(const char *a, const char *b)
>   	return parameqn(a, b, strlen(a)+1);
>   }
>   
> -static void param_check_unsafe(const struct kernel_param *kp)
> +static bool param_check_unsafe(const struct kernel_param *kp,
> +			       const char *doing)
>   {
>   	if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
>   		pr_warn("Setting dangerous option %s - tainting kernel\n",
>   			kp->name);
>   		add_taint(TAINT_USER, LOCKDEP_STILL_OK);
>   	}
> +
> +	if (kp->flags & KERNEL_PARAM_FL_HWPARAM && kernel_is_locked_down()) {
> +		pr_err("Command line-specified device addresses, irqs and dma channels are not permitted when the kernel is locked down (%s.%s)\n", doing, kp->name);
> +		return false;
> +	}
> +	return true;
>   }
>   
>   static int parse_one(char *param,
> @@ -144,8 +151,10 @@ static int parse_one(char *param,
>   			pr_debug("handling %s with %p\n", param,
>   				params[i].ops->set);
>   			kernel_param_lock(params[i].mod);
> -			param_check_unsafe(&params[i]);
> -			err = params[i].ops->set(val, &params[i]);
> +			if (param_check_unsafe(&params[i], doing))
> +				err = params[i].ops->set(val, &params[i]);
> +			else
> +				err = -EPERM;
>   			kernel_param_unlock(params[i].mod);
>   			return err;
>   		}
> @@ -620,8 +629,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
>   		return -EPERM;
>   
>   	kernel_param_lock(mk->mod);
> -	param_check_unsafe(attribute->param);
> -	err = attribute->param->ops->set(buf, attribute->param);
> +	if (param_check_unsafe(attribute->param, mk->mod->name))
> +		err = attribute->param->ops->set(buf, attribute->param);
> +	else
> +		err = -EPERM;
>   	kernel_param_unlock(mk->mod);
>   	if (!err)
>   		return len;

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

* Re: [PATCH 00/16] Kernel lockdown
  2016-11-21 19:53     ` Ard Biesheuvel
@ 2016-11-30 14:27       ` One Thousand Gnomes
  0 siblings, 0 replies; 76+ messages in thread
From: One Thousand Gnomes @ 2016-11-30 14:27 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: David Howells, keyrings, Matthew Garrett, linux-security-module,
	linux-efi, linux-kernel

> This applies equally to the kernel command line, and given that we
> cannot authenticate it, we should whitelist params that we know to be
> safe, and filter out all others. A similar concern exists for the
> device tree on ARM/arm64, and we already disable the DTB loader in the
> UEFI stub if secure boot is enabled.

Or you sign the boot command line.

> > Without that at least fixed I don't see the point in merging this. Either
> > we don't do it (which given the level of security the current Linux
> > kernel provides, and also all the golden key messups from elsewhere might
> > be the honest approach), or at least try and do the job right.
> >
> > Less security is better than fake security. If you've got less security
> > your take appropriate precautions. If you rely on fake security you don't.
> >  
> 
> In general, I think kernel hardening is an important topic

It is - so pushing something with known trivial holes isn't a useful way
to do this. The module parameter hole needs to be addressed before this
is fit for upstream.

Alan

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
       [not found]       ` <6973.1480428211-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-29 14:35         ` Corey Minyard
@ 2016-11-30 14:41         ` One Thousand Gnomes
  1 sibling, 0 replies; 76+ messages in thread
From: One Thousand Gnomes @ 2016-11-30 14:41 UTC (permalink / raw)
  To: David Howells
  Cc: minyard-HInyCGIudOg, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Tue, 29 Nov 2016 14:03:31 +0000
David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:

> How about the attached?  Obviously it need extending to other drivers.
> 
> I thought that if I'm changing the module_param annotations anyway then it's
> probably worth bunging in an extra parameter that notes what the parameter
> modifies (ioport, iomem, etc.) for future reference, even if we don't store
> it.


With a security hat on the security best practice and long standing
accepted rule is that you whitelist rather than blacklist, so there ought
to be a 

module_param_safe_array()
etc

to mark parameters that are safe, not the reverse.


That debate aside I think the patch is exactly what is needed for this,
and is probably useful for more general hardening as well.

Alan

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

* Re: [PATCH] Lock down drivers that can have io ports, io mem, irqs and dma changed
       [not found]       ` <20161130144105.2b6be4fe-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
@ 2016-11-30 16:25         ` David Howells
  0 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-11-30 16:25 UTC (permalink / raw)
  To: One Thousand Gnomes
  Cc: dhowells-H+wXaHxf7aLQT0dZR+AlfA, minyard-HInyCGIudOg,
	jforbes-H+wXaHxf7aLQT0dZR+AlfA, keyrings-u79uwXL29TY76Z2rM5mHXA,
	matthew.garrett-05XSO3Yj/JvQT0dZR+AlfA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

One Thousand Gnomes <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org> wrote:

> > I thought that if I'm changing the module_param annotations anyway then it's
> > probably worth bunging in an extra parameter that notes what the parameter
> > modifies (ioport, iomem, etc.) for future reference, even if we don't store
> > it.
> 
> With a security hat on the security best practice and long standing
> accepted rule is that you whitelist rather than blacklist, so there ought
> to be a 
> 
> module_param_safe_array()
> etc
> 
> to mark parameters that are safe, not the reverse.

Whilst that may be true, it's a lot more work.  Mind you, that said, you can
take the annotations I've made and script the inverse.

> That debate aside I think the patch is exactly what is needed for this,
> and is probably useful for more general hardening as well.

Okay, I've done a preliminary patchset, labelling all the parameters that
appear to be associated with hardware details and pushed them here:

	http://git.kernel.org/cgit/linux/kernel/git/dhowells/linux-fs.git/log/?h=efi-lock-down

The patch that modifies the module parameter header is labelled:

	Lock down module params that specify hardware parameters (eg. ioport)

and all the driver dir lockdown patches follow that.

I still need to do a bit of commenting in that patch and add various
maintainer cc's in the other patches.

David

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

* Re: [PATCH 01/16] Add the ability to lock down access to the running kernel image
  2016-11-16 21:47 ` [PATCH 01/16] Add the ability to lock down access to the running kernel image David Howells
       [not found]   ` <147933284407.19316.17886320817060158597.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
  2016-11-16 22:40   ` David Howells
@ 2016-12-25 21:20   ` Pavel Machek
  2016-12-25 21:44   ` David Howells
  3 siblings, 0 replies; 76+ messages in thread
From: Pavel Machek @ 2016-12-25 21:20 UTC (permalink / raw)
  To: David Howells
  Cc: keyrings, matthew.garrett, linux-security-module, linux-efi,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1133 bytes --]

Hi!

> allow the running kernel image to be changed including the loading of
> modules that aren't validly signed with a key we recognise, fiddling with
> MSR registers and disallowing hibernation,

"." at EOL.

> @@ -158,6 +158,21 @@ config HARDENED_USERCOPY_PAGESPAN
>  	  been removed. This config is intended to be used only while
>  	  trying to find such users.
>  
> +config LOCK_DOWN_KERNEL
> +	bool "Allow the kernel to be 'locked down'"

Locked down, or 'locked down' ? :-).

> +	help
> +	  Allow the kernel to be locked down under certain circumstances, for
> +	  instance if UEFI secure boot is enabled.  Locking down the kernel
> +	  turns off various features that might otherwise allow access to the
> +	  kernel image (eg. setting MSR registers).

I'd add something that clarifies it is "running" kernel image.

> +config ALLOW_LOCKDOWN_LIFT
> +	bool

Don't you need to add 'bool "something"' so that user can actually
select this?
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

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

* Re: [PATCH 01/16] Add the ability to lock down access to the running kernel image
  2016-11-16 21:47 ` [PATCH 01/16] Add the ability to lock down access to the running kernel image David Howells
                     ` (2 preceding siblings ...)
  2016-12-25 21:20   ` Pavel Machek
@ 2016-12-25 21:44   ` David Howells
  3 siblings, 0 replies; 76+ messages in thread
From: David Howells @ 2016-12-25 21:44 UTC (permalink / raw)
  To: Pavel Machek
  Cc: dhowells, keyrings, matthew.garrett, linux-security-module,
	linux-efi, linux-kernel

Pavel Machek <pavel@ucw.cz> wrote:

> > +config ALLOW_LOCKDOWN_LIFT
> > +	bool
> 
> Don't you need to add 'bool "something"' so that user can actually
> select this?

No - see patch 6.  This option merely makes the function available.  Actually,
I haven't done it quite right: the function in the .c file should be
conditionalised too.

David

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

end of thread, other threads:[~2016-12-25 21:44 UTC | newest]

Thread overview: 76+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
     [not found]   ` <147933284407.19316.17886320817060158597.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
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 2/6] arm/efi: Allow invocation of arbitrary runtime services 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
     [not found]         ` <20161122104401.GC1552-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
2016-11-22 10:49           ` Ard Biesheuvel
2016-11-22 14:52           ` David Howells
     [not found]             ` <25371.1479826321-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-22 20:36               ` Lukas Wunner
2016-11-22 14:47       ` David Howells
2016-11-22 20:30         ` Lukas Wunner
2016-11-23  0:02         ` David Howells
     [not found]       ` <7199.1479826047-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
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:46   ` [PATCH 02/16] efi: Get the secure boot status David Howells
2016-11-21 19:58     ` Lukas Wunner
     [not found]   ` <20161117123731.GA11573-JFq808J9C/izQB+pC5nmwQ@public.gmane.org>
2016-11-21 11:42     ` David Howells
     [not found]       ` <29779.1479728545-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-21 11:52         ` Ard Biesheuvel
     [not found]       ` <CAKv+Gu-frVDhzORDRZ6XT+FxewsTgrxhXmM=DqaS6Ns4mJhQ9g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-21 12:41         ` David Howells
2016-11-21 13:14           ` Ard Biesheuvel
     [not found]             ` <CAKv+Gu8Lhm=u97hY1y+Y+Ladk=y7pSVNrow8ML1hQUJ9+74B-w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-21 15:17               ` Lukas Wunner
2016-11-21 15:25                 ` Ard Biesheuvel
2016-11-22  0:31     ` [PATCH 1/6] x86/efi: Allow invocation of arbitrary runtime services David Howells
     [not found]       ` <147977469914.6360.17194649697208113702.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-22 10:20         ` Lukas Wunner
2016-11-22 14:17       ` David Howells
2016-11-22 14:58         ` Joe Perches
     [not found]         ` <1479826691.1942.11.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>
2016-11-22 15:52           ` David Howells
     [not found]             ` <24973.1479829961-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-22 16:25               ` Joe Perches
2016-11-22 16:40             ` David Howells
2016-11-22 16:51               ` Joe Perches
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
     [not found]       ` <CA+5PVA6F5qEnuL2UaXS9_fJ217J93cEZDDsz9Y2BPwHXcMdX-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-18 12:10         ` Ard Biesheuvel
     [not found]   ` <CAKv+Gu_8r3oM-jvvuSiXTzxp0YMEVgc5KkScJ2UhGTaXm28L6w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-11-18 17:28     ` David Howells
2016-11-16 21:48 ` [PATCH 06/16] Add a sysrq option to exit secure boot mode David Howells
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
     [not found] ` <147933283664.19316.12454053022687659937.stgit-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-16 21:48   ` [PATCH 11/16] x86: Lock down IO port " David Howells
2016-11-16 21:49   ` [PATCH 16/16] x86: Restrict MSR " 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 21:48 ` [PATCH 12/16] ACPI: Limit access to custom_method when the kernel is locked down 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 22:28 ` [PATCH 00/16] Kernel lockdown 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
     [not found]     ` <20161123192143.GA482-SGhQLRGLuNwb6pqDj42GsMgv3T4z79SOrE5yTffgRl4@public.gmane.org>
2016-11-24 17:34       ` David Howells
2016-11-24 20:19         ` Dominik Brodowski
2016-11-25 14:49         ` David Howells
     [not found]   ` <26173.1479769852-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
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
     [not found]       ` <6973.1480428211-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-11-29 14:35         ` Corey Minyard
2016-11-30 14:41         ` One Thousand Gnomes
     [not found]       ` <20161130144105.2b6be4fe-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
2016-11-30 16:25         ` David Howells
2016-11-29 10:40   ` David Howells

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