Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secure boot: lockdown, grub fallback, CI #2299

Merged
merged 6 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation seems off?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, fixed it

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
ader1990 marked this conversation as resolved.
Show resolved Hide resolved
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