diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index f1fea506e20f4..93844a247d881 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -904,6 +904,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(); @@ -1070,20 +1072,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(); diff --git a/ciq/configs/kernel-aarch64-64k-debug.config b/ciq/configs/kernel-aarch64-64k-debug.config index 66f6cd31c9fe1..cb58edf2e1d2d 100644 --- a/ciq/configs/kernel-aarch64-64k-debug.config +++ b/ciq/configs/kernel-aarch64-64k-debug.config @@ -7830,7 +7830,7 @@ CONFIG_SECURITY_YAMA=y # CONFIG_SECURITY_SAFESETID is not set CONFIG_SECURITY_LOCKDOWN_LSM=y CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y -# CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set diff --git a/ciq/configs/kernel-aarch64-64k.config b/ciq/configs/kernel-aarch64-64k.config index 510ac7f3ec2de..20b7f57192be0 100644 --- a/ciq/configs/kernel-aarch64-64k.config +++ b/ciq/configs/kernel-aarch64-64k.config @@ -7808,7 +7808,7 @@ CONFIG_SECURITY_YAMA=y # CONFIG_SECURITY_SAFESETID is not set CONFIG_SECURITY_LOCKDOWN_LSM=y CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y -# CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set diff --git a/ciq/configs/kernel-aarch64-debug.config b/ciq/configs/kernel-aarch64-debug.config index 01b45d0f644ed..ce889082816c6 100644 --- a/ciq/configs/kernel-aarch64-debug.config +++ b/ciq/configs/kernel-aarch64-debug.config @@ -7836,7 +7836,7 @@ CONFIG_SECURITY_YAMA=y # CONFIG_SECURITY_SAFESETID is not set CONFIG_SECURITY_LOCKDOWN_LSM=y CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y -# CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set diff --git a/ciq/configs/kernel-aarch64.config b/ciq/configs/kernel-aarch64.config index 0717c6f46142b..ee3db9ed518c4 100644 --- a/ciq/configs/kernel-aarch64.config +++ b/ciq/configs/kernel-aarch64.config @@ -7814,7 +7814,7 @@ CONFIG_SECURITY_YAMA=y # CONFIG_SECURITY_SAFESETID is not set CONFIG_SECURITY_LOCKDOWN_LSM=y CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y -# CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index a2d0009560d0f..4f3486e6a84b2 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/efi-init.c b/drivers/firmware/efi/efi-init.c index a00e07b853f22..8a0390d8da987 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -213,9 +213,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; @@ -237,6 +238,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/efi.c b/drivers/firmware/efi/efi.c index 70490bf2697b1..2973cce74abdf 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -993,40 +994,101 @@ int efi_mem_type(unsigned long phys_addr) return -EINVAL; } +struct efi_error_code { + efi_status_t status; + int errno; + const char *description; +}; + +static const struct efi_error_code efi_error_codes[] = { + { EFI_SUCCESS, 0, "Success"}, +#if 0 + { EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"}, +#endif + { EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"}, + { EFI_UNSUPPORTED, -ENOSYS, "Unsupported"}, + { EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"}, + { EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"}, + { EFI_NOT_READY, -EAGAIN, "Not Ready"}, + { EFI_DEVICE_ERROR, -EIO, "Device Error"}, + { EFI_WRITE_PROTECTED, -EROFS, "Write Protected"}, + { EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"}, +#if 0 + { EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"}, + { EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"}, + { EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"}, + { EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"}, +#endif + { EFI_NOT_FOUND, -ENOENT, "Not Found"}, +#if 0 + { EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"}, + { EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"}, + { EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"}, + { EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"}, + { EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"}, + { EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"}, +#endif + { EFI_ABORTED, -EINTR, "Aborted"}, +#if 0 + { EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"}, + { EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"}, + { EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"}, + { EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"}, +#endif + { EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"}, +#if 0 + { EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"}, + { EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"}, + { EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"}, + { EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"}, + { EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"}, + + // warnings + { EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"}, + { EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"}, + { EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"}, + { EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"}, +#endif +}; + +static int +efi_status_cmp_bsearch(const void *key, const void *item) +{ + u64 status = (u64)(uintptr_t)key; + struct efi_error_code *code = (struct efi_error_code *)item; + + if (status < code->status) + return -1; + if (status > code->status) + return 1; + return 0; +} + int efi_status_to_err(efi_status_t status) { - int err; - - switch (status) { - case EFI_SUCCESS: - err = 0; - break; - case EFI_INVALID_PARAMETER: - err = -EINVAL; - break; - case EFI_OUT_OF_RESOURCES: - err = -ENOSPC; - break; - case EFI_DEVICE_ERROR: - err = -EIO; - break; - case EFI_WRITE_PROTECTED: - err = -EROFS; - break; - case EFI_SECURITY_VIOLATION: - err = -EACCES; - break; - case EFI_NOT_FOUND: - err = -ENOENT; - break; - case EFI_ABORTED: - err = -EINTR; - break; - default: - err = -EINVAL; - } + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - return err; + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return -EINVAL; + return found->errno; +} + +const char * +efi_status_to_str(efi_status_t status) +{ + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); + + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return "Unknown error code"; + return found->description; } EXPORT_SYMBOL_GPL(efi_status_to_err); diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index b815d2a754eef..69a2eb539d38a 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 6a337f1f8787b..6c679da644dd6 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/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c new file mode 100644 index 0000000000000..8f2554291fb1f --- /dev/null +++ b/drivers/firmware/efi/secureboot.c @@ -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 +#include +#include +#include + +/* + * 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; + } + } +} diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 1bf192f229d71..5b791c4e4e6df 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=,,[,]\""); #ifdef CONFIG_OF diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8297b366a0669..9f762d988c0bc 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -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=, , \""); #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; diff --git a/include/linux/efi.h b/include/linux/efi.h index e28d880660337..de58dc09a85e8 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -45,6 +45,8 @@ struct screen_info; #define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1))) #define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1))) +#define EFI_IS_ERROR(x) ((x) & (1UL << (BITS_PER_LONG-1))) + typedef unsigned long efi_status_t; typedef u8 efi_bool_t; typedef u16 efi_char16_t; /* UNICODE character */ @@ -764,7 +766,8 @@ extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md); extern int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md); extern void efi_mem_reserve(phys_addr_t addr, u64 size); extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size); -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; @@ -875,6 +878,14 @@ static inline int efi_range_is_wc(unsigned long start, unsigned long len) #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 /* @@ -899,6 +910,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) { @@ -918,9 +930,11 @@ 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); +extern const char *efi_status_to_str(efi_status_t status); /* * Variable Attributes @@ -1136,13 +1150,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) { diff --git a/include/linux/security.h b/include/linux/security.h index 2ec8f3014757c..46bb1a2d5b347 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -522,6 +522,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); int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags); int security_bdev_alloc(struct block_device *bdev); @@ -1504,6 +1505,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; +} static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, void *val, size_t val_len, u64 id, u64 flags) diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig index e84ddf4840101..4175b50b1e6e1 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 f2bdbd55aa2bc..f043e70851cf4 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -24,7 +24,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;