diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py
index 0aa687855..6584b7cce 100755
--- a/debian/bin/gencontrol.py
+++ b/debian/bin/gencontrol.py
@@ -23,6 +23,7 @@ class Gencontrol(Base):
},
'build': {
'debug-info': config.SchemaItemBoolean(),
+ 'signed-modules': config.SchemaItemBoolean(),
'vdso': config.SchemaItemBoolean(),
},
'description': {
diff --git a/debian/certs/benh@debian.org.cert.pem b/debian/certs/benh@debian.org.cert.pem
new file mode 100644
index 000000000..8d49875e5
--- /dev/null
+++ b/debian/certs/benh@debian.org.cert.pem
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDYDCCAkgCCQCKAY3KgJMmMDANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJH
+QjESMBAGA1UEBwwJQ2FtYnJpZGdlMRcwFQYDVQQKDA5EZWJpYW4gUHJvamVjdDEW
+MBQGA1UEAwwNQmVuIEh1dGNoaW5nczEeMBwGCSqGSIb3DQEJARYPYmVuaEBkZWJp
+YW4ub3JnMB4XDTE2MDQwMzIyNTg1NVoXDTE2MDUwMzIyNTg1NVowcjELMAkGA1UE
+BhMCR0IxEjAQBgNVBAcMCUNhbWJyaWRnZTEXMBUGA1UECgwORGViaWFuIFByb2pl
+Y3QxFjAUBgNVBAMMDUJlbiBIdXRjaGluZ3MxHjAcBgkqhkiG9w0BCQEWD2JlbmhA
+ZGViaWFuLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMPYUchZ
+x/VmCn4klnuqyym6gehD/sUnjqAbDdVtAVMYBHTxxpujW2GDtCsyiqyeDlSlbd6X
+piXAko7u2UaBfY5SpKcw1KDDrCgzQ3y9O0QCe0DzI/7YKvE3A7FPluJ1ZhIhHIIZ
+ce6oln0WfW/H5SY6BQWE3kzxXFUXXFPvTdLQtjOBxVWeOeMTZ5CAJqG/6uHIlJms
+RTJiiiHjrI3yAfLS1wcGutmu9q9YQF1ND+lbdIT4OeyIMVGe03dVrDxWjNUL+G5h
+nBRwFAwkb5qxpDNayvA8eIlNwWJE/uu+4crlL+PdM9i2TduoG5gRE39KPTrxrUyN
+QiDe+09lJF12wQECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAieMLuk4Ky2FmMnzF
+ryaJbbRXN163bXHPrDFd0NkvWQFa+3253QXxlLwEoS4v4OFbYb0tDxcn8qkpNLCb
+DLtNUcl99slPbmBUi/RFTy/aAWc6LB4XxjbFcIlY27/c/W5bbr6/XmlVtElRW3gZ
+y3JWFjgym+6lXywbr6RVKYioM3N+LlGf794Kf/pY9y7i8PqDM8WbhurGXwoaPxjv
+/XsVTpuMCkorUya2n7Ap9Hatlref/IccdxnIOxItH3Jvze0vfygL82Mee77KN5U/
+jsvtswp6P3K08sLjtFGiAhkjim67H+nJrrhhczXjtUnLZUQuHpkzOghyKFDMpn3R
+8lchpg==
+-----END CERTIFICATE-----
diff --git a/debian/changelog b/debian/changelog
index f69110d32..8f5b3dc93 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,16 @@ linux (4.5-1~exp2) UNRELEASED; urgency=medium
write support
* Merge linux-tools source package into linux
(Closes: #550379, #573483, #816500)
+ * Add Matthew Garrett's securelevel patchset in preparation for Secure Boot
+ support (see Documentation/security/securelevel.txt)
+ * modules: Enable MODULE_SIG and MODULE_SIG_SHA256, but not MODULE_SIG_ALL
+ as signatures will be packaged separately
+ - debian/control: Add build-dependencies on libssl-dev, openssl
+ - debian/copyright: Note that extract-cert and sign-file are under LGPL 2.1
+ - linux-kbuild: Add extract-cert and sign-file programs
+ - scripts: Fix X.509 PEM support in sign-file
+ * certs: Set SYSTEM_TRUSTED_KEYS to my own personal certificate to support
+ initial testing of signed modules
[ Aurelien Jarno ]
* [mipsel/mips/config.loongson-2f] Disable VIDEO_CX23885, VIDEO_IVTV,
diff --git a/debian/config/alpha/defines b/debian/config/alpha/defines
index 971b7f0dd..386809d8d 100644
--- a/debian/config/alpha/defines
+++ b/debian/config/alpha/defines
@@ -4,6 +4,8 @@ kernel-arch: alpha
[build]
image-file: arch/alpha/boot/vmlinux.gz
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
suggests: aboot, fdutils
diff --git a/debian/config/armel/config.marvell b/debian/config/armel/config.marvell
index ed9308d95..d80a2cce4 100644
--- a/debian/config/armel/config.marvell
+++ b/debian/config/armel/config.marvell
@@ -672,6 +672,7 @@ CONFIG_ORION_WATCHDOG=m
# CONFIG_CHECKPOINT_RESTORE is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_PROFILING is not set
+# CONFIG_MODULE_SIG is not set
##
## file: kernel/power/Kconfig
diff --git a/debian/config/armel/defines b/debian/config/armel/defines
index 70798d5fa..0a6341a7e 100644
--- a/debian/config/armel/defines
+++ b/debian/config/armel/defines
@@ -17,6 +17,10 @@ install-stem: vmlinuz
[relations]
headers%gcc-5: linux-compiler-gcc-5-arm
+[marvell_build]
+# Signature verification disabled to save on code size
+signed-modules: false
+
[marvell_description]
hardware: Marvell Kirkwood/Orion
hardware-long: Marvell Kirkwood based systems (SheevaPlug, QNAP TS-119/TS-219, etc)
diff --git a/debian/config/config b/debian/config/config
index 4b1272142..1081c39fc 100644
--- a/debian/config/config
+++ b/debian/config/config
@@ -58,7 +58,10 @@ CONFIG_EFI_PARTITION=y
##
## file: certs/Kconfig
##
-# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
+#. Signatures are added in linux-signed
+CONFIG_MODULE_SIG_KEY=""
+#. Actually a list of X.509 certificates, not keys
+CONFIG_SYSTEM_TRUSTED_KEYS="debian/certs/benh@debian.org.cert.pem"
##
## file: crypto/Kconfig
@@ -5585,8 +5588,14 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
-#. Not yet
-# CONFIG_MODULE_SIG is not set
+CONFIG_MODULE_SIG=y
+#. Signature validation is a run-time option
+# CONFIG_MODULE_SIG_FORCE is not set
+#. Signatures are added in linux-signed
+# CONFIG_MODULE_SIG_ALL is not set
+## choice: Which hash algorithm should modules be signed with?
+CONFIG_MODULE_SIG_SHA256=y
+## end choice
# CONFIG_MODULE_COMPRESS is not set
##
@@ -6655,6 +6664,7 @@ CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
# CONFIG_SECURITY_PATH is not set
+CONFIG_SECURITY_SECURELEVEL=y
# CONFIG_INTEL_TXT is not set
CONFIG_LSM_MMAP_MIN_ADDR=32768
## choice: Default security module
diff --git a/debian/config/defines b/debian/config/defines
index a2fe96cf4..412966a31 100644
--- a/debian/config/defines
+++ b/debian/config/defines
@@ -31,6 +31,10 @@ featuresets:
none
rt
+[build]
+# Enable module signing by default (implemented in the linux-signed package)
+signed-modules: true
+
[featureset-rt_base]
enabled: false
diff --git a/debian/config/hppa/defines b/debian/config/hppa/defines
index 368576bbe..67351e67b 100644
--- a/debian/config/hppa/defines
+++ b/debian/config/hppa/defines
@@ -4,6 +4,8 @@ kernel-arch: parisc
[build]
image-file: vmlinux
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
suggests: palo
diff --git a/debian/config/kernelarch-x86/config b/debian/config/kernelarch-x86/config
index e8b54bee4..50bed622f 100644
--- a/debian/config/kernelarch-x86/config
+++ b/debian/config/kernelarch-x86/config
@@ -54,6 +54,7 @@ CONFIG_X86_SMAP=y
CONFIG_X86_INTEL_MPX=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
+CONFIG_EFI_SECURE_BOOT_SECURELEVEL=y
CONFIG_SECCOMP=y
CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
diff --git a/debian/config/m68k/defines b/debian/config/m68k/defines
index d5cddc958..dcaef9788 100644
--- a/debian/config/m68k/defines
+++ b/debian/config/m68k/defines
@@ -6,6 +6,8 @@ kernel-arch: m68k
[build]
image-file: vmlinux.gz
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
suggests: vmelilo, fdutils
diff --git a/debian/config/mips/defines b/debian/config/mips/defines
index 74f639ef3..55e0fb7bb 100644
--- a/debian/config/mips/defines
+++ b/debian/config/mips/defines
@@ -7,6 +7,8 @@ kernel-arch: mips
[build]
image-file: vmlinux
+# linux-signed should not wait for slow builds
+signed-modules: false
[image]
install-stem: vmlinux
diff --git a/debian/config/mips64/defines b/debian/config/mips64/defines
index 450568eab..5e3d537a8 100644
--- a/debian/config/mips64/defines
+++ b/debian/config/mips64/defines
@@ -6,6 +6,8 @@ kernel-arch: mips
[build]
image-file: vmlinux
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
install-stem: vmlinux
diff --git a/debian/config/mips64el/defines b/debian/config/mips64el/defines
index 5b198df8b..ca23bfcb5 100644
--- a/debian/config/mips64el/defines
+++ b/debian/config/mips64el/defines
@@ -7,6 +7,8 @@ kernel-arch: mips
[build]
image-file: vmlinux
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
install-stem: vmlinux
diff --git a/debian/config/mipsel/defines b/debian/config/mipsel/defines
index a78c3a8ce..536455a4a 100644
--- a/debian/config/mipsel/defines
+++ b/debian/config/mipsel/defines
@@ -9,6 +9,8 @@ kernel-arch: mips
[build]
image-file: vmlinux
+# linux-signed should not wait for slow builds
+signed-modules: false
[image]
install-stem: vmlinux
diff --git a/debian/config/powerpcspe/defines b/debian/config/powerpcspe/defines
index adb4bea07..e978279a5 100644
--- a/debian/config/powerpcspe/defines
+++ b/debian/config/powerpcspe/defines
@@ -5,6 +5,8 @@ kernel-arch: powerpc
[build]
image-file: vmlinux
+# linux-signed only works for architectures in the main archive
+signed-modules: false
vdso: true
[image]
diff --git a/debian/config/ppc64/defines b/debian/config/ppc64/defines
index 7efcb1a95..86b6b2057 100644
--- a/debian/config/ppc64/defines
+++ b/debian/config/ppc64/defines
@@ -5,6 +5,8 @@ kernel-arch: powerpc
[build]
image-file: vmlinux
+# linux-signed only works for architectures in the main archive
+signed-modules: false
vdso: true
[image]
diff --git a/debian/config/sh4/defines b/debian/config/sh4/defines
index e8e5a9e14..a50ed413f 100644
--- a/debian/config/sh4/defines
+++ b/debian/config/sh4/defines
@@ -6,6 +6,8 @@ kernel-arch: sh
[build]
image-file: arch/sh/boot/zImage
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
suggests: fdutils
diff --git a/debian/config/sparc64/defines b/debian/config/sparc64/defines
index 607a267e3..cd4d9df6a 100644
--- a/debian/config/sparc64/defines
+++ b/debian/config/sparc64/defines
@@ -6,6 +6,8 @@ kernel-arch: sparc
[build]
image-file: arch/sparc/boot/zImage
+# linux-signed only works for architectures in the main archive
+signed-modules: false
[image]
configs:
diff --git a/debian/copyright b/debian/copyright
index f1b57b2a3..c3ad49090 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -20,21 +20,6 @@ License: GPL-2
Files: debian/rules.d/tools/hv/check-hyperv.c
Copyright: 2011 Lennart Poettering
License: LGPL-2.1
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
- .
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- .
- You should have received a copy of the GNU Lesser General Public License
- along with this program; If not, see .
- .
- On Debian systems, the complete text of the GNU Lesser General Public
- License version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
Files: drivers/crypto/vmx/*.pl
Copyright: 2006,2014 Andy Polyakov
@@ -139,6 +124,11 @@ License: Xen-interface
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+Files: scripts/extract-cert.c scripts/sign-file.c
+Copyright: 2014-2015 Red Hat, Inc.
+ 2015 Intel Corporation
+License: LGPL-2.1
+
License: GPL-2
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
@@ -155,3 +145,20 @@ License: GPL-2
.
On Debian systems, the complete text of the GNU General Public License version
2 can be found in `/usr/share/common-licenses/GPL-2'.
+
+License: LGPL-2.1
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; If not, see .
+ .
+ On Debian systems, the complete text of the GNU Lesser General Public
+ License version 2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'.
diff --git a/debian/lib/python/debian_linux/gencontrol.py b/debian/lib/python/debian_linux/gencontrol.py
index fdc7e9918..49727370e 100644
--- a/debian/lib/python/debian_linux/gencontrol.py
+++ b/debian/lib/python/debian_linux/gencontrol.py
@@ -80,6 +80,7 @@ class Gencontrol(object):
def __init__(self, config, templates, version=Version):
self.config, self.templates = config, templates
self.changelog = Changelog(version=version)
+ self.vars = {}
def __call__(self):
packages = PackagesList()
@@ -94,7 +95,7 @@ class Gencontrol(object):
def do_source(self, packages):
source = self.templates["control.source"][0]
source['Source'] = self.changelog[0].source
- packages['source'] = self.process_package(source)
+ packages['source'] = self.process_package(source, self.vars)
def do_main(self, packages, makefile):
config_entry = self.config['base', ]
diff --git a/debian/patches/bugfix/all/scripts-fix-x.509-pem-support-in-sign-file.patch b/debian/patches/bugfix/all/scripts-fix-x.509-pem-support-in-sign-file.patch
new file mode 100644
index 000000000..36990d8f8
--- /dev/null
+++ b/debian/patches/bugfix/all/scripts-fix-x.509-pem-support-in-sign-file.patch
@@ -0,0 +1,37 @@
+From: Ben Hutchings
+Date: Mon, 04 Apr 2016 12:53:35 +0100
+Subject: scripts: Fix X.509 PEM support in sign-file
+
+sign-file originally required the X.509 certificate to be in DER
+format, but now has a fallback to PEM format. It expects BIO_reset()
+to return 1 on success, but:
+
+ BIO_reset() normally returns 1 for success and 0 or -1 for failure.
+ File BIOs are an exception, they return 0 for success and -1 for
+ failure.
+
+BIO_reset() also prints accumulated error messages, which we don't
+want when we're about to try a fallback, so drain them first.
+
+Signed-off-by: Ben Hutchings
+---
+--- a/scripts/sign-file.c
++++ b/scripts/sign-file.c
+@@ -229,10 +229,14 @@ int main(int argc, char **argv)
+ ERR(!b, "%s", x509_name);
+ x509 = d2i_X509_bio(b, NULL); /* Binary encoded X.509 */
+ if (!x509) {
+- ERR(BIO_reset(b) != 1, "%s", x509_name);
++ /*
++ * We want to hold onto the error messages in case
++ * it's neither valid DER or PEM, but BIO_reset() will
++ * print them immediately so we can't.
++ */
++ drain_openssl_errors();
++ ERR(BIO_reset(b) != 0, "%s", x509_name);
+ x509 = PEM_read_bio_X509(b, NULL, NULL, NULL); /* PEM encoded X.509 */
+- if (x509)
+- drain_openssl_errors();
+ }
+ BIO_free(b);
+ ERR(!x509, "%s", x509_name);
diff --git a/debian/patches/features/all/securelevel/acpi-disable-acpi-table-override-if-securelevel-is-s.patch b/debian/patches/features/all/securelevel/acpi-disable-acpi-table-override-if-securelevel-is-s.patch
new file mode 100644
index 000000000..6313cfff6
--- /dev/null
+++ b/debian/patches/features/all/securelevel/acpi-disable-acpi-table-override-if-securelevel-is-s.patch
@@ -0,0 +1,64 @@
+From: Linn Crosetto
+Date: Fri, 4 Mar 2016 16:08:24 -0700
+Subject: [16/18] acpi: Disable ACPI table override if securelevel is set
+Origin: https://github.com/mjg59/linux/commit/a4a5ed2835e8ea042868b7401dced3f517cafa76
+
+From the kernel documentation (initrd_table_override.txt):
+
+ If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible
+ to override nearly any ACPI table provided by the BIOS with an
+ instrumented, modified one.
+
+When securelevel is set, the kernel should disallow any unauthenticated
+changes to kernel space. ACPI tables contain code invoked by the kernel, so
+do not allow ACPI tables to be overridden if securelevel is set.
+
+Signed-off-by: Linn Crosetto
+---
+ arch/x86/kernel/setup.c | 12 ++++++------
+ drivers/acpi/osl.c | 6 ++++++
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1136,6 +1136,12 @@ void __init setup_arch(char **cmdline_p)
+ /* Allocate bigger log buffer */
+ setup_log_buf(1);
+
++#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
++ if (boot_params.secure_boot) {
++ set_securelevel(1);
++ }
++#endif
++
+ reserve_initrd();
+
+ #if defined(CONFIG_ACPI) && defined(CONFIG_BLK_DEV_INITRD)
+@@ -1146,12 +1152,6 @@ void __init setup_arch(char **cmdline_p)
+
+ io_delay_init();
+
+-#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
+- if (boot_params.secure_boot) {
+- set_securelevel(1);
+- }
+-#endif
+-
+ /*
+ * Parse the ACPI tables for possible boot-time SMP configuration.
+ */
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -698,6 +698,12 @@ void __init acpi_initrd_override(void *d
+ if (table_nr == 0)
+ return;
+
++ if (get_securelevel() > 0) {
++ pr_notice(PREFIX
++ "securelevel enabled, ignoring table override\n");
++ return;
++ }
++
+ acpi_tables_addr =
+ memblock_find_in_range(0, max_low_pfn_mapped << PAGE_SHIFT,
+ all_tables_size, PAGE_SIZE);
diff --git a/debian/patches/features/all/securelevel/acpi-disable-apei-error-injection-if-securelevel-is-.patch b/debian/patches/features/all/securelevel/acpi-disable-apei-error-injection-if-securelevel-is-.patch
new file mode 100644
index 000000000..f7736af44
--- /dev/null
+++ b/debian/patches/features/all/securelevel/acpi-disable-apei-error-injection-if-securelevel-is-.patch
@@ -0,0 +1,45 @@
+From: Linn Crosetto
+Date: Wed, 16 Mar 2016 14:43:33 -0600
+Subject: [17/18] acpi: Disable APEI error injection if securelevel is set
+Origin: https://github.com/mjg59/linux/commit/d7a6be58edc01b1c66ecd8fcc91236bfbce0a420
+
+ACPI provides an error injection mechanism, EINJ, for debugging and testing
+the ACPI Platform Error Interface (APEI) and other RAS features. If
+supported by the firmware, ACPI specification 5.0 and later provide for a
+way to specify a physical memory address to which to inject the error.
+
+Injecting errors through EINJ can produce errors which to the platform are
+indistinguishable from real hardware errors. This can have undesirable
+side-effects, such as causing the platform to mark hardware as needing
+replacement.
+
+While it does not provide a method to load unauthenticated privileged code,
+the effect of these errors may persist across reboots and affect trust in
+the underlying hardware, so disable error injection through EINJ if
+securelevel is set.
+
+Signed-off-by: Linn Crosetto
+---
+ drivers/acpi/apei/einj.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/acpi/apei/einj.c
++++ b/drivers/acpi/apei/einj.c
+@@ -29,6 +29,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+
+ #include "apei-internal.h"
+@@ -521,6 +522,9 @@ static int einj_error_inject(u32 type, u
+ int rc;
+ unsigned long pfn;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ /* If user manually set "flags", make sure it is legal */
+ if (flags && (flags &
+ ~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
diff --git a/debian/patches/features/all/securelevel/acpi-ignore-acpi_rsdp-kernel-parameter-when-securele.patch b/debian/patches/features/all/securelevel/acpi-ignore-acpi_rsdp-kernel-parameter-when-securele.patch
new file mode 100644
index 000000000..8a26e52d7
--- /dev/null
+++ b/debian/patches/features/all/securelevel/acpi-ignore-acpi_rsdp-kernel-parameter-when-securele.patch
@@ -0,0 +1,36 @@
+From: Josh Boyer
+Date: Mon, 25 Jun 2012 19:57:30 -0400
+Subject: [07/18] acpi: Ignore acpi_rsdp kernel parameter when securelevel is
+ set
+Origin: https://github.com/mjg59/linux/commit/9524fadac774fbe85e2ac6abe7b957b1750c7e36
+
+This option allows userspace to pass the RSDP address to the kernel, which
+makes it possible for a user to execute arbitrary code in the kernel.
+Disable this when securelevel is set.
+
+Signed-off-by: Josh Boyer
+---
+ drivers/acpi/osl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
+index 814d5f83b75e..242ca81bb606 100644
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -40,6 +40,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include
+ #include
+@@ -254,7 +255,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
+ acpi_physical_address __init acpi_os_get_root_pointer(void)
+ {
+ #ifdef CONFIG_KEXEC
+- if (acpi_rsdp)
++ if (acpi_rsdp && (get_securelevel() <= 0))
+ return acpi_rsdp;
+ #endif
+
diff --git a/debian/patches/features/all/securelevel/acpi-limit-access-to-custom_method-if-securelevel-is.patch b/debian/patches/features/all/securelevel/acpi-limit-access-to-custom_method-if-securelevel-is.patch
new file mode 100644
index 000000000..97c0b1b05
--- /dev/null
+++ b/debian/patches/features/all/securelevel/acpi-limit-access-to-custom_method-if-securelevel-is.patch
@@ -0,0 +1,36 @@
+From: Matthew Garrett
+Date: Fri, 9 Mar 2012 08:39:37 -0500
+Subject: [06/18] acpi: Limit access to custom_method if securelevel is set
+Origin: https://github.com/mjg59/linux/commit/3cdc48db6b6d1b3cc1412d428389889f74cafe83
+
+custom_method effectively allows arbitrary access to system memory, making
+it possible for an attacker to modify the kernel at runtime. Prevent this
+if securelevel has been set.
+
+Signed-off-by: Matthew Garrett
+---
+ drivers/acpi/custom_method.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
+index c68e72414a67..359f45d54543 100644
+--- a/drivers/acpi/custom_method.c
++++ b/drivers/acpi/custom_method.c
+@@ -8,6 +8,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include "internal.h"
+
+@@ -29,6 +30,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
+ struct acpi_table_header table;
+ acpi_status status;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (!(*ppos)) {
+ /* parse the table header to get the table length */
+ if (count <= sizeof(struct acpi_table_header))
diff --git a/debian/patches/features/all/securelevel/add-bsd-style-securelevel-support.patch b/debian/patches/features/all/securelevel/add-bsd-style-securelevel-support.patch
new file mode 100644
index 000000000..15e636ce7
--- /dev/null
+++ b/debian/patches/features/all/securelevel/add-bsd-style-securelevel-support.patch
@@ -0,0 +1,208 @@
+From: Matthew Garrett
+Date: Fri, 9 Aug 2013 17:58:15 -0400
+Subject: [01/18] Add BSD-style securelevel support
+Origin: https://github.com/mjg59/linux/commit/058b8ddfe86dc90268f6dbe0ffed29ec46f1fafa
+
+Provide a coarse-grained runtime configuration option for restricting
+userspace's ability to modify the running kernel.
+
+Signed-off-by: Matthew Garrett
+---
+ Documentation/security/securelevel.txt | 23 +++++++
+ include/linux/security.h | 8 +++
+ security/Kconfig | 8 +++
+ security/Makefile | 1 +
+ security/securelevel.c | 116 +++++++++++++++++++++++++++++++++
+ 5 files changed, 156 insertions(+)
+ create mode 100644 Documentation/security/securelevel.txt
+ create mode 100644 security/securelevel.c
+
+--- /dev/null
++++ b/Documentation/security/securelevel.txt
+@@ -0,0 +1,23 @@
++Linux securelevel interface
++---------------------------
++
++The Linux securelevel interface (inspired by the BSD securelevel interface)
++is a runtime mechanism for configuring coarse-grained kernel-level security
++restrictions. It provides a runtime configuration variable at
++/sys/kernel/security/securelevel which can be written to by root. The
++following values are supported:
++
++-1: Permanently insecure mode. This level is equivalent to level 0, but once
++ set cannot be changed.
++
++0: Insecure mode (default). This level imposes no additional kernel
++ restrictions.
++
++1: Secure mode. If set, userspace will be unable to perform direct access
++ to PCI devices, port IO access, access system memory directly via
++ /dev/mem and /dev/kmem, perform kexec_load(), use the userspace
++ software suspend mechanism, insert new ACPI code at runtime via the
++ custom_method interface or modify CPU MSRs (on x86). Certain drivers
++ may also limit additional interfaces.
++
++Once the securelevel value is increased, it may not be decreased.
+--- a/include/linux/security.h
++++ b/include/linux/security.h
+@@ -1589,6 +1589,14 @@ static inline void security_audit_rule_f
+ #endif /* CONFIG_SECURITY */
+ #endif /* CONFIG_AUDIT */
+
++#ifdef CONFIG_SECURITY_SECURELEVEL
++extern int get_securelevel(void);
++extern int set_securelevel(int new_securelevel);
++#else
++static inline int get_securelevel(void) { return 0; }
++static inline int set_securelevel(int new_securelevel) { return 0; }
++#endif /* CONFIG_SECURELEVEL */
++
+ #ifdef CONFIG_SECURITYFS
+
+ extern struct dentry *securityfs_create_file(const char *name, umode_t mode,
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -93,6 +93,14 @@ config SECURITY_PATH
+ implement pathname based access controls.
+ If you are unsure how to answer this question, answer N.
+
++config SECURITY_SECURELEVEL
++ bool "Securelevel kernel restriction interface"
++ depends on SECURITY
++ help
++ This enables support for adding a set of additional kernel security
++ restrictions at runtime. See Documentation/security/securelevel.txt
++ for further information.
++
+ config INTEL_TXT
+ bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
+ depends on HAVE_INTEL_TXT
+--- a/security/Makefile
++++ b/security/Makefile
+@@ -16,6 +16,7 @@ obj-$(CONFIG_MMU) += min_addr.o
+ # Object file lists
+ obj-$(CONFIG_SECURITY) += security.o
+ obj-$(CONFIG_SECURITYFS) += inode.o
++obj-$(CONFIG_SECURITY_SECURELEVEL) += securelevel.o
+ obj-$(CONFIG_SECURITY_SELINUX) += selinux/
+ obj-$(CONFIG_SECURITY_SMACK) += smack/
+ obj-$(CONFIG_AUDIT) += lsm_audit.o
+--- /dev/null
++++ b/security/securelevel.c
+@@ -0,0 +1,116 @@
++/*
++ * securelevel.c - support for generic kernel lockdown
++ *
++ * Copyright Nebula, Inc
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include
++#include
++#include
++#include
++
++static int securelevel;
++
++static DEFINE_SPINLOCK(securelevel_lock);
++
++#define MAX_SECURELEVEL 1
++
++int get_securelevel(void)
++{
++ return securelevel;
++}
++EXPORT_SYMBOL(get_securelevel);
++
++int set_securelevel(int new_securelevel)
++{
++ int ret = 0;
++
++ spin_lock(&securelevel_lock);
++
++ if ((securelevel == -1) || (new_securelevel < securelevel) ||
++ (new_securelevel > MAX_SECURELEVEL)) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ securelevel = new_securelevel;
++out:
++ spin_unlock(&securelevel_lock);
++ return ret;
++}
++EXPORT_SYMBOL(set_securelevel);
++
++static ssize_t securelevel_read(struct file *filp, char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ char tmpbuf[12];
++ ssize_t length;
++
++ length = scnprintf(tmpbuf, sizeof(tmpbuf), "%d", securelevel);
++ return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
++}
++
++static ssize_t securelevel_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ char *page = NULL;
++ ssize_t length;
++ int new_securelevel;
++
++ length = -ENOMEM;
++ if (count >= PAGE_SIZE)
++ goto out;
++
++ length = -EINVAL;
++ if (*ppos != 0)
++ goto out;
++
++ length = -ENOMEM;
++ page = (char *)get_zeroed_page(GFP_KERNEL);
++ if (!page)
++ goto out;
++
++ length = -EFAULT;
++ if (copy_from_user(page, buf, count))
++ goto out;
++
++ length = -EINVAL;
++ if (sscanf(page, "%d", &new_securelevel) != 1)
++ goto out;
++
++ length = set_securelevel(new_securelevel);
++ if (length)
++ goto out;
++
++ length = count;
++out:
++ free_page((unsigned long) page);
++ return length;
++}
++
++static const struct file_operations securelevel_fops = {
++ .read = securelevel_read,
++ .write = securelevel_write,
++ .llseek = generic_file_llseek,
++};
++
++static __init int setup_securelevel(void)
++{
++ struct dentry *securelevel_file;
++
++ securelevel_file = securityfs_create_file("securelevel",
++ S_IWUSR | S_IRUGO,
++ NULL, NULL,
++ &securelevel_fops);
++
++ if (IS_ERR(securelevel_file))
++ return PTR_ERR(securelevel_file);
++
++ return 0;
++}
++late_initcall(setup_securelevel);
diff --git a/debian/patches/features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch b/debian/patches/features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
new file mode 100644
index 000000000..c76d6edf1
--- /dev/null
+++ b/debian/patches/features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
@@ -0,0 +1,148 @@
+From: Matthew Garrett
+Date: Fri, 9 Aug 2013 18:36:30 -0400
+Subject: [12/18] Add option to automatically set securelevel when in Secure
+ Boot mode
+Origin: https://github.com/mjg59/linux/commit/e324de2d053295670f3ba8ef67289835d663aae5
+
+UEFI Secure Boot provides a mechanism for ensuring that the firmware will
+only load signed bootloaders and kernels. Certain use cases may also
+require that the kernel prevent userspace from inserting untrusted kernel
+code at runtime. Add a configuration option that enforces this automatically
+when enabled.
+
+Signed-off-by: Matthew Garrett
+---
+ Documentation/x86/zero-page.txt | 2 ++
+ arch/x86/Kconfig | 13 +++++++++++++
+ arch/x86/boot/compressed/eboot.c | 36 +++++++++++++++++++++++++++++++++++
+ arch/x86/include/uapi/asm/bootparam.h | 3 ++-
+ arch/x86/kernel/setup.c | 7 +++++++
+ 5 files changed, 60 insertions(+), 1 deletion(-)
+
+--- a/Documentation/x86/zero-page.txt
++++ b/Documentation/x86/zero-page.txt
+@@ -31,6 +31,8 @@ Offset Proto Name Meaning
+ 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
+ 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
+ (below)
++1EB/001 ALL kbd_status Numlock is enabled
++1EC/001 ALL secure_boot Secure boot is enabled in the firmware
+ 1EF/001 ALL sentinel Used to detect broken bootloaders
+ 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
+ 2D0/A00 ALL e820_map E820 memory map table
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1754,6 +1754,19 @@ config EFI_MIXED
+
+ If unsure, say N.
+
++config EFI_SECURE_BOOT_SECURELEVEL
++ def_bool n
++ depends on SECURITY_SECURELEVEL
++ depends on EFI
++ prompt "Automatically set securelevel when UEFI Secure Boot is enabled"
++ ---help---
++ UEFI Secure Boot provides a mechanism for ensuring that the
++ firmware will only load signed bootloaders and kernels. Certain
++ use cases may also require that the kernel restrict any userspace
++ mechanism that could insert untrusted code into the kernel.
++ Say Y here to automatically enable securelevel enforcement
++ when a system boots with UEFI Secure Boot enabled.
++
+ config SECCOMP
+ def_bool y
+ prompt "Enable seccomp to safely compute untrusted bytecode"
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -12,6 +12,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include "../string.h"
+ #include "eboot.h"
+@@ -1050,6 +1051,37 @@ void setup_graphics(struct boot_params *
+ }
+ }
+
++static int get_secure_boot(void)
++{
++ u8 sb, setup;
++ unsigned long datasize = sizeof(sb);
++ efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
++ efi_status_t status;
++
++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
++ L"SecureBoot", &var_guid, NULL, &datasize, &sb);
++
++ if (status != EFI_SUCCESS)
++ return 0;
++
++ if (sb == 0)
++ return 0;
++
++
++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
++ L"SetupMode", &var_guid, NULL, &datasize,
++ &setup);
++
++ if (status != EFI_SUCCESS)
++ return 0;
++
++ if (setup == 1)
++ return 0;
++
++ return 1;
++}
++
++
+ /*
+ * Because the x86 boot code expects to be passed a boot_params we
+ * need to create one ourselves (usually the bootloader would create
+@@ -1432,6 +1464,10 @@ struct boot_params *efi_main(struct efi_
+ else
+ setup_boot_services32(efi_early);
+
++ sanitize_boot_params(boot_params);
++
++ boot_params->secure_boot = get_secure_boot();
++
+ setup_graphics(boot_params);
+
+ setup_efi_pci(boot_params);
+--- a/arch/x86/include/uapi/asm/bootparam.h
++++ b/arch/x86/include/uapi/asm/bootparam.h
+@@ -134,7 +134,8 @@ struct boot_params {
+ __u8 eddbuf_entries; /* 0x1e9 */
+ __u8 edd_mbr_sig_buf_entries; /* 0x1ea */
+ __u8 kbd_status; /* 0x1eb */
+- __u8 _pad5[3]; /* 0x1ec */
++ __u8 secure_boot; /* 0x1ec */
++ __u8 _pad5[2]; /* 0x1ed */
+ /*
+ * The sentinel is set to a nonzero value (0xff) in header.S.
+ *
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -50,6 +50,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include
+ #include
+@@ -1145,6 +1146,12 @@ void __init setup_arch(char **cmdline_p)
+
+ io_delay_init();
+
++#ifdef CONFIG_EFI_SECURE_BOOT_SECURELEVEL
++ if (boot_params.secure_boot) {
++ set_securelevel(1);
++ }
++#endif
++
+ /*
+ * Parse the ACPI tables for possible boot-time SMP configuration.
+ */
diff --git a/debian/patches/features/all/securelevel/asus-wmi-restrict-debugfs-interface-when-securelevel.patch b/debian/patches/features/all/securelevel/asus-wmi-restrict-debugfs-interface-when-securelevel.patch
new file mode 100644
index 000000000..08afb52c7
--- /dev/null
+++ b/debian/patches/features/all/securelevel/asus-wmi-restrict-debugfs-interface-when-securelevel.patch
@@ -0,0 +1,57 @@
+From: Matthew Garrett
+Date: Fri, 9 Mar 2012 08:46:50 -0500
+Subject: [11/18] asus-wmi: Restrict debugfs interface when securelevel is set
+Origin: https://github.com/mjg59/linux/commit/f6e21827205ffcbfcce4b13d3a233427c3e742e0
+
+We have no way of validating what all of the Asus WMI methods do on a
+given machine, and there's a risk that some will allow hardware state to
+be manipulated in such a way that arbitrary code can be executed in the
+kernel. Prevent that if securelevel is set.
+
+Signed-off-by: Matthew Garrett
+---
+ drivers/platform/x86/asus-wmi.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index a96630d52346..93943e480a67 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -45,6 +45,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+ #include
+ #include
+@@ -1867,6 +1868,9 @@ static int show_dsts(struct seq_file *m, void *data)
+ int err;
+ u32 retval = -1;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
+
+ if (err < 0)
+@@ -1883,6 +1887,9 @@ static int show_devs(struct seq_file *m, void *data)
+ int err;
+ u32 retval = -1;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
+ &retval);
+
+@@ -1907,6 +1914,9 @@ static int show_call(struct seq_file *m, void *data)
+ union acpi_object *obj;
+ acpi_status status;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
+ 1, asus->debug.method_id,
+ &input, &output);
diff --git a/debian/patches/features/all/securelevel/efi-disable-secure-boot-if-shim-is-in-insecure-mode.patch b/debian/patches/features/all/securelevel/efi-disable-secure-boot-if-shim-is-in-insecure-mode.patch
new file mode 100644
index 000000000..98cd43c6d
--- /dev/null
+++ b/debian/patches/features/all/securelevel/efi-disable-secure-boot-if-shim-is-in-insecure-mode.patch
@@ -0,0 +1,66 @@
+From: Josh Boyer
+Date: Tue, 5 Feb 2013 19:25:05 -0500
+Subject: [13/18] efi: Disable secure boot if shim is in insecure mode
+Origin: https://github.com/mjg59/linux/commit/f444a5ecb0ab09d6cf661b4520dd8e6fffacb8be
+
+A user can manually tell the shim boot loader to disable validation of
+images it loads. When a user does this, it creates a UEFI variable called
+MokSBState that does not have the runtime attribute set. Given that the
+user explicitly disabled validation, we can honor that and not enable
+secure boot mode if that variable is set.
+
+Signed-off-by: Josh Boyer
+---
+ arch/x86/boot/compressed/eboot.c | 20 +++++++++++++++++++-
+ include/linux/efi.h | 3 +++
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -1053,8 +1053,9 @@ void setup_graphics(struct boot_params *
+
+ static int get_secure_boot(void)
+ {
+- u8 sb, setup;
++ u8 sb, setup, moksbstate;
+ unsigned long datasize = sizeof(sb);
++ u32 attr;
+ efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
+ efi_status_t status;
+
+@@ -1078,6 +1079,23 @@ static int get_secure_boot(void)
+ if (setup == 1)
+ return 0;
+
++ /* See if a user has put shim into insecure_mode. If so, and the variable
++ * doesn't have the runtime attribute set, we might as well honor that.
++ */
++ var_guid = EFI_SHIM_LOCK_GUID;
++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable,
++ L"MokSBState", &var_guid, &attr, &datasize,
++ &moksbstate);
++
++ /* If it fails, we don't care why. Default to secure */
++ if (status != EFI_SUCCESS)
++ return 1;
++
++ if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS)) {
++ if (moksbstate == 1)
++ return 0;
++ }
++
+ return 1;
+ }
+
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -629,6 +629,9 @@ typedef struct {
+ #define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | (10))
+ #define EFI_1_02_SYSTEM_TABLE_REVISION ((1 << 16) | (02))
+
++#define EFI_SHIM_LOCK_GUID \
++ EFI_GUID( 0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 )
++
+ typedef struct {
+ efi_table_hdr_t hdr;
+ u64 fw_vendor; /* physical addr of CHAR16 vendor string */
diff --git a/debian/patches/features/all/securelevel/enable-cold-boot-attack-mitigation.patch b/debian/patches/features/all/securelevel/enable-cold-boot-attack-mitigation.patch
new file mode 100644
index 000000000..14d5a3bda
--- /dev/null
+++ b/debian/patches/features/all/securelevel/enable-cold-boot-attack-mitigation.patch
@@ -0,0 +1,49 @@
+From: Matthew Garrett
+Date: Tue, 12 Jan 2016 12:51:27 -0800
+Subject: [18/18] Enable cold boot attack mitigation
+Origin: https://github.com/mjg59/linux/commit/02d999574936dd234a508c0112a0200c135a5c34
+
+---
+ arch/x86/boot/compressed/eboot.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
+index 28c24d80d0a0..b0413ba639af 100644
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -1051,6 +1051,22 @@ void setup_graphics(struct boot_params *boot_params)
+ }
+ }
+
++#define MEMORY_ONLY_RESET_CONTROL_GUID \
++ EFI_GUID (0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
++
++static void enable_reset_attack_mitigation(void)
++{
++ u8 val = 1;
++ efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
++
++ /* Ignore the return value here - there's not really a lot we can do */
++ efi_early->call((unsigned long)sys_table->runtime->set_variable,
++ L"MemoryOverwriteRequestControl", &var_guid,
++ EFI_VARIABLE_NON_VOLATILE |
++ EFI_VARIABLE_BOOTSERVICE_ACCESS |
++ EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), val);
++}
++
+ static int get_secure_boot(void)
+ {
+ u8 sb, setup, moksbstate;
+@@ -1482,6 +1498,12 @@ struct boot_params *efi_main(struct efi_config *c,
+ else
+ setup_boot_services32(efi_early);
+
++ /*
++ * Ask the firmware to clear memory if we don't have a clean
++ * shutdown
++ */
++ enable_reset_attack_mitigation();
++
+ sanitize_boot_params(boot_params);
+
+ boot_params->secure_boot = get_secure_boot();
diff --git a/debian/patches/features/all/securelevel/enforce-module-signatures-when-securelevel-is-greate.patch b/debian/patches/features/all/securelevel/enforce-module-signatures-when-securelevel-is-greate.patch
new file mode 100644
index 000000000..f6a295980
--- /dev/null
+++ b/debian/patches/features/all/securelevel/enforce-module-signatures-when-securelevel-is-greate.patch
@@ -0,0 +1,24 @@
+From: Matthew Garrett
+Date: Mon, 9 Sep 2013 08:46:52 -0400
+Subject: [02/18] Enforce module signatures when securelevel is greater than 0
+Origin: https://github.com/mjg59/linux/commit/90e0fa532b145d1bb76c368277a3a3e3b3eb5c94
+
+If securelevel has been set to 1 or greater, require that all modules have
+valid signatures.
+
+Signed-off-by: Matthew Garrett
+---
+ kernel/module.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -2616,7 +2616,7 @@ static int module_sig_check(struct load_
+ }
+
+ /* Not having a signature is only an error if we're strict. */
+- if (err == -ENOKEY && !sig_enforce)
++ if ((err == -ENOKEY && !sig_enforce) && (get_securelevel() <= 0))
+ err = 0;
+
+ return err;
diff --git a/debian/patches/features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch b/debian/patches/features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
new file mode 100644
index 000000000..3f2231456
--- /dev/null
+++ b/debian/patches/features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
@@ -0,0 +1,36 @@
+From: Josh Boyer
+Date: Fri, 20 Jun 2014 08:53:24 -0400
+Subject: [14/18] hibernate: Disable when securelevel is set
+Origin: https://github.com/mjg59/linux/commit/500a87278c5c0608ba88ed8af7a35fcfa955c492
+
+There is currently no way to verify the resume image when returning
+from hibernate. This might compromise the securelevel trust model,
+so until we can work with signed hibernate images we disable it in
+a secure modules environment.
+
+Signed-off-by: Josh Boyer
+---
+ kernel/power/hibernate.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index fca9254280ee..7bf7f723a27f 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -29,6 +29,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+
+ #include "power.h"
+@@ -66,7 +67,7 @@ static const struct platform_hibernation_ops *hibernation_ops;
+
+ bool hibernation_available(void)
+ {
+- return (nohibernate == 0);
++ return ((nohibernate == 0) && (get_securelevel() <= 0));
+ }
+
+ /**
diff --git a/debian/patches/features/all/securelevel/kexec-disable-at-runtime-if-securelevel-has-been-set.patch b/debian/patches/features/all/securelevel/kexec-disable-at-runtime-if-securelevel-has-been-set.patch
new file mode 100644
index 000000000..3969a8e7e
--- /dev/null
+++ b/debian/patches/features/all/securelevel/kexec-disable-at-runtime-if-securelevel-has-been-set.patch
@@ -0,0 +1,36 @@
+From: Matthew Garrett
+Date: Fri, 9 Aug 2013 03:33:56 -0400
+Subject: [08/18] kexec: Disable at runtime if securelevel has been set.
+Origin: https://github.com/mjg59/linux/commit/ec87b6aac76fd553578cec2c05674e22b79afe3e
+
+kexec permits the loading and execution of arbitrary code in ring 0, which
+permits the modification of the running kernel. Prevent this if securelevel
+has been set.
+
+Signed-off-by: Matthew Garrett
+---
+ kernel/kexec.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/kexec.c b/kernel/kexec.c
+index ee70aef5cd81..542655ea297c 100644
+--- a/kernel/kexec.c
++++ b/kernel/kexec.c
+@@ -17,6 +17,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include "kexec_internal.h"
+
+@@ -134,6 +135,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
+ if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+ return -EPERM;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ /*
+ * Verify we have a legal set of flags
+ * This leaves us room for future extensions.
diff --git a/debian/patches/features/all/securelevel/kexec-uefi-copy-secure_boot-flag-in-boot-params-acro.patch b/debian/patches/features/all/securelevel/kexec-uefi-copy-secure_boot-flag-in-boot-params-acro.patch
new file mode 100644
index 000000000..445aa6369
--- /dev/null
+++ b/debian/patches/features/all/securelevel/kexec-uefi-copy-secure_boot-flag-in-boot-params-acro.patch
@@ -0,0 +1,32 @@
+From: Dave Young
+Date: Tue, 6 Oct 2015 13:31:31 +0100
+Subject: [15/18] kexec/uefi: copy secure_boot flag in boot params across kexec
+ reboot
+Origin: https://github.com/mjg59/linux/commit/4b2b64d5a6ebc84214755ebccd599baef7c1b798
+
+Kexec reboot in case secure boot being enabled does not keep the secure
+boot mode in new kernel, so later one can load unsigned kernel via legacy
+kexec_load. In this state, the system is missing the protections provided
+by secure boot. Adding a patch to fix this by retain the secure_boot flag
+in original kernel.
+
+secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
+stub. Fixing this issue by copying secure_boot flag across kexec reboot.
+
+Signed-off-by: Dave Young
+---
+ arch/x86/kernel/kexec-bzimage64.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
+index 2af478e3fd4e..61827eeb6881 100644
+--- a/arch/x86/kernel/kexec-bzimage64.c
++++ b/arch/x86/kernel/kexec-bzimage64.c
+@@ -180,6 +180,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
+ if (efi_enabled(EFI_OLD_MEMMAP))
+ return 0;
+
++ params->secure_boot = boot_params.secure_boot;
+ ei->efi_loader_signature = current_ei->efi_loader_signature;
+ ei->efi_systab = current_ei->efi_systab;
+ ei->efi_systab_hi = current_ei->efi_systab_hi;
diff --git a/debian/patches/features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch b/debian/patches/features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
new file mode 100644
index 000000000..64624bd57
--- /dev/null
+++ b/debian/patches/features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
@@ -0,0 +1,108 @@
+From: Matthew Garrett
+Date: Thu, 8 Mar 2012 10:10:38 -0500
+Subject: [03/18] PCI: Lock down BAR access when securelevel is enabled
+Origin: https://github.com/mjg59/linux/commit/2533a3844cf8c43bf58b653334f8925cd1e7d405
+
+Any hardware that can potentially generate DMA has to be locked down from
+userspace in order to avoid it being possible for an attacker to modify
+kernel code. This should be prevented if securelevel has been set. Default
+to paranoid - in future we can potentially relax this for sufficiently
+IOMMU-isolated devices.
+
+Signed-off-by: Matthew Garrett
+---
+ drivers/pci/pci-sysfs.c | 9 +++++++++
+ drivers/pci/proc.c | 9 ++++++++-
+ drivers/pci/syscall.c | 3 ++-
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -711,6 +711,9 @@ static ssize_t pci_write_config(struct f
+ loff_t init_off = off;
+ u8 *data = (u8 *) buf;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (off > dev->cfg_size)
+ return 0;
+ if (off + count > dev->cfg_size) {
+@@ -998,6 +1001,9 @@ static int pci_mmap_resource(struct kobj
+ resource_size_t start, end;
+ int i;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ for (i = 0; i < PCI_ROM_RESOURCE; i++)
+ if (res == &pdev->resource[i])
+ break;
+@@ -1098,6 +1104,9 @@ static ssize_t pci_write_resource_io(str
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+ {
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ return pci_resource_io(filp, kobj, attr, buf, off, count, true);
+ }
+
+--- a/drivers/pci/proc.c
++++ b/drivers/pci/proc.c
+@@ -11,6 +11,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+ #include
+ #include "pci.h"
+@@ -116,6 +117,9 @@ static ssize_t proc_bus_pci_write(struct
+ int size = dev->cfg_size;
+ int cnt;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (pos >= size)
+ return 0;
+ if (nbytes >= size)
+@@ -195,6 +199,9 @@ static long proc_bus_pci_ioctl(struct fi
+ #endif /* HAVE_PCI_MMAP */
+ int ret = 0;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ switch (cmd) {
+ case PCIIOC_CONTROLLER:
+ ret = pci_domain_nr(dev->bus);
+@@ -233,7 +240,7 @@ static int proc_bus_pci_mmap(struct file
+ struct pci_filp_private *fpriv = file->private_data;
+ int i, ret;
+
+- if (!capable(CAP_SYS_RAWIO))
++ if (!capable(CAP_SYS_RAWIO) || (get_securelevel() > 0))
+ return -EPERM;
+
+ /* Make sure the caller is mapping a real resource for this device */
+--- a/drivers/pci/syscall.c
++++ b/drivers/pci/syscall.c
+@@ -10,6 +10,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+ #include "pci.h"
+
+@@ -92,7 +93,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigne
+ u32 dword;
+ int err = 0;
+
+- if (!capable(CAP_SYS_ADMIN))
++ if (!capable(CAP_SYS_ADMIN) || (get_securelevel() > 0))
+ return -EPERM;
+
+ dev = pci_get_bus_and_slot(bus, dfn);
diff --git a/debian/patches/features/all/securelevel/restrict-dev-mem-and-dev-kmem-when-securelevel-is-se.patch b/debian/patches/features/all/securelevel/restrict-dev-mem-and-dev-kmem-when-securelevel-is-se.patch
new file mode 100644
index 000000000..48cf73dd7
--- /dev/null
+++ b/debian/patches/features/all/securelevel/restrict-dev-mem-and-dev-kmem-when-securelevel-is-se.patch
@@ -0,0 +1,38 @@
+From: Matthew Garrett
+Date: Fri, 9 Mar 2012 09:28:15 -0500
+Subject: [05/18] Restrict /dev/mem and /dev/kmem when securelevel is set.
+Origin: https://github.com/mjg59/linux/commit/401996625d478c814fe9e736ca9e6c5c5f055f06
+
+Allowing users to write to address space provides mechanisms that may permit
+modification of the kernel at runtime. Prevent this if securelevel has been
+set.
+
+Signed-off-by: Matthew Garrett
+---
+ drivers/char/mem.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/char/mem.c b/drivers/char/mem.c
+index cef0d40a3d74..c810f1e15c73 100644
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -167,6 +167,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
+ if (p != *ppos)
+ return -EFBIG;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (!valid_phys_addr_range(p, count))
+ return -EFAULT;
+
+@@ -513,6 +516,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
+ char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+ int err = 0;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (p < (unsigned long) high_memory) {
+ unsigned long to_write = min_t(unsigned long, count,
+ (unsigned long)high_memory - p);
diff --git a/debian/patches/features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch b/debian/patches/features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
new file mode 100644
index 000000000..88129ec7b
--- /dev/null
+++ b/debian/patches/features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
@@ -0,0 +1,36 @@
+From: Matthew Garrett
+Date: Tue, 3 Sep 2013 11:23:29 -0400
+Subject: [09/18] uswsusp: Disable when securelevel is set
+Origin: https://github.com/mjg59/linux/commit/504f45f7cc9b4265a4d89728c4f8254295e81977
+
+uswsusp allows a user process to dump and then restore kernel state, which
+makes it possible to modify the running kernel. Disable this if securelevel
+has been set.
+
+Signed-off-by: Matthew Garrett
+---
+ kernel/power/user.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/power/user.c b/kernel/power/user.c
+index 526e8911460a..40618bf41620 100644
+--- a/kernel/power/user.c
++++ b/kernel/power/user.c
+@@ -24,6 +24,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include
+
+@@ -52,6 +53,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
+ if (!hibernation_available())
+ return -EPERM;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ lock_system_sleep();
+
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
diff --git a/debian/patches/features/all/securelevel/x86-lock-down-io-port-access-when-securelevel-is-ena.patch b/debian/patches/features/all/securelevel/x86-lock-down-io-port-access-when-securelevel-is-ena.patch
new file mode 100644
index 000000000..b62f47511
--- /dev/null
+++ b/debian/patches/features/all/securelevel/x86-lock-down-io-port-access-when-securelevel-is-ena.patch
@@ -0,0 +1,74 @@
+From: Matthew Garrett
+Date: Thu, 8 Mar 2012 10:35:59 -0500
+Subject: [04/18] x86: Lock down IO port access when securelevel is enabled
+Origin: https://github.com/mjg59/linux/commit/2ad64f6ea1f1164c8b552860faa27392d9da9928
+
+IO port access would permit users to gain access to PCI configuration
+registers, which in turn (on a lot of hardware) give access to MMIO register
+space. This would potentially permit root to trigger arbitrary DMA, so lock
+it down when securelevel is set.
+
+Signed-off-by: Matthew Garrett
+---
+ arch/x86/kernel/ioport.c | 5 +++--
+ drivers/char/mem.c | 7 +++++++
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kernel/ioport.c
++++ b/arch/x86/kernel/ioport.c
+@@ -15,6 +15,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+
+ /*
+@@ -28,7 +29,7 @@ asmlinkage long sys_ioperm(unsigned long
+
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
+ return -EINVAL;
+- if (turn_on && !capable(CAP_SYS_RAWIO))
++ if (turn_on && (!capable(CAP_SYS_RAWIO) || (get_securelevel() > 0)))
+ return -EPERM;
+
+ /*
+@@ -103,7 +104,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
+ return -EINVAL;
+ /* Trying to gain more privileges? */
+ if (level > old) {
+- if (!capable(CAP_SYS_RAWIO))
++ if (!capable(CAP_SYS_RAWIO) || (get_securelevel() > 0))
+ return -EPERM;
+ }
+ regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -27,6 +27,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include
+
+@@ -559,6 +560,9 @@ static ssize_t read_port(struct file *fi
+ unsigned long i = *ppos;
+ char __user *tmp = buf;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (!access_ok(VERIFY_WRITE, buf, count))
+ return -EFAULT;
+ while (count-- > 0 && i < 65536) {
+@@ -577,6 +581,9 @@ static ssize_t write_port(struct file *f
+ unsigned long i = *ppos;
+ const char __user *tmp = buf;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (!access_ok(VERIFY_READ, buf, count))
+ return -EFAULT;
+ while (count-- > 0 && i < 65536) {
diff --git a/debian/patches/features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch b/debian/patches/features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
new file mode 100644
index 000000000..e46e85ec4
--- /dev/null
+++ b/debian/patches/features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
@@ -0,0 +1,46 @@
+From: Matthew Garrett
+Date: Fri, 8 Feb 2013 11:12:13 -0800
+Subject: [10/18] x86: Restrict MSR access when securelevel is set
+Origin: https://github.com/mjg59/linux/commit/c6ad37822699967e60fae57a64ae89676f543182
+
+Permitting write access to MSRs allows userspace to modify the running
+kernel. Prevent this if securelevel has been set. Based on a patch by Kees
+Cook.
+
+Cc: Kees Cook
+Signed-off-by: Matthew Garrett
+---
+ arch/x86/kernel/msr.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/x86/kernel/msr.c
++++ b/arch/x86/kernel/msr.c
+@@ -39,6 +39,7 @@
+ #include
+ #include
+ #include
++#include
+
+ #include
+ #include
+@@ -83,6 +84,9 @@ static ssize_t msr_write(struct file *fi
+ int err = 0;
+ ssize_t bytes = 0;
+
++ if (get_securelevel() > 0)
++ return -EPERM;
++
+ if (count % 8)
+ return -EINVAL; /* Invalid chunk size */
+
+@@ -130,6 +134,10 @@ static long msr_ioctl(struct file *file,
+ err = -EBADF;
+ break;
+ }
++ if (get_securelevel() > 0) {
++ err = -EPERM;
++ break;
++ }
+ if (copy_from_user(®s, uregs, sizeof regs)) {
+ err = -EFAULT;
+ break;
diff --git a/debian/patches/series b/debian/patches/series
index 7aa6e87d4..342528080 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -77,6 +77,26 @@ features/all/grsecurity/grsecurity-kconfig.patch
#features/all/grsecurity/grsecurity-kbuild.patch
features/all/grsecurity/grkernsec_perf_harden.patch
+# Securelevel patchset from mjg59
+features/all/securelevel/add-bsd-style-securelevel-support.patch
+features/all/securelevel/enforce-module-signatures-when-securelevel-is-greate.patch
+features/all/securelevel/pci-lock-down-bar-access-when-securelevel-is-enabled.patch
+features/all/securelevel/x86-lock-down-io-port-access-when-securelevel-is-ena.patch
+features/all/securelevel/restrict-dev-mem-and-dev-kmem-when-securelevel-is-se.patch
+features/all/securelevel/acpi-limit-access-to-custom_method-if-securelevel-is.patch
+features/all/securelevel/acpi-ignore-acpi_rsdp-kernel-parameter-when-securele.patch
+features/all/securelevel/kexec-disable-at-runtime-if-securelevel-has-been-set.patch
+features/all/securelevel/uswsusp-disable-when-securelevel-is-set.patch
+features/all/securelevel/x86-restrict-msr-access-when-securelevel-is-set.patch
+features/all/securelevel/asus-wmi-restrict-debugfs-interface-when-securelevel.patch
+features/all/securelevel/add-option-to-automatically-set-securelevel-when-in-.patch
+features/all/securelevel/efi-disable-secure-boot-if-shim-is-in-insecure-mode.patch
+features/all/securelevel/hibernate-disable-when-securelevel-is-set.patch
+features/all/securelevel/kexec-uefi-copy-secure_boot-flag-in-boot-params-acro.patch
+features/all/securelevel/acpi-disable-acpi-table-override-if-securelevel-is-s.patch
+features/all/securelevel/acpi-disable-apei-error-injection-if-securelevel-is-.patch
+features/all/securelevel/enable-cold-boot-attack-mitigation.patch
+
# Security fixes
bugfix/all/ptrace-being-capable-wrt-a-process-requires-mapped-uids-gids.patch
bugfix/x86/x86-mm-page-align-the-_end-symbol-to-avoid-pfn-conve.patch
@@ -115,3 +135,4 @@ bugfix/all/lockdep-add-missing-macros.patch
bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch
bugfix/all/power-cpupower-fix-manpages-NAME.patch
bugfix/all/tools-lib-traceevent-fix-use-of-uninitialized-variables.patch
+bugfix/all/scripts-fix-x.509-pem-support-in-sign-file.patch
diff --git a/debian/rules.d/scripts/Makefile b/debian/rules.d/scripts/Makefile
index 63cc4be87..d735ecf03 100644
--- a/debian/rules.d/scripts/Makefile
+++ b/debian/rules.d/scripts/Makefile
@@ -1,8 +1,10 @@
PROGS = \
conmakehash \
+ extract-cert \
kallsyms \
pnmtologo \
- recordmcount
+ recordmcount \
+ sign-file
DATA = \
Kbuild.include \
@@ -37,3 +39,4 @@ SUBDIRS = \
include $(top_rulesdir)/Makefile.inc
CPPFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+extract-cert sign-file: LDLIBS += -lcrypto
diff --git a/debian/templates/control.source.in b/debian/templates/control.source.in
index ab65421ea..43677eba7 100644
--- a/debian/templates/control.source.in
+++ b/debian/templates/control.source.in
@@ -4,7 +4,7 @@ Maintainer: Debian Kernel Team
Uploaders: Bastian Blank , maximilian attems , Ben Hutchings
Standards-Version: 3.9.5
Build-Depends: debhelper, python3:any, quilt,
- cpio , kmod , xz-utils , kernel-wedge (>= 2.93~) , bc ,
+ cpio , kmod , xz-utils , kernel-wedge (>= 2.93~) , bc , libssl-dev , openssl ,
asciidoc , bison , flex , gcc-multilib [amd64 ppc64 s390x sparc64] , libaudit-dev , libdw-dev , libelf-dev , libiberty-dev | binutils-dev (<< 2.23.91.20131123-1) , libnewt-dev , libnuma-dev [amd64 arm64 hppa i386 mips mips64 mips64el mipsel powerpc powerpcspe ppc64 ppc64el sparc x32] , libperl-dev , libunwind8-dev [amd64 armel armhf arm64 i386] , python-dev , xmlto ,
autoconf , automake , libtool , libglib2.0-dev , libudev-dev , libwrap0-dev , libpci-dev ,
dh-python , dh-systemd