Skip to content
This repository was archived by the owner on Sep 24, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3aba70b
efi: Add EFI_SECURE_BOOT bit
Nov 21, 2016
b4a3a20
Add the ability to lock down access to the running kernel image
dhowells Nov 21, 2016
8aebfe3
efi: Lock down the kernel if booted in secure boot mode
dhowells Nov 21, 2016
c0e5d82
Enforce module signatures if the kernel is locked down
dhowells Nov 23, 2016
77e6c38
Restrict /dev/mem and /dev/kmem when the kernel is locked down
Nov 22, 2016
91141d1
kexec: Disable at runtime if the kernel is locked down
Nov 22, 2016
1d15fbf
Copy secure_boot flag in boot params across kexec reboot
daveyoung Nov 22, 2016
892424e
kexec_file: Disable at runtime if securelevel has been set
Nov 23, 2016
1e6be78
hibernate: Disable when the kernel is locked down
Nov 22, 2016
8f81c0c
uswsusp: Disable when the kernel is locked down
mjg59 Nov 23, 2016
49587ab
PCI: Lock down BAR access when the kernel is locked down
Nov 22, 2016
655e161
x86: Lock down IO port access when the kernel is locked down
Nov 22, 2016
c0a701d
x86: Restrict MSR access when the kernel is locked down
Nov 22, 2016
39393da
asus-wmi: Restrict debugfs interface when the kernel is locked down
Nov 22, 2016
637a86e
ACPI: Limit access to custom_method when the kernel is locked down
Nov 22, 2016
da05ae0
acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down
jwboyer Nov 22, 2016
bfa92c8
acpi: Disable ACPI table override if the kernel is locked down
Nov 23, 2016
92945af
acpi: Disable APEI error injection if the kernel is locked down
Nov 23, 2016
5ee4118
bpf: Restrict kernel image access functions when the kernel is locked…
joeyli Nov 23, 2016
05b3bf7
scsi: Lock down the eata driver
dhowells Nov 22, 2016
4e8f5c1
Prohibit PCMCIA CIS storage when the kernel is locked down
dhowells Nov 25, 2016
e92b61c
Lock down TIOCSSERIAL
dhowells Dec 7, 2016
7138866
kbuild: derive relative path for KBUILD_SRC from CURDIR
Nov 25, 2015
d5044e5
Add arm64 coreos verity hash
glevand Nov 12, 2016
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make

# Invoke a second make in the output directory, passing relevant variables
sub-make:
$(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
$(Q)$(MAKE) -C $(KBUILD_OUTPUT) \
KBUILD_SRC=$(shell realpath --relative-to=$(KBUILD_OUTPUT) $(CURDIR)) \
-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))

# Leave processing to above invocation of make
Expand Down
5 changes: 5 additions & 0 deletions arch/arm64/kernel/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ section_table:

.set section_count, (. - section_table) / 40

/* CoreOS 64 byte verity hash value. */
.org _head + 512
.ascii "verity-hash"
.org _head + 512 + 64

#ifdef CONFIG_DEBUG_EFI
/*
* The debug table is referenced via its Relative Virtual Address (RVA),
Expand Down
12 changes: 12 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,18 @@ config EFI_MIXED

If unsure, say N.

config EFI_SECURE_BOOT_LOCK_DOWN
def_bool n
depends on EFI
prompt "Lock down the kernel when UEFI Secure Boot is enabled"
---help---
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 and that
userspace is prevented from directly changing the running kernel
image. Say Y here to automatically lock down the kernel when a
system boots with UEFI Secure Boot enabled.

config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/ioport.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)

if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
return -EINVAL;
if (turn_on && !capable(CAP_SYS_RAWIO))
if (turn_on && (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down()))
return -EPERM;

/*
Expand Down Expand Up @@ -120,7 +120,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
return -EINVAL;
/* Trying to gain more privileges? */
if (level > old) {
if (!capable(CAP_SYS_RAWIO))
if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
return -EPERM;
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/kexec-bzimage64.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
if (efi_enabled(EFI_OLD_MEMMAP))
return 0;

params->secure_boot = boot_params.secure_boot;
ei->efi_loader_signature = current_ei->efi_loader_signature;
ei->efi_systab = current_ei->efi_systab;
ei->efi_systab_hi = current_ei->efi_systab_hi;
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/kernel/msr.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
int err = 0;
ssize_t bytes = 0;

if (kernel_is_locked_down())
return -EPERM;

if (count % 8)
return -EINVAL; /* Invalid chunk size */

Expand Down Expand Up @@ -131,6 +134,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
err = -EBADF;
break;
}
if (kernel_is_locked_down()) {
err = -EPERM;
break;
}
if (copy_from_user(&regs, uregs, sizeof regs)) {
err = -EFAULT;
break;
Expand Down
9 changes: 8 additions & 1 deletion arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include <linux/crash_dump.h>
#include <linux/tboot.h>
#include <linux/jiffies.h>
#include <linux/security.h>

#include <linux/usb/xhci-dbgp.h>
#include <video/edid.h>
Expand Down Expand Up @@ -1190,7 +1191,13 @@ void __init setup_arch(char **cmdline_p)
pr_info("Secure boot disabled\n");
break;
case efi_secureboot_mode_enabled:
pr_info("Secure boot enabled\n");
set_bit(EFI_SECURE_BOOT, &efi.flags);
if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
lock_kernel_down();
pr_info("Secure boot enabled and kernel locked down\n");
} else {
pr_info("Secure boot enabled\n");
}
break;
default:
pr_info("Secure boot could not be determined\n");
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/apei/einj.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
int rc;
u64 base_addr, size;

if (kernel_is_locked_down())
return -EPERM;

/* If user manually set "flags", make sure it is legal */
if (flags && (flags &
~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/custom_method.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
struct acpi_table_header table;
acpi_status status;

if (kernel_is_locked_down())
return -EPERM;

if (!(*ppos)) {
/* parse the table header to get the table length */
if (count <= sizeof(struct acpi_table_header))
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
acpi_physical_address pa = 0;

#ifdef CONFIG_KEXEC
if (acpi_rsdp)
if (acpi_rsdp && !kernel_is_locked_down())
return acpi_rsdp;
#endif

Expand Down
5 changes: 5 additions & 0 deletions drivers/acpi/tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ void __init acpi_table_upgrade(void)
if (table_nr == 0)
return;

if (kernel_is_locked_down()) {
pr_notice("kernel is locked down, ignoring table override\n");
return;
}

acpi_tables_addr =
memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
all_tables_size, PAGE_SIZE);
Expand Down
8 changes: 8 additions & 0 deletions drivers/char/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
if (p != *ppos)
return -EFBIG;

if (kernel_is_locked_down())
return -EPERM;

if (!valid_phys_addr_range(p, count))
return -EFAULT;

Expand Down Expand Up @@ -540,6 +543,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
int err = 0;

if (kernel_is_locked_down())
return -EPERM;

if (p < (unsigned long) high_memory) {
unsigned long to_write = min_t(unsigned long, count,
(unsigned long)high_memory - p);
Expand Down Expand Up @@ -762,6 +768,8 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)

static int open_port(struct inode *inode, struct file *filp)
{
if (kernel_is_locked_down())
return -EPERM;
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}

Expand Down
9 changes: 9 additions & 0 deletions drivers/pci/pci-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
loff_t init_off = off;
u8 *data = (u8 *) buf;

if (kernel_is_locked_down())
return -EPERM;

if (off > dev->cfg_size)
return 0;
if (off + count > dev->cfg_size) {
Expand Down Expand Up @@ -1182,6 +1185,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
enum pci_mmap_state mmap_type;
struct resource *res = &pdev->resource[bar];

if (kernel_is_locked_down())
return -EPERM;

if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
return -EINVAL;

Expand Down Expand Up @@ -1265,6 +1271,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
if (kernel_is_locked_down())
return -EPERM;

return pci_resource_io(filp, kobj, attr, buf, off, count, true);
}

Expand Down
8 changes: 7 additions & 1 deletion drivers/pci/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
int size = dev->cfg_size;
int cnt;

if (kernel_is_locked_down())
return -EPERM;

if (pos >= size)
return 0;
if (nbytes >= size)
Expand Down Expand Up @@ -195,6 +198,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
#endif /* HAVE_PCI_MMAP */
int ret = 0;

if (kernel_is_locked_down())
return -EPERM;

switch (cmd) {
case PCIIOC_CONTROLLER:
ret = pci_domain_nr(dev->bus);
Expand Down Expand Up @@ -236,7 +242,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
struct pci_filp_private *fpriv = file->private_data;
int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;

if (!capable(CAP_SYS_RAWIO))
if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
return -EPERM;

if (fpriv->mmap_state == pci_mmap_io) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/pci/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
u32 dword;
int err = 0;

if (!capable(CAP_SYS_ADMIN))
if (!capable(CAP_SYS_ADMIN) || kernel_is_locked_down())
return -EPERM;

dev = pci_get_bus_and_slot(bus, dfn);
Expand Down
5 changes: 5 additions & 0 deletions drivers/pcmcia/cistpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,11 @@ static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
struct pcmcia_socket *s;
int error;

if (kernel_is_locked_down()) {
pr_err("Direct CIS storage isn't permitted when the kernel is locked down\n");
return -EPERM;
}

s = to_socket(container_of(kobj, struct device, kobj));

if (off)
Expand Down
9 changes: 9 additions & 0 deletions drivers/platform/x86/asus-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,9 @@ static int show_dsts(struct seq_file *m, void *data)
int err;
u32 retval = -1;

if (kernel_is_locked_down())
return -EPERM;

err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);

if (err < 0)
Expand All @@ -1921,6 +1924,9 @@ static int show_devs(struct seq_file *m, void *data)
int err;
u32 retval = -1;

if (kernel_is_locked_down())
return -EPERM;

err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
&retval);

Expand All @@ -1945,6 +1951,9 @@ static int show_call(struct seq_file *m, void *data)
union acpi_object *obj;
acpi_status status;

if (kernel_is_locked_down())
return -EPERM;

status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
1, asus->debug.method_id,
&input, &output);
Expand Down
7 changes: 6 additions & 1 deletion drivers/scsi/eata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1552,8 +1552,13 @@ static int eata2x_detect(struct scsi_host_template *tpnt)

tpnt->proc_name = "eata2x";

if (strlen(boot_options))
if (strlen(boot_options)) {
if (kernel_is_locked_down()) {
pr_err("Command line-specified device addresses, irqs and dma channels are not permitted when the kernel is locked down\n");
return -EPERM;
}
option_setup(boot_options);
}

#if defined(MODULE)
/* io_port could have been modified when loading as a module */
Expand Down
6 changes: 6 additions & 0 deletions drivers/tty/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,12 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
new_flags = new_info->flags;
old_custom_divisor = uport->custom_divisor;

if ((change_port || change_irq) && kernel_is_locked_down()) {
pr_err("Using TIOCSSERIAL to change device addresses, irqs and dma channels is not permitted when the kernel is locked down\n");
retval = -EPERM;
goto exit;
}

if (!capable(CAP_SYS_ADMIN)) {
retval = -EPERM;
if (change_irq || change_port ||
Expand Down
1 change: 1 addition & 0 deletions include/linux/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,7 @@ extern int __init efi_setup_pcdp_console(char *);
#define EFI_DBG 8 /* Print additional debug info at runtime */
#define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */
#define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
#define EFI_SECURE_BOOT 11 /* Are we in Secure Boot mode? */

#ifdef CONFIG_EFI
/*
Expand Down
9 changes: 9 additions & 0 deletions include/linux/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,15 @@ extern int oops_may_print(void);
void do_exit(long error_code) __noreturn;
void complete_and_exit(struct completion *, long) __noreturn;

#ifdef CONFIG_LOCK_DOWN_KERNEL
extern bool kernel_is_locked_down(void);
#else
static inline bool kernel_is_locked_down(void)
{
return false;
}
#endif

/* Internal, do not use. */
int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
int __must_check _kstrtol(const char *s, unsigned int base, long *res);
Expand Down
11 changes: 11 additions & 0 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -1764,5 +1764,16 @@ static inline void free_secdata(void *secdata)
{ }
#endif /* CONFIG_SECURITY */

#ifdef CONFIG_LOCK_DOWN_KERNEL
extern void lock_kernel_down(void);
#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT
extern void lift_kernel_lockdown(void);
#endif
#else
static inline void lock_kernel_down(void)
{
}
#endif

#endif /* ! __LINUX_SECURITY_H */

7 changes: 7 additions & 0 deletions kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
return -EPERM;

/*
* kexec can be used to circumvent module loading restrictions, so
* prevent loading in that case
*/
if (kernel_is_locked_down())
return -EPERM;

/*
* Verify we have a legal set of flags
* This leaves us room for future extensions.
Expand Down
6 changes: 6 additions & 0 deletions kernel/kexec_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
return -EPERM;

/* Don't permit images to be loaded into trusted kernels if we're not
* going to verify the signature on them
*/
if (!IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) && kernel_is_locked_down())
return -EPERM;

/* Make sure we have a legal set of flags */
if (flags != (flags & KEXEC_FILE_FLAGS))
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -2781,7 +2781,7 @@ static int module_sig_check(struct load_info *info, int flags)
}

/* Not having a signature is only an error if we're strict. */
if (err == -ENOKEY && !sig_enforce)
if (err == -ENOKEY && !sig_enforce && !kernel_is_locked_down())
err = 0;

return err;
Expand Down
Loading