Commit b2a18c25 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Ingo Molnar:
 "Various fixes all over the map: prevent boot crashes on HyperV,
  classify UEFI randomness as bootloader randomness, fix EFI boot for
  the Raspberry Pi2, fix efi_test permissions, etc"

* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/efi_test: Lock down /dev/efi_test and require CAP_SYS_ADMIN
  x86, efi: Never relocate kernel below lowest acceptable address
  efi: libstub/arm: Account for firmware reserved memory at the base of RAM
  efi/random: Treat EFI_RNG_PROTOCOL output as bootloader randomness
  efi/tpm: Return -EINVAL when determining tpm final events log size fails
  efi: Make CONFIG_EFI_RCI2_TABLE selectable on x86 only
parents d540c398 359efcc2
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/e820/types.h> #include <asm/e820/types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/desc.h> #include <asm/desc.h>
#include <asm/boot.h>
#include "../string.h" #include "../string.h"
#include "eboot.h" #include "eboot.h"
...@@ -813,7 +814,8 @@ efi_main(struct efi_config *c, struct boot_params *boot_params) ...@@ -813,7 +814,8 @@ efi_main(struct efi_config *c, struct boot_params *boot_params)
status = efi_relocate_kernel(sys_table, &bzimage_addr, status = efi_relocate_kernel(sys_table, &bzimage_addr,
hdr->init_size, hdr->init_size, hdr->init_size, hdr->init_size,
hdr->pref_address, hdr->pref_address,
hdr->kernel_alignment); hdr->kernel_alignment,
LOAD_PHYSICAL_ADDR);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); efi_printk(sys_table, "efi_relocate_kernel() failed!\n");
goto fail; goto fail;
......
...@@ -182,6 +182,7 @@ config RESET_ATTACK_MITIGATION ...@@ -182,6 +182,7 @@ config RESET_ATTACK_MITIGATION
config EFI_RCI2_TABLE config EFI_RCI2_TABLE
bool "EFI Runtime Configuration Interface Table Version 2 Support" bool "EFI Runtime Configuration Interface Table Version 2 Support"
depends on X86 || COMPILE_TEST
help help
Displays the content of the Runtime Configuration Interface Displays the content of the Runtime Configuration Interface
Table version 2 on Dell EMC PowerEdge systems as a binary Table version 2 on Dell EMC PowerEdge systems as a binary
......
...@@ -554,7 +554,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, ...@@ -554,7 +554,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
sizeof(*seed) + size); sizeof(*seed) + size);
if (seed != NULL) { if (seed != NULL) {
pr_notice("seeding entropy pool\n"); pr_notice("seeding entropy pool\n");
add_device_randomness(seed->bits, seed->size); add_bootloader_randomness(seed->bits, seed->size);
early_memunmap(seed, sizeof(*seed) + size); early_memunmap(seed, sizeof(*seed) + size);
} else { } else {
pr_err("Could not map UEFI random seed!\n"); pr_err("Could not map UEFI random seed!\n");
......
...@@ -52,6 +52,7 @@ lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \ ...@@ -52,6 +52,7 @@ lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \
lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += arm64-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o
CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
# #
......
...@@ -195,6 +195,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, ...@@ -195,6 +195,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
unsigned long dram_base, unsigned long dram_base,
efi_loaded_image_t *image) efi_loaded_image_t *image)
{ {
unsigned long kernel_base;
efi_status_t status; efi_status_t status;
/* /*
...@@ -204,9 +205,18 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, ...@@ -204,9 +205,18 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
* loaded. These assumptions are made by the decompressor, * loaded. These assumptions are made by the decompressor,
* before any memory map is available. * before any memory map is available.
*/ */
dram_base = round_up(dram_base, SZ_128M); kernel_base = round_up(dram_base, SZ_128M);
status = reserve_kernel_base(sys_table, dram_base, reserve_addr, /*
* Note that some platforms (notably, the Raspberry Pi 2) put
* spin-tables and other pieces of firmware at the base of RAM,
* abusing the fact that the window of TEXT_OFFSET bytes at the
* base of the kernel image is only partially used at the moment.
* (Up to 5 pages are used for the swapper page tables)
*/
kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE;
status = reserve_kernel_base(sys_table, kernel_base, reserve_addr,
reserve_size); reserve_size);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n"); pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n");
...@@ -220,7 +230,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, ...@@ -220,7 +230,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
*image_size = image->image_size; *image_size = image->image_size;
status = efi_relocate_kernel(sys_table, image_addr, *image_size, status = efi_relocate_kernel(sys_table, image_addr, *image_size,
*image_size, *image_size,
dram_base + MAX_UNCOMP_KERNEL_SIZE, 0); kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
pr_efi_err(sys_table, "Failed to relocate kernel.\n"); pr_efi_err(sys_table, "Failed to relocate kernel.\n");
efi_free(sys_table, *reserve_size, *reserve_addr); efi_free(sys_table, *reserve_size, *reserve_addr);
......
...@@ -260,11 +260,11 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, ...@@ -260,11 +260,11 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
} }
/* /*
* Allocate at the lowest possible address. * Allocate at the lowest possible address that is not below 'min'.
*/ */
efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
unsigned long size, unsigned long align, unsigned long size, unsigned long align,
unsigned long *addr) unsigned long *addr, unsigned long min)
{ {
unsigned long map_size, desc_size, buff_size; unsigned long map_size, desc_size, buff_size;
efi_memory_desc_t *map; efi_memory_desc_t *map;
...@@ -311,13 +311,8 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, ...@@ -311,13 +311,8 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
start = desc->phys_addr; start = desc->phys_addr;
end = start + desc->num_pages * EFI_PAGE_SIZE; end = start + desc->num_pages * EFI_PAGE_SIZE;
/* if (start < min)
* Don't allocate at 0x0. It will confuse code that start = min;
* checks pointers against NULL. Skip the first 8
* bytes so we start at a nice even number.
*/
if (start == 0x0)
start += 8;
start = round_up(start, align); start = round_up(start, align);
if ((start + size) > end) if ((start + size) > end)
...@@ -698,7 +693,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, ...@@ -698,7 +693,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
unsigned long image_size, unsigned long image_size,
unsigned long alloc_size, unsigned long alloc_size,
unsigned long preferred_addr, unsigned long preferred_addr,
unsigned long alignment) unsigned long alignment,
unsigned long min_addr)
{ {
unsigned long cur_image_addr; unsigned long cur_image_addr;
unsigned long new_addr = 0; unsigned long new_addr = 0;
...@@ -731,8 +727,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, ...@@ -731,8 +727,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
* possible. * possible.
*/ */
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
status = efi_low_alloc(sys_table_arg, alloc_size, alignment, status = efi_low_alloc_above(sys_table_arg, alloc_size,
&new_addr); alignment, &new_addr, min_addr);
} }
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n"); pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/security.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -717,6 +718,13 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd, ...@@ -717,6 +718,13 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd,
static int efi_test_open(struct inode *inode, struct file *file) static int efi_test_open(struct inode *inode, struct file *file)
{ {
int ret = security_locked_down(LOCKDOWN_EFI_TEST);
if (ret)
return ret;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
/* /*
* nothing special to do here * nothing special to do here
* We do accept multiple open files at the same time as we * We do accept multiple open files at the same time as we
......
...@@ -88,6 +88,7 @@ int __init efi_tpm_eventlog_init(void) ...@@ -88,6 +88,7 @@ int __init efi_tpm_eventlog_init(void)
if (tbl_size < 0) { if (tbl_size < 0) {
pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
ret = -EINVAL;
goto out_calc; goto out_calc;
} }
......
...@@ -1579,9 +1579,22 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, ...@@ -1579,9 +1579,22 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
struct efi_boot_memmap *map); struct efi_boot_memmap *map);
efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg,
unsigned long size, unsigned long align,
unsigned long *addr, unsigned long min);
static inline
efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
unsigned long size, unsigned long align, unsigned long size, unsigned long align,
unsigned long *addr); unsigned long *addr)
{
/*
* Don't allocate at 0x0. It will confuse code that
* checks pointers against NULL. Skip the first 8
* bytes so we start at a nice even number.
*/
return efi_low_alloc_above(sys_table_arg, size, align, addr, 0x8);
}
efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
unsigned long size, unsigned long align, unsigned long size, unsigned long align,
...@@ -1592,7 +1605,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, ...@@ -1592,7 +1605,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
unsigned long image_size, unsigned long image_size,
unsigned long alloc_size, unsigned long alloc_size,
unsigned long preferred_addr, unsigned long preferred_addr,
unsigned long alignment); unsigned long alignment,
unsigned long min_addr);
efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
efi_loaded_image_t *image, efi_loaded_image_t *image,
......
...@@ -105,6 +105,7 @@ enum lockdown_reason { ...@@ -105,6 +105,7 @@ enum lockdown_reason {
LOCKDOWN_NONE, LOCKDOWN_NONE,
LOCKDOWN_MODULE_SIGNATURE, LOCKDOWN_MODULE_SIGNATURE,
LOCKDOWN_DEV_MEM, LOCKDOWN_DEV_MEM,
LOCKDOWN_EFI_TEST,
LOCKDOWN_KEXEC, LOCKDOWN_KEXEC,
LOCKDOWN_HIBERNATION, LOCKDOWN_HIBERNATION,
LOCKDOWN_PCI_ACCESS, LOCKDOWN_PCI_ACCESS,
......
...@@ -20,6 +20,7 @@ static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { ...@@ -20,6 +20,7 @@ static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_NONE] = "none", [LOCKDOWN_NONE] = "none",
[LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading", [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
[LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port", [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
[LOCKDOWN_EFI_TEST] = "/dev/efi_test access",
[LOCKDOWN_KEXEC] = "kexec of unsigned images", [LOCKDOWN_KEXEC] = "kexec of unsigned images",
[LOCKDOWN_HIBERNATION] = "hibernation", [LOCKDOWN_HIBERNATION] = "hibernation",
[LOCKDOWN_PCI_ACCESS] = "direct PCI access", [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment