Skip to content

Commit

Permalink
Merge pull request #2299 from flatcar/jepio+sayan/sboot-lockdown
Browse files Browse the repository at this point in the history
secure boot: lockdown, grub fallback, CI
  • Loading branch information
jepio authored Sep 17, 2024
2 parents ea395fe + fd54cca commit a23e5bb
Show file tree
Hide file tree
Showing 13 changed files with 594 additions and 20 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/run-kola-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
# Extract the generic image we'll use for qemu tests.
# Note that the qemu[_uefi] tests use the generic image instead of the
# 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/
Expand Down Expand Up @@ -197,7 +197,8 @@ jobs:
cat > sdk_container/.env <<EOF
# export the QEMU_IMAGE_NAME to avoid to download it.
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_DEVCONTAINER_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}"
export QEMU_DEVCONTAINER_BINHOST_URL="http://${TESTS_WEBSERVER_IP}:${TESTS_WEBSERVER_PORT}"
Expand Down
3 changes: 3 additions & 0 deletions build_library/grub.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ insmod all_video

# Default menuentry id and boot timeout
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

# Default kernel args for root filesystem, console, and Flatcar.
Expand Down
1 change: 1 addition & 0 deletions changelog/changes/2024-09-10-kernel-lockdown.md
Original file line number Diff line number Diff line change
@@ -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))
12 changes: 7 additions & 5 deletions ci-automation/ci-config.env
Original file line number Diff line number Diff line change
Expand Up @@ -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
QEMU_KOLA_SKIP_MANGLE="${QEMU_KOLA_SKIP_MANGLE:-}"

# BIOS path within the SDK
QEMU_BIOS="/usr/share/qemu/bios-256k.bin"
# Firmware path within the SDK
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.
QEMU_UEFI_BIOS="${QEMU_UEFI_BIOS:-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_FIRMWARE="${QEMU_UEFI_FIRMWARE:-flatcar_production_qemu_uefi_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.
# The default path set below is relative to TEST_WORK_DIR
Expand Down
32 changes: 23 additions & 9 deletions ci-automation/vendor-testing/qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ set -euo pipefail

source ci-automation/vendor_test.sh

SECUREBOOT=""
ovmf_vars=""

# ARM64 qemu tests only supported on UEFI
if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; then
echo "1..1" > "${CIA_TAPFILE}"
Expand All @@ -21,7 +24,7 @@ if [ "${CIA_ARCH}" = "arm64" ] && [ "${CIA_TESTSCRIPT}" != "qemu_uefi.sh" ] ; th
exit 1
fi

# Fetch image and BIOS if not present
# Fetch image and firmware if not present
if [ -f "${QEMU_IMAGE_NAME}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${QEMU_IMAGE_NAME} for testing ${CIA_VERNUM} (${CIA_ARCH}) ++++"
else
Expand All @@ -31,21 +34,30 @@ else
lbunzip2 "${QEMU_IMAGE_NAME}.bz2"
fi

bios="${QEMU_BIOS}"
firmware="${QEMU_FIRMWARE}"
if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] ; then
bios="${QEMU_UEFI_BIOS}"
firmware="${QEMU_UEFI_FIRMWARE}"
ovmf_vars="${QEMU_UEFI_OVMF_VARS}"
fi

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

if [ "${CIA_TESTSCRIPT}" = "qemu_uefi.sh" ] || [ "${CIA_TESTSCRIPT}" = "qemu_uefi_secure.sh" ] ; then
if [ -f "${bios}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${bios} ++++"
if [ -f "${firmware}" ] ; then
echo "++++ ${CIA_TESTSCRIPT}: Using existing ${firmware} ++++"
else
echo "++++ ${CIA_TESTSCRIPT}: downloading ${firmware} for ${CIA_VERNUM} (${CIA_ARCH}) ++++"
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 ${bios} for ${CIA_VERNUM} (${CIA_ARCH}) ++++"
copy_from_buildcache "images/${CIA_ARCH}/${CIA_VERNUM}/${bios}" .
echo "++++ ${CIA_TESTSCRIPT}: downloading ${ovmf_vars} for ${CIA_VERNUM} (${CIA_ARCH}) ++++"
copy_from_buildcache "images/${CIA_ARCH}/${CIA_VERNUM}/${ovmf_vars}" .
fi
fi

Expand All @@ -68,11 +80,13 @@ kola run \
--board="${CIA_ARCH}-usr" \
--parallel="${QEMU_PARALLEL}" \
--platform=qemu \
--qemu-bios="${bios}" \
--qemu-firmware="${firmware}" \
--qemu-image="${QEMU_IMAGE_NAME}" \
--tapfile="${CIA_TAPFILE}" \
"${ovmf_vars:+--qemu-ovmf-vars=${ovmf_vars}}" \
${QEMU_KOLA_SKIP_MANGLE:+--qemu-skip-mangle} \
"${devcontainer_opts[@]}" \
${SECUREBOOT:+--enable-secureboot} \
"${@}"

set +x
6 changes: 3 additions & 3 deletions ci-automation/vendor-testing/qemu_update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ else
lbunzip2 -k -f tmp/flatcar_production_image_first_dual.bin.bz2
fi

bios="${QEMU_BIOS}"
bios="${QEMU_FIRMWARE}"
if [ "${CIA_ARCH}" = "arm64" ]; then
bios="${QEMU_UEFI_BIOS}"
bios="${QEMU_UEFI_FIRMWARE}"
if [ -f "${bios}" ] ; then
echo "++++ qemu_update.sh: Using existing ./${bios} ++++"
else
Expand Down Expand Up @@ -114,7 +114,7 @@ run_kola_tests() {
--board="${CIA_ARCH}-usr" \
--parallel="${QEMU_PARALLEL}" \
--platform=qemu \
--qemu-bios="${bios}" \
--qemu-firmware="${bios}" \
--qemu-image="${image}" \
--tapfile="${instance_tapfile}" \
--update-payload="${QEMU_UPDATE_PAYLOAD}" \
Expand Down
3 changes: 2 additions & 1 deletion run_local_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ function set_vars() {
# The local directory ("pwd") will be mounted to /work/ in the container.
cat > sdk_container/.env <<EOF
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 PARALLEL_TESTS=${parallel@Q}
EOF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ CONFIG_LEDS_CLASS=y
CONFIG_LIBFC=m
CONFIG_LIBFCOE=m
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
CONFIG_LOG_BUF_SHIFT=18
CONFIG_LOOPBACK_TARGET=m
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,8 @@ UNIPATCH_LIST="
${PATCH_DIR}/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch \
${PATCH_DIR}/z0002-revert-pahole-flags.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 \
"
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
From 1e2ffbec195c89d887bc088691ebb19c9173ecad Mon Sep 17 00:00:00 2001
From: David Howells <[email protected]>
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 <[email protected]>
Signed-off-by: David Howells <[email protected]>
Reviewed-by: Ard Biesheuvel <[email protected]>
cc: [email protected]
[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 ([email protected])
+ *
+ * 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

Loading

0 comments on commit a23e5bb

Please sign in to comment.