Skip to content

Commit

Permalink
Merge feature/secure-boot-lockdown/6.6 into v6.6.47
Browse files Browse the repository at this point in the history
* commit '8bbb6780deb56560af81a3bacd59aaf48714240e':
  mtd: phram,slram: Disable when the kernel is locked down
  efi: Lock down the kernel if booted in secure boot mode
  efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
  arm64: add kernel config option to lock down when in Secure Boot mode
  • Loading branch information
allenpais committed Aug 22, 2024
2 parents 829847d + 8bbb678 commit 5af5f7a
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 27 deletions.
16 changes: 2 additions & 14 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -1190,20 +1192,6 @@ 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;
}
}

reserve_initrd();

acpi_table_upgrade();
Expand Down
1 change: 1 addition & 0 deletions drivers/firmware/efi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion drivers/firmware/efi/efi-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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().
Expand Down
12 changes: 11 additions & 1 deletion drivers/firmware/efi/fdtparams.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum {
MMSIZE,
DCSIZE,
DCVERS,
SBMODE,

PARAMCOUNT
};
Expand All @@ -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 {
Expand All @@ -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
Expand All @@ -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",
}
}
};
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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));
Expand Down
6 changes: 6 additions & 0 deletions drivers/firmware/efi/libstub/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
44 changes: 44 additions & 0 deletions drivers/firmware/efi/secureboot.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

/* 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>
#include <linux/security.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);
#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:
pr_warn("Secure boot could not be determined (mode %u)\n",
mode);
break;
}
}
}
6 changes: 5 additions & 1 deletion drivers/mtd/devices/phram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion drivers/mtd/devices/slram.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
20 changes: 12 additions & 8 deletions include/linux/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -871,6 +872,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
/*
Expand All @@ -895,6 +904,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)
{
Expand All @@ -914,6 +924,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);
Expand Down Expand Up @@ -1133,13 +1144,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)
{
Expand Down
9 changes: 9 additions & 0 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ void security_bdev_free(struct block_device *bdev);
int security_bdev_setintegrity(struct block_device *bdev,
enum lsm_integrity_type type, const void *value,
size_t size);
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)
Expand Down Expand Up @@ -1439,6 +1440,7 @@ static inline int security_locked_down(enum lockdown_reason what)
{
return 0;
}
<<<<<<< HEAD

static inline int security_bdev_alloc(struct block_device *bdev)
{
Expand All @@ -1456,6 +1458,13 @@ static inline int security_bdev_setintegrity(struct block_device *bdev,
return 0;
}

=======
static inline int
lock_kernel_down(const char *where, enum lockdown_reason level)
{
return -EOPNOTSUPP;
}
>>>>>>> efi: Lock down the kernel if booted in secure boot mode
#endif /* CONFIG_SECURITY */

#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
Expand Down
15 changes: 15 additions & 0 deletions security/lockdown/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion security/lockdown/lockdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 5af5f7a

Please sign in to comment.