Merge pull request #2299 from flatcar/jepio+sayan/sboot-lockdown

secure boot: lockdown, grub fallback, CI
This commit is contained in:
Jeremi Piotrowski 2024-09-17 13:55:49 +02:00 committed by GitHub
commit a23e5bbed2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 594 additions and 20 deletions

View File

@ -162,7 +162,7 @@ jobs:
# Extract the generic image we'll use for qemu tests. # Extract the generic image we'll use for qemu tests.
# Note that the qemu[_uefi] tests use the generic image instead of the # Note that the qemu[_uefi] tests use the generic image instead of the
# qemu vendor VM image ("Astronaut: [...] Always have been."). # qemu vendor VM image ("Astronaut: [...] Always have been.").
mv flatcar_production_image.bin flatcar_production_qemu_uefi_efi_code.fd scripts/ mv flatcar_production_image.bin flatcar_production_qemu_uefi_efi_code.fd flatcar_production_qemu_uefi_efi_vars.fd scripts/
mv flatcar_test_update.gz scripts/ mv flatcar_test_update.gz scripts/
@ -197,7 +197,8 @@ jobs:
cat > sdk_container/.env <<EOF cat > sdk_container/.env <<EOF
# export the QEMU_IMAGE_NAME to avoid to download it. # export the QEMU_IMAGE_NAME to avoid to download it.
export QEMU_IMAGE_NAME="/work/flatcar_production_image.bin" export QEMU_IMAGE_NAME="/work/flatcar_production_image.bin"
export QEMU_UEFI_BIOS="/work/flatcar_production_qemu_uefi_efi_code.fd" export QEMU_UEFI_FIRMWARE="/work/flatcar_production_qemu_uefi_efi_code.fd"
export QEMU_UEFI_OVMF_VARS="/work/flatcar_production_qemu_uefi_efi_vars.fd"
export QEMU_UPDATE_PAYLOAD="/work/flatcar_test_update.gz" export QEMU_UPDATE_PAYLOAD="/work/flatcar_test_update.gz"
export QEMU_DEVCONTAINER_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}" export QEMU_DEVCONTAINER_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}"
export QEMU_DEVCONTAINER_BINHOST_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}" export QEMU_DEVCONTAINER_BINHOST_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}"

View File

@ -9,6 +9,9 @@ insmod all_video
# Default menuentry id and boot timeout # Default menuentry id and boot timeout
set default="flatcar" set default="flatcar"
# Retry default boot entry - this will decrement the gpt tries counter and
# switch to previous entry when all attempts are exhausted.
set fallback="0 0 0"
set timeout=1 set timeout=1
# Default kernel args for root filesystem, console, and Flatcar. # Default kernel args for root filesystem, console, and Flatcar.

View File

@ -0,0 +1 @@
- Kernel lockdown in integrity mode is now enabled when secure boot is enabled. This prevents loading unsigned kernel modules and matches the behavior of all major distros. ([scripts#2299](https://github.com/flatcar/scripts/pull/2299))

View File

@ -60,13 +60,15 @@ QEMU_PARALLEL="${PARALLEL_TESTS:-20}"
# Whether kola can use loop devices to capture serial console output and check for error patterns # Whether kola can use loop devices to capture serial console output and check for error patterns
QEMU_KOLA_SKIP_MANGLE="${QEMU_KOLA_SKIP_MANGLE:-}" QEMU_KOLA_SKIP_MANGLE="${QEMU_KOLA_SKIP_MANGLE:-}"
# BIOS path within the SDK # Firmware path within the SDK
QEMU_BIOS="/usr/share/qemu/bios-256k.bin" QEMU_FIRMWARE="/usr/share/qemu/bios-256k.bin"
# UEFI bios filename on build cache. # UEFI firmware filename on build cache.
# Published by vms.sh as part of the qemu vendor build. # Published by vms.sh as part of the qemu vendor build.
QEMU_UEFI_BIOS="${QEMU_UEFI_BIOS:-flatcar_production_qemu_uefi_efi_code.fd}" QEMU_UEFI_FIRMWARE="${QEMU_UEFI_FIRMWARE:-flatcar_production_qemu_uefi_efi_code.fd}"
QEMU_UEFI_SECURE_BIOS="${QEMU_UEFI_SECURE_BIOS:-flatcar_production_qemu_uefi_secure_efi_code.fd}" QEMU_UEFI_SECURE_FIRMWARE="${QEMU_UEFI_SECURE_FIRMWARE:-flatcar_production_qemu_uefi_secure_efi_code.fd}"
QEMU_UEFI_OVMF_VARS="${QEMU_UEFI_OVMF_VARS:-flatcar_production_qemu_uefi_efi_vars.fd}"
QEMU_UEFI_SECURE_OVMF_VARS="${QEMU_UEFI_SECURE_OVMF_VARS:-flatcar_production_qemu_uefi_secure_efi_vars.fd}"
# Update payload for the qemu_update.sh test. # Update payload for the qemu_update.sh test.
# The default path set below is relative to TEST_WORK_DIR # The default path set below is relative to TEST_WORK_DIR

View File

@ -10,6 +10,9 @@ set -euo pipefail
source ci-automation/vendor_test.sh source ci-automation/vendor_test.sh
SECUREBOOT=""
ovmf_vars=""
# ARM64 qemu tests only supported on UEFI # ARM64 qemu tests only supported on UEFI
if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; then if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; then
echo "1..1" > "${CIA_TAPFILE}" echo "1..1" > "${CIA_TAPFILE}"
@ -21,7 +24,7 @@ if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; th
exit 1 exit 1
fi fi
# Fetch image and BIOS if not present # Fetch image and firmware if not present
if [ -f "${QEMU_IMAGE_NAME}" ] ; then if [ -f "${QEMU_IMAGE_NAME}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${QEMU_IMAGE_NAME} for testing ${CIA_VERNUM} (${CIA_ARCH}) ++++" echo "++++ ${CIA_TESTSCRIPT}: Using existing ${QEMU_IMAGE_NAME} for testing ${CIA_VERNUM} (${CIA_ARCH}) ++++"
else else
@ -31,21 +34,30 @@ else
lbunzip2 "${QEMU_IMAGE_NAME}.bz2" lbunzip2 "${QEMU_IMAGE_NAME}.bz2"
fi fi
bios="${QEMU_BIOS}" firmware="${QEMU_FIRMWARE}"
if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] ; then if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] ; then
bios="${QEMU_UEFI_BIOS}" firmware="${QEMU_UEFI_FIRMWARE}"
ovmf_vars="${QEMU_UEFI_OVMF_VARS}"
fi fi
if [ "${CIA_TESTSCRIPT}" = "qemu_uefi_secure.sh" ] ; then if [ "${CIA_TESTSCRIPT}" = "qemu_uefi_secure.sh" ] ; then
bios="${QEMU_UEFI_SECURE_BIOS}" firmware="${QEMU_UEFI_SECURE_FIRMWARE}"
ovmf_vars="${QEMU_UEFI_SECURE_OVMF_VARS}"
SECUREBOOT=1
fi fi
if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] || [ "${CIA_TESTSCRIPT}" = "qemu_uefi_secure.sh" ] ; then if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] || [ "${CIA_TESTSCRIPT}" = "qemu_uefi_secure.sh" ] ; then
if [ -f "${bios}" ] ; then if [ -f "${firmware}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${bios} ++++" echo "++++ ${CIA_TESTSCRIPT}: Using existing ${firmware} ++++"
else else
echo "++++ ${CIA_TESTSCRIPT}: downloading ${bios} for ${CIA_VERNUM} (${CIA_ARCH}) ++++" echo "++++ ${CIA_TESTSCRIPT}: downloading ${firmware} for ${CIA_VERNUM} (${CIA_ARCH}) ++++"
copy_from_buildcache "images/${CIA_ARCH}/${CIA_VERNUM}/${bios}" . copy_from_buildcache "images/${CIA_ARCH}/${CIA_VERNUM}/${firmware}" .
fi
if [ -f "${ovmf_vars}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${ovmf_vars} ++++"
else
echo "++++ ${CIA_TESTSCRIPT}: downloading ${ovmf_vars} for ${CIA_VERNUM} (${CIA_ARCH}) ++++"
copy_from_buildcache "images/${CIA_ARCH}/${CIA_VERNUM}/${ovmf_vars}" .
fi fi
fi fi
@ -68,11 +80,13 @@ kola run \
--board="${CIA_ARCH}-usr" \ --board="${CIA_ARCH}-usr" \
--parallel="${QEMU_PARALLEL}" \ --parallel="${QEMU_PARALLEL}" \
--platform=qemu \ --platform=qemu \
--qemu-bios="${bios}" \ --qemu-firmware="${firmware}" \
--qemu-image="${QEMU_IMAGE_NAME}" \ --qemu-image="${QEMU_IMAGE_NAME}" \
--tapfile="${CIA_TAPFILE}" \ --tapfile="${CIA_TAPFILE}" \
"${ovmf_vars:+--qemu-ovmf-vars=${ovmf_vars}}" \
${QEMU_KOLA_SKIP_MANGLE:+--qemu-skip-mangle} \ ${QEMU_KOLA_SKIP_MANGLE:+--qemu-skip-mangle} \
"${devcontainer_opts[@]}" \ "${devcontainer_opts[@]}" \
${SECUREBOOT:+--enable-secureboot} \
"${@}" "${@}"
set +x set +x

View File

@ -68,9 +68,9 @@ else
lbunzip2 -k -f tmp/flatcar_production_image_first_dual.bin.bz2 lbunzip2 -k -f tmp/flatcar_production_image_first_dual.bin.bz2
fi fi
bios="${QEMU_BIOS}" bios="${QEMU_FIRMWARE}"
if [ "${CIA_ARCH}" = "arm64" ]; then if [ "${CIA_ARCH}" = "arm64" ]; then
bios="${QEMU_UEFI_BIOS}" bios="${QEMU_UEFI_FIRMWARE}"
if [ -f "${bios}" ] ; then if [ -f "${bios}" ] ; then
echo "++++ qemu_update.sh: Using existing ./${bios} ++++" echo "++++ qemu_update.sh: Using existing ./${bios} ++++"
else else
@ -114,7 +114,7 @@ run_kola_tests() {
--board="${CIA_ARCH}-usr" \ --board="${CIA_ARCH}-usr" \
--parallel="${QEMU_PARALLEL}" \ --parallel="${QEMU_PARALLEL}" \
--platform=qemu \ --platform=qemu \
--qemu-bios="${bios}" \ --qemu-firmware="${bios}" \
--qemu-image="${image}" \ --qemu-image="${image}" \
--tapfile="${instance_tapfile}" \ --tapfile="${instance_tapfile}" \
--update-payload="${QEMU_UPDATE_PAYLOAD}" \ --update-payload="${QEMU_UPDATE_PAYLOAD}" \

View File

@ -52,7 +52,8 @@ function set_vars() {
# The local directory ("pwd") will be mounted to /work/ in the container. # The local directory ("pwd") will be mounted to /work/ in the container.
cat > sdk_container/.env <<EOF cat > sdk_container/.env <<EOF
export QEMU_IMAGE_NAME=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_production_image.bin export QEMU_IMAGE_NAME=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_production_image.bin
export QEMU_UEFI_BIOS=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_production_qemu_uefi_efi_code.fd export QEMU_UEFI_FIRMWARE=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_production_qemu_uefi_efi_code.fd
export QEMU_UEFI_OVMF_VARS=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_production_qemu_uefi_efi_vars.fd
export QEMU_UPDATE_PAYLOAD=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_test_update.gz export QEMU_UPDATE_PAYLOAD=/work/__build__/images/images/${arch@Q}-usr/latest/flatcar_test_update.gz
export PARALLEL_TESTS=${parallel@Q} export PARALLEL_TESTS=${parallel@Q}
EOF EOF

View File

@ -422,6 +422,7 @@ CONFIG_LEDS_CLASS=y
CONFIG_LIBFC=m CONFIG_LIBFC=m
CONFIG_LIBFCOE=m CONFIG_LIBFCOE=m
# CONFIG_LOCALVERSION_AUTO is not set # CONFIG_LOCALVERSION_AUTO is not set
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_BUF_SHIFT=18
CONFIG_LOOPBACK_TARGET=m CONFIG_LOOPBACK_TARGET=m
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"

View File

@ -38,4 +38,8 @@ UNIPATCH_LIST="
${PATCH_DIR}/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch \ ${PATCH_DIR}/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch \
${PATCH_DIR}/z0002-revert-pahole-flags.patch \ ${PATCH_DIR}/z0002-revert-pahole-flags.patch \
${PATCH_DIR}/z0003-Revert-x86-boot-Remove-the-bugger-off-message.patch \ ${PATCH_DIR}/z0003-Revert-x86-boot-Remove-the-bugger-off-message.patch \
${PATCH_DIR}/z0004-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch \
${PATCH_DIR}/z0005-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch \
${PATCH_DIR}/z0006-mtd-phram-slram-Disable-when-the-kernel-is-locked-do.patch \
${PATCH_DIR}/z0007-arm64-add-kernel-config-option-to-lock-down-when-in-.patch \
" "

View File

@ -0,0 +1,166 @@
From 1e2ffbec195c89d887bc088691ebb19c9173ecad Mon Sep 17 00:00:00 2001
From: David Howells <dhowells@redhat.com>
Date: Mon, 18 Feb 2019 12:45:03 +0000
Subject: [PATCH 1/4] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
mode
UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT
flag that can be passed to efi_enabled() to find out whether secure boot is
enabled.
Move the switch-statement in x86's setup_arch() that inteprets the
secure_boot boot parameter to generic code and set the bit there.
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
cc: linux-efi@vger.kernel.org
[rperier: Forward-ported to 5.5:
- Use pr_warn()
- Adjust context]
[bwh: Forward-ported to 5.6: adjust context]
[bwh: Forward-ported to 5.7:
- Use the next available bit in efi.flags
- Adjust context]
---
arch/x86/kernel/setup.c | 14 +----------
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/secureboot.c | 39 +++++++++++++++++++++++++++++++
include/linux/efi.h | 17 ++++++++------
4 files changed, 51 insertions(+), 20 deletions(-)
create mode 100644 drivers/firmware/efi/secureboot.c
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index eb129277dcdd..7c4a6697e39d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1190,19 +1190,7 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);
- if (efi_enabled(EFI_BOOT)) {
- switch (boot_params.secure_boot) {
- case efi_secureboot_mode_disabled:
- pr_info("Secure boot disabled\n");
- break;
- case efi_secureboot_mode_enabled:
- pr_info("Secure boot enabled\n");
- break;
- default:
- pr_info("Secure boot could not be determined\n");
- break;
- }
- }
+ efi_set_secure_boot(boot_params.secure_boot);
reserve_initrd();
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index e489fefd23da..f2dfae764fb5 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -25,6 +25,7 @@ subdir-$(CONFIG_EFI_STUB) += libstub
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
obj-$(CONFIG_EFI_TEST) += test/
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
+obj-$(CONFIG_EFI) += secureboot.o
obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
new file mode 100644
index 000000000000..b6620669e32b
--- /dev/null
+++ b/drivers/firmware/efi/secureboot.c
@@ -0,0 +1,39 @@
+
+/* Core kernel secure boot support.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/*
+ * Decide what to do when UEFI secure boot mode is enabled.
+ */
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
+{
+ if (efi_enabled(EFI_BOOT)) {
+ switch (mode) {
+ case efi_secureboot_mode_disabled:
+ pr_info("Secure boot disabled\n");
+ break;
+ case efi_secureboot_mode_enabled:
+ set_bit(EFI_SECURE_BOOT, &efi.flags);
+ pr_info("Secure boot enabled\n");
+ break;
+ default:
+ pr_warn("Secure boot could not be determined (mode %u)\n",
+ mode);
+ break;
+ }
+ }
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 80b21d1c6eaf..d267ddba8369 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -871,6 +871,14 @@ extern int __init efi_setup_pcdp_console(char *);
#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */
#define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */
+#define EFI_SECURE_BOOT 13 /* Are we in Secure Boot mode? */
+
+enum efi_secureboot_mode {
+ efi_secureboot_mode_unset,
+ efi_secureboot_mode_unknown,
+ efi_secureboot_mode_disabled,
+ efi_secureboot_mode_enabled,
+};
#ifdef CONFIG_EFI
/*
@@ -895,6 +903,7 @@ static inline bool efi_rt_services_supported(unsigned int mask)
return (efi.runtime_supported_mask & mask) == mask;
}
extern void efi_find_mirror(void);
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
#else
static inline bool efi_enabled(int feature)
{
@@ -914,6 +923,7 @@ static inline bool efi_rt_services_supported(unsigned int mask)
}
static inline void efi_find_mirror(void) {}
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
#endif
extern int efi_status_to_err(efi_status_t status);
@@ -1133,13 +1143,6 @@ static inline bool efi_runtime_disabled(void) { return true; }
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
extern unsigned long efi_call_virt_save_flags(void);
-enum efi_secureboot_mode {
- efi_secureboot_mode_unset,
- efi_secureboot_mode_unknown,
- efi_secureboot_mode_disabled,
- efi_secureboot_mode_enabled,
-};
-
static inline
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
{
--
2.39.2

View File

@ -0,0 +1,135 @@
From fa96a2ef86466da0a43756ee39ce3b1cb555a55a Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Tue, 10 Sep 2019 11:54:28 +0100
Subject: [PATCH 2/4] efi: Lock down the kernel if booted in secure boot mode
Based on an earlier patch by David Howells, who wrote the following
description:
> 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: Ben Hutchings <ben@decadent.org.uk>
[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the
help text for LOCK_DOWN_IN_EFI_SECURE_BOOT was adjusted to mention that
lockdown is triggered in integrity mode (https://bugs.debian.org/1025417)]
Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
---
arch/x86/kernel/setup.c | 4 ++--
drivers/firmware/efi/secureboot.c | 5 +++++
include/linux/security.h | 6 ++++++
security/lockdown/Kconfig | 15 +++++++++++++++
security/lockdown/lockdown.c | 2 +-
5 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 7c4a6697e39d..04e73973098e 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1028,6 +1028,8 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled(EFI_BOOT))
efi_init();
+ efi_set_secure_boot(boot_params.secure_boot);
+
reserve_ibft_region();
x86_init.resources.dmi_setup();
@@ -1190,8 +1192,6 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);
- efi_set_secure_boot(boot_params.secure_boot);
-
reserve_initrd();
acpi_table_upgrade();
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
index b6620669e32b..8f2554291fb1 100644
--- a/drivers/firmware/efi/secureboot.c
+++ b/drivers/firmware/efi/secureboot.c
@@ -15,6 +15,7 @@
#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/printk.h>
+#include <linux/security.h>
/*
* Decide what to do when UEFI secure boot mode is enabled.
@@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
break;
case efi_secureboot_mode_enabled:
set_bit(EFI_SECURE_BOOT, &efi.flags);
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
+ lock_kernel_down("EFI Secure Boot",
+ LOCKDOWN_INTEGRITY_MAX);
+#endif
pr_info("Secure boot enabled\n");
break;
default:
diff --git a/include/linux/security.h b/include/linux/security.h
index 4bd0f6fc553e..08258ecbb5f9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -486,6 +486,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
int security_locked_down(enum lockdown_reason what);
+int lock_kernel_down(const char *where, enum lockdown_reason level);
#else /* CONFIG_SECURITY */
static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -1404,6 +1405,11 @@ static inline int security_locked_down(enum lockdown_reason what)
{
return 0;
}
+static inline int
+lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+ return -EOPNOTSUPP;
+}
#endif /* CONFIG_SECURITY */
#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
index e84ddf484010..4175b50b1e6e 100644
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY
disabled.
endchoice
+
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
+ bool "Lock down the kernel in EFI Secure Boot mode"
+ default n
+ depends on SECURITY_LOCKDOWN_LSM
+ depends on EFI
+ select SECURITY_LOCKDOWN_LSM_EARLY
+ help
+ UEFI Secure Boot provides a mechanism for ensuring that the firmware
+ will only load signed bootloaders and kernels. Secure boot mode may
+ be determined from EFI variables provided by the system firmware if
+ not indicated by the boot parameters.
+
+ Enabling this option results in kernel lockdown being
+ triggered in integrity mode if EFI Secure Boot is set.
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 68d19632aeb7..67cc9839952f 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -23,7 +23,7 @@ static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
/*
* Put the kernel into lock-down mode.
*/
-static int lock_kernel_down(const char *where, enum lockdown_reason level)
+int lock_kernel_down(const char *where, enum lockdown_reason level)
{
if (kernel_locked_down >= level)
return -EPERM;
--
2.39.2

View File

@ -0,0 +1,82 @@
From bb8912cf807feab56cf8e924d33229d800ae71a6 Mon Sep 17 00:00:00 2001
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 30 Aug 2019 15:54:24 +0100
Subject: [PATCH 3/4] mtd: phram,slram: Disable when the kernel is locked down
These drivers allow mapping arbitrary memory ranges as MTD devices.
This should be disabled to preserve the kernel's integrity when it is
locked down.
* Add the HWPARAM flag to the module parameters
* When slram is built-in, it uses __setup() to read kernel parameters,
so add an explicit check security_locked_down() check
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Cc: Matthew Garrett <mjg59@google.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Joern Engel <joern@lazybastard.org>
Cc: linux-mtd@lists.infradead.org
---
drivers/mtd/devices/phram.c | 6 +++++-
drivers/mtd/devices/slram.c | 9 ++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 208bd4d871f4..30f84a91692d 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -364,7 +364,11 @@ static int phram_param_call(const char *val, const struct kernel_param *kp)
#endif
}
-module_param_call(phram, phram_param_call, NULL, NULL, 0200);
+static const struct kernel_param_ops phram_param_ops = {
+ .set = phram_param_call
+};
+__module_param_call(MODULE_PARAM_PREFIX, phram, &phram_param_ops, NULL,
+ 0200, -1, KERNEL_PARAM_FL_HWPARAM | hwparam_iomem);
MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>[,<erasesize>]\"");
#ifdef CONFIG_OF
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 28131a127d06..d92a2461e2ce 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -43,6 +43,7 @@
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/security.h>
#include <linux/mtd/mtd.h>
@@ -65,7 +66,7 @@ typedef struct slram_mtd_list {
#ifdef MODULE
static char *map[SLRAM_MAX_DEVICES_PARAMS];
-module_param_array(map, charp, NULL, 0);
+module_param_hw_array(map, charp, iomem, NULL, 0);
MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\"");
#else
static char *map;
@@ -281,11 +282,17 @@ static int __init init_slram(void)
#ifndef MODULE
char *devstart;
char *devlength;
+ int ret;
if (!map) {
E("slram: not enough parameters.\n");
return(-EINVAL);
}
+
+ ret = security_locked_down(LOCKDOWN_MODULE_PARAMETERS);
+ if (ret)
+ return ret;
+
while (map) {
devname = devstart = devlength = NULL;
--
2.39.2

View File

@ -0,0 +1,164 @@
From 8598238a38a333fed5ec0c8287f99813578370ab Mon Sep 17 00:00:00 2001
From: Linn Crosetto <linn@hpe.com>
Date: Tue, 30 Aug 2016 11:54:38 -0600
Subject: [PATCH 4/4] arm64: add kernel config option to lock down when in
Secure Boot mode
Add a kernel configuration option to lock down the kernel, to restrict
userspace's ability to modify the running kernel when UEFI Secure Boot is
enabled. Based on the x86 patch by Matthew Garrett.
Determine the state of Secure Boot in the EFI stub and pass this to the
kernel using the FDT.
Signed-off-by: Linn Crosetto <linn@hpe.com>
[bwh: Forward-ported to 4.10: adjust context]
[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream]
[bwh: Forward-ported to 4.15 and lockdown patch set:
- Pass result of efi_get_secureboot() in stub through to
efi_set_secure_boot() in main kernel
- Use lockdown API and naming]
[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()]
[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection]
[bwh: Drop call to init_lockdown(), as efi_set_secure_boot() now calls this]
[bwh: Forward-ported to 5.6: efi_get_secureboot() no longer takes a
sys_table parameter]
[bwh: Forward-ported to 5.7: EFI initialisation from FDT was rewritten, so:
- Add Secure Boot mode to the parameter enumeration in fdtparams.c
- Add a parameter to efi_get_fdt_params() to return the Secure Boot mode
- Since Xen does not have a property name defined for Secure Boot mode,
change efi_get_fdt_prop() to handle a missing property name by clearing
the output variable]
[Salvatore Bonaccorso: Forward-ported to 5.10: f30f242fb131 ("efi: Rename
arm-init to efi-init common for all arch") renamed arm-init.c to efi-init.c]
---
drivers/firmware/efi/efi-init.c | 5 ++++-
drivers/firmware/efi/fdtparams.c | 12 +++++++++++-
drivers/firmware/efi/libstub/fdt.c | 6 ++++++
include/linux/efi.h | 3 ++-
4 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index 59b0d7197b68..e63f8a82d9f4 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -204,9 +204,10 @@ void __init efi_init(void)
{
struct efi_memory_map_data data;
u64 efi_system_table;
+ u32 secure_boot;
/* Grab UEFI information placed in FDT by stub */
- efi_system_table = efi_get_fdt_params(&data);
+ efi_system_table = efi_get_fdt_params(&data, &secure_boot);
if (!efi_system_table)
return;
@@ -228,6 +229,8 @@ void __init efi_init(void)
return;
}
+ efi_set_secure_boot(secure_boot);
+
reserve_regions();
/*
* For memblock manipulation, the cap should come after the memblock_add().
diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c
index 0ec83ba58097..81a0ac408cf5 100644
--- a/drivers/firmware/efi/fdtparams.c
+++ b/drivers/firmware/efi/fdtparams.c
@@ -16,6 +16,7 @@ enum {
MMSIZE,
DCSIZE,
DCVERS,
+ SBMODE,
PARAMCOUNT
};
@@ -26,6 +27,7 @@ static __initconst const char name[][22] = {
[MMSIZE] = "MemMap Size ",
[DCSIZE] = "MemMap Desc. Size ",
[DCVERS] = "MemMap Desc. Version ",
+ [SBMODE] = "Secure Boot Enabled ",
};
static __initconst const struct {
@@ -43,6 +45,7 @@ static __initconst const struct {
[MMSIZE] = "xen,uefi-mmap-size",
[DCSIZE] = "xen,uefi-mmap-desc-size",
[DCVERS] = "xen,uefi-mmap-desc-ver",
+ [SBMODE] = "",
}
}, {
#endif
@@ -53,6 +56,7 @@ static __initconst const struct {
[MMSIZE] = "linux,uefi-mmap-size",
[DCSIZE] = "linux,uefi-mmap-desc-size",
[DCVERS] = "linux,uefi-mmap-desc-ver",
+ [SBMODE] = "linux,uefi-secure-boot",
}
}
};
@@ -64,6 +68,11 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname,
int len;
u64 val;
+ if (!pname[0]) {
+ memset(var, 0, size);
+ return 0;
+ }
+
prop = fdt_getprop(fdt, node, pname, &len);
if (!prop)
return 1;
@@ -81,7 +90,7 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname,
return 0;
}
-u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm)
+u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm, u32 *secure_boot)
{
const void *fdt = initial_boot_params;
unsigned long systab;
@@ -95,6 +104,7 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm)
[MMSIZE] = { &mm->size, sizeof(mm->size) },
[DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) },
[DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) },
+ [SBMODE] = { secure_boot, sizeof(*secure_boot) },
};
BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name));
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 6a337f1f8787..6c679da644dd 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -132,6 +132,12 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
}
}
+ fdt_val32 = cpu_to_fdt32(efi_get_secureboot());
+ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot",
+ &fdt_val32, sizeof(fdt_val32));
+ if (status)
+ goto fdt_set_fail;
+
/* Shrink the FDT back to its minimum size: */
fdt_pack(fdt);
diff --git a/include/linux/efi.h b/include/linux/efi.h
index d267ddba8369..fbce526768d3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -756,7 +756,8 @@ extern void efi_mem_reserve(phys_addr_t addr, u64 size);
extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
extern void efi_initialize_iomem_resources(struct resource *code_resource,
struct resource *data_resource, struct resource *bss_resource);
-extern u64 efi_get_fdt_params(struct efi_memory_map_data *data);
+extern u64 efi_get_fdt_params(struct efi_memory_map_data *data,
+ u32 *secure_boot);
extern struct kobject *efi_kobj;
extern int efi_reboot_quirk_mode;
--
2.39.2