From patchwork Tue Nov 22 11:12:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91EA5C07E9D for ; Tue, 22 Nov 2022 11:12:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232483AbiKVLM4 (ORCPT ); Tue, 22 Nov 2022 06:12:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232999AbiKVLMr (ORCPT ); Tue, 22 Nov 2022 06:12:47 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 866C81030; Tue, 22 Nov 2022 03:12:44 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 4CF12419E9F0; Tue, 22 Nov 2022 11:12:40 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 4CF12419E9F0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115560; bh=4ZeCfeL+Tv55vKbW3Vc1Ph6Cjl3WL9hmJicrinwykXM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LJ+J+4AHnuC2D2QMr1jHJSyjPXrNYVvD5P4BnmbIvK/cWY1vZJBkzMMOQB8GL/p17 UpFi694ht927LmhYZA4meBb6AfGoTq9HdUGyglSFGnIxUCN2x+YtLmOyFi5Hcla056 qEQVE5BwUH9rZ7DQwz54vwlIGTIId+iTIGi2Y1QA= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 01/24] x86/boot: Align vmlinuz sections on page size Date: Tue, 22 Nov 2022 14:12:10 +0300 Message-Id: X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org To protect sections on page table level each section needs to be aligned on page size (4KB). Set sections alignment in linker script. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/vmlinux.lds.S | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 112b2375d021..6be90f1a1198 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -27,21 +27,27 @@ SECTIONS HEAD_TEXT _ehead = . ; } + . = ALIGN(PAGE_SIZE); .rodata..compressed : { + _compressed = .; *(.rodata..compressed) + _ecompressed = .; } + . = ALIGN(PAGE_SIZE); .text : { _text = .; /* Text */ *(.text) *(.text.*) _etext = . ; } + . = ALIGN(PAGE_SIZE); .rodata : { _rodata = . ; *(.rodata) /* read-only data */ *(.rodata.*) _erodata = . ; } + . = ALIGN(PAGE_SIZE); .data : { _data = . ; *(.data) From patchwork Tue Nov 22 11:12:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627800 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 591E9C4167E for ; Tue, 22 Nov 2022 11:12:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233072AbiKVLMx (ORCPT ); Tue, 22 Nov 2022 06:12:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59330 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232523AbiKVLMq (ORCPT ); Tue, 22 Nov 2022 06:12:46 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83471D8F; Tue, 22 Nov 2022 03:12:44 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 1F10140737BC; Tue, 22 Nov 2022 11:12:41 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 1F10140737BC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115561; bh=2OgHhvX0+NKEpZn5NMyzaoGQPiwdR+Cd155qSqPChrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KLz8q0MMIyC5hmzfbPOkVty4Msd4Og74V5Gkwmoa+152kRZT4ObOLpYa+KPyaSCC5 hDzv+vG5RFomXnx1ZY/eM0iNu6NArTDIEqUM68/mURRV9c5nuTYHh84Rrh8RxW+rqH HtkloXpaE8sxoWT6kHcXu/UjK9LdvX9DCSw2W5n4= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 04/24] x86/boot: Increase boot page table size Date: Tue, 22 Nov 2022 14:12:13 +0300 Message-Id: <5fe439aefdbbe52908512f5229d975dbd7780628.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Previous upper limit ignored pages implicitly mapped from #PF handler by code accessing ACPI tables (boot/compressed/{acpi.c,efi.c}), so theoretical upper limit is higher than it was set. Using 4KB pages is desirable for better memory protection granularity. Approximately twice as much memory is required for those. Increase initial page table size to 64 4KB page tables. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/include/asm/boot.h | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 9191280d9ea3..024d972c248e 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -41,22 +41,24 @@ # define BOOT_STACK_SIZE 0x4000 # define BOOT_INIT_PGT_SIZE (6*4096) -# ifdef CONFIG_RANDOMIZE_BASE /* * Assuming all cross the 512GB boundary: * 1 page for level4 - * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel - * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). - * Total is 19 pages. + * (3+3)*2 pages for param and cmd_line + * (2+2+S)*2 pages for kernel and randomized kernel, where S is total number + * of sections of kernel. Explanation: 2+2 are upper level page tables. + * We can have only S unaligned parts of section: 1 at the end of the kernel + * and (S-1) at the section borders. The start address of the kernel is + * aligned, so an extra page table. There are at most S=6 sections in + * vmlinux ELF image. + * 3 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). + * Total is 36 pages. + * + * Some pages are also required for UEFI memory map and + * ACPI table mappings, so we need to add extra space. + * FIXME: Figure out exact amount of pages. */ -# ifdef CONFIG_X86_VERBOSE_BOOTUP -# define BOOT_PGT_SIZE (19*4096) -# else /* !CONFIG_X86_VERBOSE_BOOTUP */ -# define BOOT_PGT_SIZE (17*4096) -# endif -# else /* !CONFIG_RANDOMIZE_BASE */ -# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE -# endif +# define BOOT_PGT_SIZE (64*4096) #else /* !CONFIG_X86_64 */ # define BOOT_STACK_SIZE 0x1000 From patchwork Tue Nov 22 11:12:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627796 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26050C47089 for ; Tue, 22 Nov 2022 11:13:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233019AbiKVLND (ORCPT ); Tue, 22 Nov 2022 06:13:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233034AbiKVLMu (ORCPT ); Tue, 22 Nov 2022 06:12:50 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3310E267F; Tue, 22 Nov 2022 03:12:48 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 9C08B40737C1; Tue, 22 Nov 2022 11:12:41 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 9C08B40737C1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115561; bh=4haHvAge0ZVypAtCqNphqmDSbsiyOEoFu7H/5nST5/U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AMCUBXhWSudRV8+u0wMZu0mFj3VC2LoL3pB8bToGWOLrd1q3LZmoWiyvSEBaOssCN xGWQE67y4znk2a9I20jroKw7z8jasppzxUpuTjlIaOHl7zE4thS5uDa7lEZkMzxtd6 kmYHmIGK79gSDeCtHGHTTpsSuC9o8aoMzuysbXRM= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 06/24] x86/boot: Setup memory protection for bzImage code Date: Tue, 22 Nov 2022 14:12:15 +0300 Message-Id: X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Use previously added code to use 4KB pages for mapping. Map compressed and uncompressed kernel with appropriate memory protection attributes. For compressed kernel set them up manually. For uncompressed kernel used flags specified in ELF header. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov delete mode 100644 arch/x86/boot/compressed/pgtable.h create mode 100644 arch/x86/include/asm/shared/pgtable.h --- arch/x86/boot/compressed/head_64.S | 24 +++++- arch/x86/boot/compressed/ident_map_64.c | 97 ++++++++++++++++--------- arch/x86/boot/compressed/misc.c | 63 ++++++++++++++-- arch/x86/boot/compressed/misc.h | 22 +++++- arch/x86/boot/compressed/pgtable.h | 20 ----- arch/x86/boot/compressed/pgtable_64.c | 2 +- arch/x86/boot/compressed/sev.c | 6 +- arch/x86/include/asm/shared/pgtable.h | 29 ++++++++ 8 files changed, 197 insertions(+), 66 deletions(-) delete mode 100644 arch/x86/boot/compressed/pgtable.h create mode 100644 arch/x86/include/asm/shared/pgtable.h diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 2a4372b84fc8..73a2ac2b063d 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -29,13 +29,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include "pgtable.h" +#include /* * Locally defined symbols should be marked hidden: @@ -578,6 +579,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) pushq %rsi call load_stage2_idt + call enable_nx_if_supported /* Pass boot_params to initialize_identity_maps() */ movq (%rsp), %rdi call initialize_identity_maps @@ -602,6 +604,26 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) jmp *%rax SYM_FUNC_END(.Lrelocated) +SYM_FUNC_START_LOCAL_NOALIGN(enable_nx_if_supported) + pushq %rbx + + mov $0x80000001, %eax + cpuid + btl $(X86_FEATURE_NX & 31), %edx + jnc .Lnonx + + movl $MSR_EFER, %ecx + rdmsr + btsl $_EFER_NX, %eax + wrmsr + + movb $1, has_nx(%rip) + +.Lnonx: + popq %rbx + RET +SYM_FUNC_END(enable_nx_if_supported) + .code32 /* * This is the 32-bit trampoline that will be copied over to low memory. diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c index d4a314cc50d6..fec795a4ce23 100644 --- a/arch/x86/boot/compressed/ident_map_64.c +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -28,6 +28,7 @@ #include #include #include +#include /* Use the static base for this part of the boot process */ #undef __PAGE_OFFSET #define __PAGE_OFFSET __PAGE_OFFSET_BASE @@ -86,24 +87,52 @@ phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1; * Due to relocation, pointers must be assigned at run time not build time. */ static struct x86_mapping_info mapping_info; +bool has_nx; /* set in head_64.S */ /* * Adds the specified range to the identity mappings. */ -void kernel_add_identity_map(unsigned long start, unsigned long end) +unsigned long kernel_add_identity_map(unsigned long start, + unsigned long end, + unsigned int flags) { int ret; /* Align boundary to 2M. */ - start = round_down(start, PMD_SIZE); - end = round_up(end, PMD_SIZE); + start = round_down(start, PAGE_SIZE); + end = round_up(end, PAGE_SIZE); if (start >= end) - return; + return start; + + /* + * Warn if W^X is violated. + * Only do that if CONFIG_RANDOMIZE_BASE is set, since otherwise we need + * to create RWX region in case of overlapping memory regions for + * compressed and uncompressed kernel. + */ + + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && + (flags & (MAP_EXEC | MAP_WRITE)) == (MAP_EXEC | MAP_WRITE)) + warn("W^X violation\n"); + + bool nx = !(flags & MAP_EXEC) && has_nx; + bool ro = !(flags & MAP_WRITE); + + mapping_info.page_flag = sme_me_mask | (nx ? + (ro ? __PAGE_KERNEL_RO : __PAGE_KERNEL) : + (ro ? __PAGE_KERNEL_ROX : __PAGE_KERNEL_EXEC)); /* Build the mapping. */ - ret = kernel_ident_mapping_init(&mapping_info, (pgd_t *)top_level_pgt, start, end); + ret = kernel_ident_mapping_init(&mapping_info, + (pgd_t *)top_level_pgt, + start, end); if (ret) error("Error: kernel_ident_mapping_init() failed\n"); + + if (!(flags & MAP_NOFLUSH)) + write_cr3(top_level_pgt); + + return start; } /* Locates and clears a region for a new top level page table. */ @@ -112,14 +141,17 @@ void initialize_identity_maps(void *rmode) unsigned long cmdline; struct setup_data *sd; + boot_params = rmode; + /* Exclude the encryption mask from __PHYSICAL_MASK */ physical_mask &= ~sme_me_mask; /* Init mapping_info with run-time function/buffer pointers. */ mapping_info.alloc_pgt_page = alloc_pgt_page; mapping_info.context = &pgt_data; - mapping_info.page_flag = __PAGE_KERNEL_LARGE_EXEC | sme_me_mask; + mapping_info.page_flag = __PAGE_KERNEL_EXEC | sme_me_mask; mapping_info.kernpg_flag = _KERNPG_TABLE; + mapping_info.allow_4kpages = 1; /* * It should be impossible for this not to already be true, @@ -154,15 +186,29 @@ void initialize_identity_maps(void *rmode) /* * New page-table is set up - map the kernel image, boot_params and the * command line. The uncompressed kernel requires boot_params and the - * command line to be mapped in the identity mapping. Map them - * explicitly here in case the compressed kernel does not touch them, - * or does not touch all the pages covering them. + * command line to be mapped in the identity mapping. + * Every other accessed memory region is mapped later, if required. */ - kernel_add_identity_map((unsigned long)_head, (unsigned long)_end); - boot_params = rmode; - kernel_add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); + kernel_add_identity_map((unsigned long)_head, + (unsigned long)_ehead, MAP_EXEC | MAP_NOFLUSH); + + kernel_add_identity_map((unsigned long)_compressed, + (unsigned long)_ecompressed, MAP_WRITE | MAP_NOFLUSH); + + kernel_add_identity_map((unsigned long)_text, + (unsigned long)_etext, MAP_EXEC | MAP_NOFLUSH); + + kernel_add_identity_map((unsigned long)_rodata, + (unsigned long)_erodata, MAP_NOFLUSH); + + kernel_add_identity_map((unsigned long)_data, + (unsigned long)_end, MAP_WRITE | MAP_NOFLUSH); + + kernel_add_identity_map((unsigned long)boot_params, + (unsigned long)(boot_params + 1), MAP_WRITE | MAP_NOFLUSH); + cmdline = get_cmd_line_ptr(); - kernel_add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); + kernel_add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE, MAP_NOFLUSH); /* * Also map the setup_data entries passed via boot_params in case they @@ -172,7 +218,7 @@ void initialize_identity_maps(void *rmode) while (sd) { unsigned long sd_addr = (unsigned long)sd; - kernel_add_identity_map(sd_addr, sd_addr + sizeof(*sd) + sd->len); + kernel_add_identity_map(sd_addr, sd_addr + sizeof(*sd) + sd->len, MAP_NOFLUSH); sd = (struct setup_data *)sd->next; } @@ -185,26 +231,11 @@ void initialize_identity_maps(void *rmode) static pte_t *split_large_pmd(struct x86_mapping_info *info, pmd_t *pmdp, unsigned long __address) { - unsigned long page_flags; - unsigned long address; - pte_t *pte; - pmd_t pmd; - int i; - - pte = (pte_t *)info->alloc_pgt_page(info->context); + unsigned long address = __address & PMD_MASK; + pte_t *pte = ident_split_large_pmd(info, pmdp, address); if (!pte) return NULL; - address = __address & PMD_MASK; - /* No large page - clear PSE flag */ - page_flags = info->page_flag & ~_PAGE_PSE; - - /* Populate the PTEs */ - for (i = 0; i < PTRS_PER_PMD; i++) { - set_pte(&pte[i], __pte(address | page_flags)); - address += PAGE_SIZE; - } - /* * Ideally we need to clear the large PMD first and do a TLB * flush before we write the new PMD. But the 2M range of the @@ -214,7 +245,7 @@ static pte_t *split_large_pmd(struct x86_mapping_info *info, * also the only user of the page-table, so there is no chance * of a TLB multihit. */ - pmd = __pmd((unsigned long)pte | info->kernpg_flag); + pmd_t pmd = __pmd((unsigned long)pte | info->kernpg_flag); set_pmd(pmdp, pmd); /* Flush TLB to establish the new PMD */ write_cr3(top_level_pgt); @@ -377,5 +408,5 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) * Error code is sane - now identity map the 2M region around * the faulting address. */ - kernel_add_identity_map(address, end); + kernel_add_identity_map(address, end, MAP_WRITE); } diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index cf690d8712f4..0c7ec290044d 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -14,10 +14,10 @@ #include "misc.h" #include "error.h" -#include "pgtable.h" #include "../string.h" #include "../voffset.h" #include +#include /* * WARNING!! @@ -277,7 +277,8 @@ static inline void handle_relocations(void *output, unsigned long output_len, { } #endif -static void parse_elf(void *output) +static void parse_elf(void *output, unsigned long output_len, + unsigned long virt_addr) { #ifdef CONFIG_X86_64 Elf64_Ehdr ehdr; @@ -287,6 +288,7 @@ static void parse_elf(void *output) Elf32_Phdr *phdrs, *phdr; #endif void *dest; + unsigned long addr; int i; memcpy(&ehdr, output, sizeof(ehdr)); @@ -323,10 +325,49 @@ static void parse_elf(void *output) #endif memmove(dest, output + phdr->p_offset, phdr->p_filesz); break; - default: /* Ignore other PT_* */ break; + default: + /* Ignore other PT_* */ + break; + } + } + + handle_relocations(output, output_len, virt_addr); + + if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) + goto skip_protect; + + for (i = 0; i < ehdr.e_phnum; i++) { + phdr = &phdrs[i]; + + switch (phdr->p_type) { + case PT_LOAD: +#ifdef CONFIG_RELOCATABLE + addr = (unsigned long)output; + addr += (phdr->p_paddr - LOAD_PHYSICAL_ADDR); +#else + addr = phdr->p_paddr; +#endif + /* + * Simultaneously readable and writable segments are + * violating W^X, and should not be present in vmlinux image. + * The absence of such segments is checked during build. + */ + + unsigned int flags = MAP_PROTECT; + if (phdr->p_flags & PF_X) + flags |= MAP_EXEC; + if (phdr->p_flags & PF_W) + flags |= MAP_WRITE; + + kernel_add_identity_map(addr, addr + phdr->p_memsz, flags); + break; + default: + /* Ignore other PT_* */ + break; } } +skip_protect: free(phdrs); } @@ -434,6 +475,19 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, needed_size, &virt_addr); + unsigned long phys_addr = (unsigned long)output; + + /* + * If KASLR is disabled input and output regions may overlap. + * In this case we need to map region excutable as well. + */ + unsigned long map_flags = MAP_ALLOC | MAP_WRITE | + (IS_ENABLED(CONFIG_RANDOMIZE_BASE) ? 0 : MAP_EXEC); + phys_addr = kernel_add_identity_map(phys_addr, + phys_addr + needed_size, + map_flags); + output = (unsigned char *)phys_addr; + /* Validate memory location choices. */ if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1)) error("Destination physical address inappropriately aligned"); @@ -456,8 +510,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, debug_putstr("\nDecompressing Linux... "); __decompress(input_data, input_len, NULL, NULL, output, output_len, NULL, error); - parse_elf(output); - handle_relocations(output, output_len, virt_addr); + parse_elf(output, output_len, virt_addr); debug_putstr("done.\nBooting the kernel.\n"); /* Disable exception handling before booting the kernel */ diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 62208ec04ca4..033db9b536e6 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -44,8 +44,12 @@ #define memptr unsigned #endif -/* boot/compressed/vmlinux start and end markers */ -extern char _head[], _end[]; +/* Compressed kernel section start/end markers. */ +extern char _head[], _ehead[]; +extern char _compressed[], _ecompressed[]; +extern char _text[], _etext[]; +extern char _rodata[], _erodata[]; +extern char _data[], _end[]; /* misc.c */ extern memptr free_mem_ptr; @@ -171,8 +175,18 @@ static inline int count_immovable_mem_regions(void) { return 0; } #ifdef CONFIG_X86_5LEVEL extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; #endif -extern void kernel_add_identity_map(unsigned long start, unsigned long end); - +#ifdef CONFIG_X86_64 +extern unsigned long kernel_add_identity_map(unsigned long start, + unsigned long end, + unsigned int flags); +#else +static inline unsigned long kernel_add_identity_map(unsigned long start, + unsigned long end, + unsigned int flags) +{ + return start; +} +#endif /* Used by PAGE_KERN* macros: */ extern pteval_t __default_kernel_pte_mask; diff --git a/arch/x86/boot/compressed/pgtable.h b/arch/x86/boot/compressed/pgtable.h deleted file mode 100644 index cc9b2529a086..000000000000 --- a/arch/x86/boot/compressed/pgtable.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef BOOT_COMPRESSED_PAGETABLE_H -#define BOOT_COMPRESSED_PAGETABLE_H - -#define TRAMPOLINE_32BIT_SIZE (2 * PAGE_SIZE) - -#define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 - -#define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE -#define TRAMPOLINE_32BIT_CODE_SIZE 0x80 - -#define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE - -#ifndef __ASSEMBLER__ - -extern unsigned long *trampoline_32bit; - -extern void trampoline_32bit_src(void *return_ptr); - -#endif /* __ASSEMBLER__ */ -#endif /* BOOT_COMPRESSED_PAGETABLE_H */ diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index 2ac12ff4111b..c7cf5a1059a8 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -2,7 +2,7 @@ #include "misc.h" #include #include -#include "pgtable.h" +#include #include "../string.h" #include "efi.h" diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c index c93930d5ccbd..99f3ad0b30f3 100644 --- a/arch/x86/boot/compressed/sev.c +++ b/arch/x86/boot/compressed/sev.c @@ -13,6 +13,7 @@ #include "misc.h" #include +#include #include #include #include @@ -435,10 +436,11 @@ void sev_prep_identity_maps(unsigned long top_level_pgt) unsigned long cc_info_pa = boot_params->cc_blob_address; struct cc_blob_sev_info *cc_info; - kernel_add_identity_map(cc_info_pa, cc_info_pa + sizeof(*cc_info)); + kernel_add_identity_map(cc_info_pa, cc_info_pa + sizeof(*cc_info), MAP_NOFLUSH); cc_info = (struct cc_blob_sev_info *)cc_info_pa; - kernel_add_identity_map(cc_info->cpuid_phys, cc_info->cpuid_phys + cc_info->cpuid_len); + kernel_add_identity_map(cc_info->cpuid_phys, + cc_info->cpuid_phys + cc_info->cpuid_len, MAP_NOFLUSH); } sev_verify_cbit(top_level_pgt); diff --git a/arch/x86/include/asm/shared/pgtable.h b/arch/x86/include/asm/shared/pgtable.h new file mode 100644 index 000000000000..6527dadf39d6 --- /dev/null +++ b/arch/x86/include/asm/shared/pgtable.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef ASM_SHARED_PAGETABLE_H +#define ASM_SHARED_PAGETABLE_H + +#define MAP_WRITE 0x02 /* Writable memory */ +#define MAP_EXEC 0x04 /* Executable memory */ +#define MAP_ALLOC 0x10 /* Range needs to be allocated */ +#define MAP_PROTECT 0x20 /* Set exact memory attributes for memory range */ +#define MAP_NOFLUSH 0x40 /* Avoid flushing TLB */ + +#define TRAMPOLINE_32BIT_SIZE (3 * PAGE_SIZE) + +#define TRAMPOLINE_32BIT_PLACEMENT_MAX (0xA0000) + +#define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 + +#define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE +#define TRAMPOLINE_32BIT_CODE_SIZE 0x80 + +#define TRAMPOLINE_32BIT_STACK_END TRAMPOLINE_32BIT_SIZE + +#ifndef __ASSEMBLER__ + +extern unsigned long *trampoline_32bit; + +extern void trampoline_32bit_src(void *return_ptr); + +#endif /* __ASSEMBLER__ */ +#endif /* ASM_SHARED_PAGETABLE_H */ From patchwork Tue Nov 22 11:12:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627798 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B26CAC07E9D for ; Tue, 22 Nov 2022 11:13:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233099AbiKVLM7 (ORCPT ); Tue, 22 Nov 2022 06:12:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233013AbiKVLMt (ORCPT ); Tue, 22 Nov 2022 06:12:49 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F354A4; Tue, 22 Nov 2022 03:12:48 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 0491940737C3; Tue, 22 Nov 2022 11:12:42 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 0491940737C3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115562; bh=zJyjXdeGncN0/sCqkQ6LWnTu+HAOR00PivwRmGI/62E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XOkIZdYOveVvoUdyG5wJ1ub0mdhP43FQ/wnUmCYA90XpAOfHLev5q4XWjd+mmHXnX RvZZEsePoUe5/5lNRDYmdrM0J2lSA2lqxwSv0C5tolDpC9/FjmGGXfpF1KrlTUUqh/ XXcfH0sglQeGoz6jxe4vQk2uu/eZ6L8XQG+M+5PM= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 07/24] x86/build: Check W^X of vmlinux during build Date: Tue, 22 Nov 2022 14:12:16 +0300 Message-Id: <686f40eb9c83f9b5e4deba7bfb6cc9c0626d310c.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Check if there are simultaneously writable and executable program segments in vmlinux ELF image and fail build if there are any. This would prevent accidental introduction of RWX segments. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 3a261abb6d15..64de6c2b1740 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -112,11 +112,17 @@ vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a +quiet_cmd_wx_check = WXCHK $< +cmd_wx_check = if $(OBJDUMP) -p $< | grep "flags .wx" > /dev/null; \ + then (echo >&2 "$<: Simultaneously writable and executable sections are prohibited"; \ + /bin/false); fi + $(obj)/vmlinux: $(vmlinux-objs-y) $(efi-obj-y) FORCE $(call if_changed,ld) OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE + $(call cmd,wx_check) $(call if_changed,objcopy) targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs From patchwork Tue Nov 22 11:12:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627794 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 948C0C4167E for ; Tue, 22 Nov 2022 11:13:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233141AbiKVLNJ (ORCPT ); Tue, 22 Nov 2022 06:13:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232730AbiKVLMu (ORCPT ); Tue, 22 Nov 2022 06:12:50 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B62862AC7; Tue, 22 Nov 2022 03:12:48 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 8D6E840737CB; Tue, 22 Nov 2022 11:12:42 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 8D6E840737CB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115562; bh=6oUI8mIWLd1Fo2Wh2YHphseFjFuqPo1vi/6/ODurdpA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qlx40wQ5kSLXszjhsQVxrO7xRhMyp9Oeuf12SIidIpokRDaEqNZ0ZRiVGEDVJVEVw Xo1PjqI0fJjpP8NhqxzQ+0D/QKO4G4UgcycPQVTvRJjf/mZXYg3Dhf50S0Z2+PWHK0 RWWb5DFfcPIQe+twwUa/qAqFFUbJtoOnF8anC/3Y= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 09/24] x86/boot: Remove mapping from page fault handler Date: Tue, 22 Nov 2022 14:12:18 +0300 Message-Id: <7438db5fded11a28310267a7b51b483a5f61d0d4.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org After every implicit mapping is removed, this code is no longer needed. Remove memory mapping from page fault handler to ensure that there are no hidden invalid memory accesses. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/ident_map_64.c | 26 ++++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c index fec795a4ce23..ba5108c58a4e 100644 --- a/arch/x86/boot/compressed/ident_map_64.c +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -386,27 +386,21 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code) { unsigned long address = native_read_cr2(); unsigned long end; - bool ghcb_fault; + char *msg; - ghcb_fault = sev_es_check_ghcb_fault(address); + if (sev_es_check_ghcb_fault(address)) + msg = "Page-fault on GHCB page:"; + else + msg = "Unexpected page-fault:"; address &= PMD_MASK; end = address + PMD_SIZE; /* - * Check for unexpected error codes. Unexpected are: - * - Faults on present pages - * - User faults - * - Reserved bits set - */ - if (error_code & (X86_PF_PROT | X86_PF_USER | X86_PF_RSVD)) - do_pf_error("Unexpected page-fault:", error_code, address, regs->ip); - else if (ghcb_fault) - do_pf_error("Page-fault on GHCB page:", error_code, address, regs->ip); - - /* - * Error code is sane - now identity map the 2M region around - * the faulting address. + * Since all memory allocations are made explicit + * now, every page fault at this stage is an + * error and the error handler is there only + * for debug purposes. */ - kernel_add_identity_map(address, end, MAP_WRITE); + do_pf_error(msg, error_code, address, regs->ip); } From patchwork Tue Nov 22 11:12:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627797 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51823C46467 for ; Tue, 22 Nov 2022 11:13:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232707AbiKVLNB (ORCPT ); Tue, 22 Nov 2022 06:13:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233028AbiKVLMu (ORCPT ); Tue, 22 Nov 2022 06:12:50 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B65D42AEC; Tue, 22 Nov 2022 03:12:48 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 47A1840737D8; Tue, 22 Nov 2022 11:12:43 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 47A1840737D8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115563; bh=crSlzJwK96YW/rE+r+0VuFq2u4zO2iJQEIttDiLLC3Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HZvlcI6T9aWDGQqrRXS8cjF5H0rQ63ngSLaMc5ftyOH5hUATAk1DdStVQkfo7oYa+ Hr2z4elSgKFLllD0x7YSGln3+LloM9wKWOzd3QOMia+1FToMaLIfBCV0VSfSn6QuM3 YgM8Vr9UDc4wHe0S8gfs9/kiR/akD7MgLSopsf7I= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 12/24] x86/boot: Make kernel_add_identity_map() a pointer Date: Tue, 22 Nov 2022 14:12:21 +0300 Message-Id: <9251fb0d8dbb6fbb3a4730952314170c6771df0e.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Convert kernel_add_identity_map() into a function pointer to be able to provide alternative implementations of this function. Required to enable calling the code using this function from EFI environment. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/ident_map_64.c | 7 ++++--- arch/x86/boot/compressed/misc.c | 24 ++++++++++++++++++++++++ arch/x86/boot/compressed/misc.h | 15 +++------------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c index ba5108c58a4e..1aee524d3c2b 100644 --- a/arch/x86/boot/compressed/ident_map_64.c +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -92,9 +92,9 @@ bool has_nx; /* set in head_64.S */ /* * Adds the specified range to the identity mappings. */ -unsigned long kernel_add_identity_map(unsigned long start, - unsigned long end, - unsigned int flags) +unsigned long kernel_add_identity_map_(unsigned long start, + unsigned long end, + unsigned int flags) { int ret; @@ -142,6 +142,7 @@ void initialize_identity_maps(void *rmode) struct setup_data *sd; boot_params = rmode; + kernel_add_identity_map = kernel_add_identity_map_; /* Exclude the encryption mask from __PHYSICAL_MASK */ physical_mask &= ~sme_me_mask; diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index aa4a22bc9cf9..c9c235d65d16 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -275,6 +275,22 @@ static void parse_elf(void *output, unsigned long output_len, free(phdrs); } +/* + * This points to actual implementation of mapping function + * for current environment: either EFI API wrapper, + * own implementation or dummy implementation below. + */ +unsigned long (*kernel_add_identity_map)(unsigned long start, + unsigned long end, + unsigned int flags); + +static inline unsigned long kernel_add_identity_map_dummy(unsigned long start, + unsigned long end, + unsigned int flags) +{ + return start; +} + /* * The compressed kernel image (ZO), has been moved so that its position * is against the end of the buffer used to hold the uncompressed kernel @@ -312,6 +328,14 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, init_default_io_ops(); + /* + * On 64-bit this pointer is set during page table uninitialization, + * but on 32-bit it remains uninitialized, since paging is disabled. + */ + if (IS_ENABLED(CONFIG_X86_32)) + kernel_add_identity_map = kernel_add_identity_map_dummy; + + /* * Detect TDX guest environment. * diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 38d31bec062d..0076b2845b4b 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -180,18 +180,9 @@ static inline int count_immovable_mem_regions(void) { return 0; } #ifdef CONFIG_X86_5LEVEL extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d; #endif -#ifdef CONFIG_X86_64 -extern unsigned long kernel_add_identity_map(unsigned long start, - unsigned long end, - unsigned int flags); -#else -static inline unsigned long kernel_add_identity_map(unsigned long start, - unsigned long end, - unsigned int flags) -{ - return start; -} -#endif +extern unsigned long (*kernel_add_identity_map)(unsigned long start, + unsigned long end, + unsigned int flags); /* Used by PAGE_KERN* macros: */ extern pteval_t __default_kernel_pte_mask; From patchwork Tue Nov 22 11:12:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627795 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EDE42C43217 for ; Tue, 22 Nov 2022 11:13:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233119AbiKVLNG (ORCPT ); Tue, 22 Nov 2022 06:13:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59822 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233042AbiKVLMu (ORCPT ); Tue, 22 Nov 2022 06:12:50 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F23FD2BD2; Tue, 22 Nov 2022 03:12:48 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 7B3A340737DC; Tue, 22 Nov 2022 11:12:43 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 7B3A340737DC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115563; bh=PQtsrCYU1PKgl/tUvA5tLuxewf/SvD2lWTLiW0J0hPU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aoR9o6GCQktf0NJUvawuKROyXeRphTzk4l2u/3i189V58z4DVD61ktH5HW92MSIrk ohC0y4cHtZYMLLJVe/K/zZIfQ2MYcuyfqlcjjq0Tu2rP3nERn4wRC19etwywnbR9SP wq32Lt78Hns8pUov/+JGW3NfR/aeb0gAkg6qF/3U= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 13/24] x86/boot: Split trampoline and pt init code Date: Tue, 22 Nov 2022 14:12:22 +0300 Message-Id: X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org When allocating trampoline from libstub trampoline allocation is performed separately, so it needs to be skipped. Split trampoline initialization and allocation code into two functions to make them invokable separately. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/pgtable_64.c | 73 +++++++++++++++++---------- 1 file changed, 46 insertions(+), 27 deletions(-) diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index c7cf5a1059a8..1f7169248612 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -106,12 +106,8 @@ static unsigned long find_trampoline_placement(void) return bios_start - TRAMPOLINE_32BIT_SIZE; } -struct paging_config paging_prepare(void *rmode) +bool trampoline_pgtable_init(struct boot_params *boot_params) { - struct paging_config paging_config = {}; - - /* Initialize boot_params. Required for cmdline_find_option_bool(). */ - boot_params = rmode; /* * Check if LA57 is desired and supported. @@ -125,26 +121,10 @@ struct paging_config paging_prepare(void *rmode) * * That's substitute for boot_cpu_has() in early boot code. */ - if (IS_ENABLED(CONFIG_X86_5LEVEL) && - !cmdline_find_option_bool("no5lvl") && - native_cpuid_eax(0) >= 7 && - (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) { - paging_config.l5_required = 1; - } - - paging_config.trampoline_start = find_trampoline_placement(); - - trampoline_32bit = (unsigned long *)paging_config.trampoline_start; - - /* Preserve trampoline memory */ - memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); - - /* Clear trampoline memory first */ - memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); - - /* Copy trampoline code in place */ - memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), - &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); + bool l5_required = IS_ENABLED(CONFIG_X86_5LEVEL) && + !cmdline_find_option_bool("no5lvl") && + native_cpuid_eax(0) >= 7 && + (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31))); /* * The code below prepares page table in trampoline memory. @@ -160,10 +140,10 @@ struct paging_config paging_prepare(void *rmode) * We are not going to use the page table in trampoline memory if we * are already in the desired paging mode. */ - if (paging_config.l5_required == !!(native_read_cr4() & X86_CR4_LA57)) + if (l5_required == !!(native_read_cr4() & X86_CR4_LA57)) goto out; - if (paging_config.l5_required) { + if (l5_required) { /* * For 4- to 5-level paging transition, set up current CR3 as * the first and the only entry in a new top-level page table. @@ -185,6 +165,45 @@ struct paging_config paging_prepare(void *rmode) (void *)src, PAGE_SIZE); } +out: + return l5_required; +} + +struct paging_config paging_prepare(void *rmode) +{ + struct paging_config paging_config = {}; + bool early_trampoline_alloc = 0; + + /* Initialize boot_params. Required for cmdline_find_option_bool(). */ + boot_params = rmode; + + /* + * We only need to find trampoline placement, if we have + * not already done it from libstub. + */ + + paging_config.trampoline_start = find_trampoline_placement(); + trampoline_32bit = (unsigned long *)paging_config.trampoline_start; + early_trampoline_alloc = 0; + + /* + * Preserve trampoline memory. + * When trampoline is located in memory + * owned by us, i.e. allocated in EFISTUB, + * we don't care about previous contents + * of this memory so copying can also be skipped. + */ + memcpy(trampoline_save, trampoline_32bit, TRAMPOLINE_32BIT_SIZE); + + /* Clear trampoline memory first */ + memset(trampoline_32bit, 0, TRAMPOLINE_32BIT_SIZE); + + /* Copy trampoline code in place */ + memcpy(trampoline_32bit + TRAMPOLINE_32BIT_CODE_OFFSET / sizeof(unsigned long), + &trampoline_32bit_src, TRAMPOLINE_32BIT_CODE_SIZE); + + paging_config.l5_required = trampoline_pgtable_init(boot_params); + out: return paging_config; } From patchwork Tue Nov 22 11:12:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627793 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61561C43219 for ; Tue, 22 Nov 2022 11:18:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233200AbiKVLSc (ORCPT ); Tue, 22 Nov 2022 06:18:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33600 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232682AbiKVLRc (ORCPT ); Tue, 22 Nov 2022 06:17:32 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A488DEE9; Tue, 22 Nov 2022 03:14:46 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 91753419E9FE; Tue, 22 Nov 2022 11:14:44 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 91753419E9FE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115684; bh=hDUzGiUVmLaacOXu/z6JftlYgMxorcNB1P4zYdNcUVA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fGp+oA9iDBAPhlVYXBcZfYbMN02qaqGsTRz7H2BSjs+/7jTtObG+4M1M1MvcrYwyS rYutse9d68YK6zjZDvAzrCSHnlnmMKYENCBqkOjK7G3Nonpj+4/J67ocO4x5QqnaD1 9pQax7kYHukdsFvsRvMvpiQU/uMqsb/hTPSoqBjk= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 16/24] x86/boot: Reduce lower limit of physical KASLR Date: Tue, 22 Nov 2022 14:12:25 +0300 Message-Id: <0e6a4c9c7655d3f42f624e1174b223fec5b2b087.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Set lower limit of physical KASLR to 64M. Previously is was set to 512M when kernel is loaded higher than that. That prevented physical KASLR from being performed on x86_32, where upper limit is also set to 512M. The limit is pretty arbitrary, and the most important is to set it above the ISA hole, i.e. higher than 16M. It was not that important before, but now kernel is not getting relocated to the lower address when booting via EFI, exposing the KASLR failures. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/boot/compressed/kaslr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 7e09d65f7b57..672550686f62 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -852,10 +852,10 @@ void choose_random_location(unsigned long input, /* * Low end of the randomization range should be the - * smaller of 512M or the initial kernel image + * smaller of 64M or the initial kernel image * location: */ - min_addr = min(*output, 512UL << 20); + min_addr = min(*output, 64UL << 20); /* Make sure minimum is aligned. */ min_addr = ALIGN(min_addr, CONFIG_PHYSICAL_ALIGN); From patchwork Tue Nov 22 11:12:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627792 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19203C43217 for ; Tue, 22 Nov 2022 11:18:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232359AbiKVLSi (ORCPT ); Tue, 22 Nov 2022 06:18:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233002AbiKVLRc (ORCPT ); Tue, 22 Nov 2022 06:17:32 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 20CFB11A35; Tue, 22 Nov 2022 03:14:47 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 1A92140737BF; Tue, 22 Nov 2022 11:14:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 1A92140737BF DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115685; bh=n5AAiEOOYWrwvzMdBWF1U0sf/6pYWwLzWndZJS/v8Q8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LBil9KppqQewrqN1HAVvDjCoE9soUaQxF8RjkHSaSEOnZAfaBWK2/Y/sJroNE4RF+ Et7Cwy5nwpKwStyx9DDAf6/zBMRcc46YAhOosSY4JYlyNnK9RQWabOXvvVA+HPi9L8 LgwIMcKxXE3fuEd4kQB4vpRAcEejVAiye/ps6Q38= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 18/24] tools/include: Add simplified version of pe.h Date: Tue, 22 Nov 2022 14:12:27 +0300 Message-Id: <77698e99062c376d0146e093b61ee189322f6a94.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org This is needed to remove magic numbers from x86 bzImage building tool (arch/x86/boot/tools/build.c). Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- tools/include/linux/pe.h | 150 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 tools/include/linux/pe.h diff --git a/tools/include/linux/pe.h b/tools/include/linux/pe.h new file mode 100644 index 000000000000..41c09ec371d8 --- /dev/null +++ b/tools/include/linux/pe.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Simplified version of include/linux/pe.h: + * Copyright 2011 Red Hat, Inc. All rights reserved. + * Author(s): Peter Jones + */ +#ifndef __LINUX_PE_H +#define __LINUX_PE_H + +#include + +#define IMAGE_FILE_MACHINE_I386 0x014c + +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */ +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */ +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */ +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */ +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */ +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */ + +#define MZ_HEADER_PEADDR_OFFSET 0x3c + +struct pe_hdr { + uint32_t magic; /* PE magic */ + uint16_t machine; /* machine type */ + uint16_t sections; /* number of sections */ + uint32_t timestamp; /* time_t */ + uint32_t symbol_table; /* symbol table offset */ + uint32_t symbols; /* number of symbols */ + uint16_t opt_hdr_size; /* size of optional header */ + uint16_t flags; /* flags */ +}; + +/* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't + * work right. vomit. */ +struct pe32_opt_hdr { + /* "standard" header */ + uint16_t magic; /* file type */ + uint8_t ld_major; /* linker major version */ + uint8_t ld_minor; /* linker minor version */ + uint32_t text_size; /* size of text section(s) */ + uint32_t data_size; /* size of data section(s) */ + uint32_t bss_size; /* size of bss section(s) */ + uint32_t entry_point; /* file offset of entry point */ + uint32_t code_base; /* relative code addr in ram */ + uint32_t data_base; /* relative data addr in ram */ + /* "windows" header */ + uint32_t image_base; /* preferred load address */ + uint32_t section_align; /* alignment in bytes */ + uint32_t file_align; /* file alignment in bytes */ + uint16_t os_major; /* major OS version */ + uint16_t os_minor; /* minor OS version */ + uint16_t image_major; /* major image version */ + uint16_t image_minor; /* minor image version */ + uint16_t subsys_major; /* major subsystem version */ + uint16_t subsys_minor; /* minor subsystem version */ + uint32_t win32_version; /* reserved, must be 0 */ + uint32_t image_size; /* image size */ + uint32_t header_size; /* header size rounded up to + file_align */ + uint32_t csum; /* checksum */ + uint16_t subsys; /* subsystem */ + uint16_t dll_flags; /* more flags! */ + uint32_t stack_size_req;/* amt of stack requested */ + uint32_t stack_size; /* amt of stack required */ + uint32_t heap_size_req; /* amt of heap requested */ + uint32_t heap_size; /* amt of heap required */ + uint32_t loader_flags; /* reserved, must be 0 */ + uint32_t data_dirs; /* number of data dir entries */ +}; + +struct pe32plus_opt_hdr { + uint16_t magic; /* file type */ + uint8_t ld_major; /* linker major version */ + uint8_t ld_minor; /* linker minor version */ + uint32_t text_size; /* size of text section(s) */ + uint32_t data_size; /* size of data section(s) */ + uint32_t bss_size; /* size of bss section(s) */ + uint32_t entry_point; /* file offset of entry point */ + uint32_t code_base; /* relative code addr in ram */ + /* "windows" header */ + uint64_t image_base; /* preferred load address */ + uint32_t section_align; /* alignment in bytes */ + uint32_t file_align; /* file alignment in bytes */ + uint16_t os_major; /* major OS version */ + uint16_t os_minor; /* minor OS version */ + uint16_t image_major; /* major image version */ + uint16_t image_minor; /* minor image version */ + uint16_t subsys_major; /* major subsystem version */ + uint16_t subsys_minor; /* minor subsystem version */ + uint32_t win32_version; /* reserved, must be 0 */ + uint32_t image_size; /* image size */ + uint32_t header_size; /* header size rounded up to + file_align */ + uint32_t csum; /* checksum */ + uint16_t subsys; /* subsystem */ + uint16_t dll_flags; /* more flags! */ + uint64_t stack_size_req;/* amt of stack requested */ + uint64_t stack_size; /* amt of stack required */ + uint64_t heap_size_req; /* amt of heap requested */ + uint64_t heap_size; /* amt of heap required */ + uint32_t loader_flags; /* reserved, must be 0 */ + uint32_t data_dirs; /* number of data dir entries */ +}; + +struct data_dirent { + uint32_t virtual_address; /* relative to load address */ + uint32_t size; +}; + +struct data_directory { + struct data_dirent exports; /* .edata */ + struct data_dirent imports; /* .idata */ + struct data_dirent resources; /* .rsrc */ + struct data_dirent exceptions; /* .pdata */ + struct data_dirent certs; /* certs */ + struct data_dirent base_relocations; /* .reloc */ + struct data_dirent debug; /* .debug */ + struct data_dirent arch; /* reservered */ + struct data_dirent global_ptr; /* global pointer reg. Size=0 */ + struct data_dirent tls; /* .tls */ + struct data_dirent load_config; /* load configuration structure */ + struct data_dirent bound_imports; /* no idea */ + struct data_dirent import_addrs; /* import address table */ + struct data_dirent delay_imports; /* delay-load import table */ + struct data_dirent clr_runtime_hdr; /* .cor (object only) */ + struct data_dirent reserved; +}; + +struct section_header { + char name[8]; /* name or "/12\0" string tbl offset */ + uint32_t virtual_size; /* size of loaded section in ram */ + uint32_t virtual_address; /* relative virtual address */ + uint32_t raw_data_size; /* size of the section */ + uint32_t data_addr; /* file pointer to first page of sec */ + uint32_t relocs; /* file pointer to relocation entries */ + uint32_t line_numbers; /* line numbers! */ + uint16_t num_relocs; /* number of relocations */ + uint16_t num_lin_numbers; /* srsly. */ + uint32_t flags; +}; + +struct coff_reloc { + uint32_t virtual_address; + uint32_t symbol_table_index; + uint16_t data; +}; + +#endif /* __LINUX_PE_H */ From patchwork Tue Nov 22 11:12:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627790 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBB61C4321E for ; Tue, 22 Nov 2022 11:18:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233151AbiKVLSr (ORCPT ); Tue, 22 Nov 2022 06:18:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233008AbiKVLRf (ORCPT ); Tue, 22 Nov 2022 06:17:35 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27E656069C; Tue, 22 Nov 2022 03:14:50 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id B3D3340737C9; Tue, 22 Nov 2022 11:14:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru B3D3340737C9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115685; bh=ZUJpRbIyPzAf4A80RpXrKYrL/K9OYgNwdLc+ngJr0bg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cmk+mb5huszA2qUFj6o4xt2AVcWngG+nCNUXrywyMMftoNEzoH1yIW/BlZ68vjIAy Hf7zgiAUUOm2pr1Xbrn2xDzRLWWWhw8MnYOKl4531bY6OOICWrEMmjn3n/zbcDKJ/q yj9lRV7Xe7xSb2tS0ae/DT7XA1UVQGIXKExqa6ng= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 21/24] efi/x86: Explicitly set sections memory attributes Date: Tue, 22 Nov 2022 14:12:30 +0300 Message-Id: <9b18f9efb457e9aa88e814928fdaa37c76f080e1.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Explicitly change sections memory attributes in efi_pe_entry in case of incorrect EFI implementations and to reduce access rights to compressed kernel blob. By default it is set executable due to restriction in maximum number of sections that can fit before zero page. Signed-off-by: Evgeniy Baskov --- drivers/firmware/efi/libstub/x86-stub.c | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index d9b239d7289f..56b8e7207361 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -27,6 +27,12 @@ const efi_dxe_services_table_t *efi_dxe_table; extern u32 image_offset; static efi_loaded_image_t *image __section(".data"); +extern char _head[], _ehead[]; +extern char _compressed[], _ecompressed[]; +extern char _text[], _etext[]; +extern char _rodata[], _erodata[]; +extern char _data[]; + static efi_status_t preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) { @@ -343,6 +349,52 @@ void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) asm("hlt"); } + +/* + * Manually setup memory protection attributes for each ELF section + * since we cannot do it properly by using PE sections. + */ +static void setup_sections_memory_protection(unsigned long image_base) +{ +#ifdef CONFIG_EFI_DXE_MEM_ATTRIBUTES + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); + + if (!efi_dxe_table || + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { + efi_warn("Unable to locate EFI DXE services table\n"); + efi_dxe_table = NULL; + return; + } + + /* .setup [image_base, _head] */ + efi_adjust_memory_range_protection(image_base, + (unsigned long)_head - image_base, + EFI_MEMORY_RO | EFI_MEMORY_XP); + /* .head.text [_head, _ehead] */ + efi_adjust_memory_range_protection((unsigned long)_head, + (unsigned long)_ehead - (unsigned long)_head, + EFI_MEMORY_RO); + /* .rodata..compressed [_compressed, _ecompressed] */ + efi_adjust_memory_range_protection((unsigned long)_compressed, + (unsigned long)_ecompressed - (unsigned long)_compressed, + EFI_MEMORY_RO | EFI_MEMORY_XP); + /* .text [_text, _etext] */ + efi_adjust_memory_range_protection((unsigned long)_text, + (unsigned long)_etext - (unsigned long)_text, + EFI_MEMORY_RO); + /* .rodata [_rodata, _erodata] */ + efi_adjust_memory_range_protection((unsigned long)_rodata, + (unsigned long)_erodata - (unsigned long)_rodata, + EFI_MEMORY_RO | EFI_MEMORY_XP); + /* .data, .bss [_data, _end] */ + efi_adjust_memory_range_protection((unsigned long)_data, + (unsigned long)_end - (unsigned long)_data, + EFI_MEMORY_XP); +#else + (void)image_base; +#endif +} + void __noreturn efi_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, struct boot_params *boot_params); @@ -687,6 +739,8 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, efi_dxe_table = NULL; } + setup_sections_memory_protection(bzimage_addr - image_offset); + #ifdef CONFIG_CMDLINE_BOOL status = efi_parse_options(CONFIG_CMDLINE); if (status != EFI_SUCCESS) { From patchwork Tue Nov 22 11:12:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627791 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55C34C433FE for ; Tue, 22 Nov 2022 11:18:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233283AbiKVLSp (ORCPT ); Tue, 22 Nov 2022 06:18:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233139AbiKVLRe (ORCPT ); Tue, 22 Nov 2022 06:17:34 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22C4E6069B; Tue, 22 Nov 2022 03:14:50 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id EE34D40737CB; Tue, 22 Nov 2022 11:14:45 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru EE34D40737CB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115686; bh=cllZgKoFdcdi/05M19KDo6OekyVBAAVXha3SArZmxSY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eLhoxF/G4zVE5KxP8xburRpYWx4NgyifFg3DSHui5TJGtnehXeepnViHh+C/nSs+Z XetFDHQVTc9Y1ybMUPgIN/+wbtI9DcmgCjUJUMkup9itgOOiLUhbqMSkNyiW7Uq7ez 2RCk1w68y+kKFjiLcpYObRT9/fbnjp+xN/74jdxg= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 22/24] efi/libstub: Add memory attribute protocol definitions Date: Tue, 22 Nov 2022 14:12:31 +0300 Message-Id: <44539c8c6afdba66f791942deae95c7b13d1e13b.1668958803.git.baskov@ispras.ru> X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org EFI_MEMORY_ATTRIBUTE_PROTOCOL servers as a better alternative to DXE services for setting memory attributes in EFI Boot Services environment. This protocol is better since it is a part of UEFI specification itself and not UEFI PI specification like DXE services. Add EFI_MEMORY_ATTRIBUTE_PROTOCOL definitions. Support mixed mode properly for its calls. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- arch/x86/include/asm/efi.h | 7 +++++++ drivers/firmware/efi/libstub/efistub.h | 22 ++++++++++++++++++++++ include/linux/efi.h | 1 + 3 files changed, 30 insertions(+) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 233ae6986d6f..522ff2e443b3 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -325,6 +325,13 @@ static inline u32 efi64_convert_status(efi_status_t status) #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) +/* Memory Attribute Protocol */ +#define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ + ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) + +#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ + ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) + /* * The macros below handle the plumbing for the argument mapping. To add a * mapping for a specific EFI method, simply define a macro diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index c74ac2875e31..343cae662bec 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -39,6 +39,9 @@ extern const efi_system_table_t *efi_system_table; typedef union efi_dxe_services_table efi_dxe_services_table_t; extern const efi_dxe_services_table_t *efi_dxe_table; +typedef union efi_memory_attribute_protocol efi_memory_attribute_protocol_t; +extern efi_memory_attribute_protocol_t *efi_mem_attrib_proto; + efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg); @@ -415,6 +418,25 @@ union efi_dxe_services_table { } mixed_mode; }; +union efi_memory_attribute_protocol { + struct { + void *get_memory_attributes; + efi_status_t (__efiapi *set_memory_attributes)(efi_memory_attribute_protocol_t *, + efi_physical_addr_t, + u64, + u64); + efi_status_t (__efiapi *clear_memory_attributes)(efi_memory_attribute_protocol_t *, + efi_physical_addr_t, + u64, + u64); + }; + struct { + u32 get_memory_attributes; + u32 set_memory_attributes; + u32 clear_memory_attributes; + } mixed_mode; +}; + typedef union efi_uga_draw_protocol efi_uga_draw_protocol_t; union efi_uga_draw_protocol { diff --git a/include/linux/efi.h b/include/linux/efi.h index 7603fc58c47c..5f880e8f96bd 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -390,6 +390,7 @@ void efi_native_runtime_setup(void); #define EFI_RT_PROPERTIES_TABLE_GUID EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9) #define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) #define EFI_SMBIOS_PROTOCOL_GUID EFI_GUID(0x03583ff6, 0xcb36, 0x4940, 0x94, 0x7e, 0xb9, 0xb3, 0x9f, 0x4a, 0xfa, 0xf7) +#define EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID EFI_GUID(0xf4560cf6, 0x40ec, 0x4b4a, 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89) #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) From patchwork Tue Nov 22 11:12:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeniy Baskov X-Patchwork-Id: 627789 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE917C4332F for ; Tue, 22 Nov 2022 11:19:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233352AbiKVLTK (ORCPT ); Tue, 22 Nov 2022 06:19:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233168AbiKVLRh (ORCPT ); Tue, 22 Nov 2022 06:17:37 -0500 Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5374E6069D; Tue, 22 Nov 2022 03:14:50 -0800 (PST) Received: from localhost.localdomain (unknown [83.149.199.65]) by mail.ispras.ru (Postfix) with ESMTPSA id 303F540737CC; Tue, 22 Nov 2022 11:14:46 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru 303F540737CC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ispras.ru; s=default; t=1669115686; bh=2Z3eUgmMTKBvXlCU86hmKECd7rhhkSSGu3zwsXuXe64=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lm7JzWv6usfro23PK+b4IBbUG87BJ/E76vutLNGBVjRCcg2q6qYI2BRIvKvpBsyMh pLVskgvaOiMJQJt6bAnwON4iQvWn2HjDrv0KXxXLqRLb57M4d6ffUcWkNhffHDvYIz n39ceZw8c8Mw4MYf0dty0sqvjmM4t96qbdqlT18g= From: Evgeniy Baskov To: Ard Biesheuvel Cc: Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , "Limonciello, Mario" , joeyli , lvc-project@linuxtesting.org, x86@kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH v3 23/24] efi/libstub: Use memory attribute protocol Date: Tue, 22 Nov 2022 14:12:32 +0300 Message-Id: X-Mailer: git-send-email 2.37.4 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add EFI_MEMORY_ATTRIBUTE_PROTOCOL as preferred alternative to DXE services for changing memory attributes in the EFISTUB. Use DXE services only as a fallback in case aforementioned protocol is not supported by UEFI implementation. Move DXE services initialization code closer to the place they are used to match EFI_MEMORY_ATTRIBUTE_PROTOCOL initialization code. Tested-by: Mario Limonciello Signed-off-by: Evgeniy Baskov --- drivers/firmware/efi/libstub/mem.c | 168 ++++++++++++++++++------ drivers/firmware/efi/libstub/x86-stub.c | 17 --- 2 files changed, 128 insertions(+), 57 deletions(-) diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c index cdf1e6fb6430..35acec241dd3 100644 --- a/drivers/firmware/efi/libstub/mem.c +++ b/drivers/firmware/efi/libstub/mem.c @@ -5,6 +5,9 @@ #include "efistub.h" +const efi_dxe_services_table_t *efi_dxe_table; +efi_memory_attribute_protocol_t *efi_mem_attrib_proto; + /** * efi_get_memory_map() - get memory map * @map: pointer to memory map pointer to which to assign the @@ -126,66 +129,47 @@ void efi_free(unsigned long size, unsigned long addr) efi_bs_call(free_pages, addr, nr_pages); } -/** - * efi_adjust_memory_range_protection() - change memory range protection attributes - * @start: memory range start address - * @size: memory range size - * - * Actual memory range for which memory attributes are modified is - * the smallest ranged with start address and size aligned to EFI_PAGE_SIZE - * that includes [start, start + size]. - * - * @return: status code - */ -efi_status_t efi_adjust_memory_range_protection(unsigned long start, - unsigned long size, - unsigned long attributes) +static void retrieve_dxe_table(void) +{ + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); + if (efi_dxe_table && + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { + efi_warn("Ignoring DXE services table: invalid signature\n"); + efi_dxe_table = NULL; + } +} + +static efi_status_t adjust_mem_attrib_dxe(efi_physical_addr_t rounded_start, + efi_physical_addr_t rounded_end, + unsigned long attributes) { efi_status_t status; efi_gcd_memory_space_desc_t desc; - efi_physical_addr_t end, next; - efi_physical_addr_t rounded_start, rounded_end; + efi_physical_addr_t end, next, start; efi_physical_addr_t unprotect_start, unprotect_size; - if (efi_dxe_table == NULL) - return EFI_UNSUPPORTED; + if (!efi_dxe_table) { + retrieve_dxe_table(); - /* - * This function should not be used to modify attributes - * other than writable/executable. - */ - - if ((attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_XP)) != 0) - return EFI_INVALID_PARAMETER; - - /* - * Disallow simultaniously executable and writable memory - * to inforce W^X policy if direct extraction code is enabled. - */ - - if ((attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) { - efi_warn("W^X violation at [%08lx,%08lx]\n", - (unsigned long)rounded_start, - (unsigned long)rounded_end); + if (!efi_dxe_table) + return EFI_UNSUPPORTED; } - rounded_start = rounddown(start, EFI_PAGE_SIZE); - rounded_end = roundup(start + size, EFI_PAGE_SIZE); - /* * Don't modify memory region attributes, they are * already suitable, to lower the possibility to * encounter firmware bugs. */ - for (end = start + size; start < end; start = next) { + + for (start = rounded_start, end = rounded_end; start < end; start = next) { status = efi_dxe_call(get_memory_space_descriptor, start, &desc); if (status != EFI_SUCCESS) { efi_warn("Unable to get memory descriptor at %lx\n", - start); + (unsigned long)start); return status; } @@ -227,3 +211,107 @@ efi_status_t efi_adjust_memory_range_protection(unsigned long start, return EFI_SUCCESS; } + +static void retrieve_memory_attributes_proto(void) +{ + efi_status_t status; + efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; + + status = efi_bs_call(locate_protocol, &guid, NULL, + (void **)&efi_mem_attrib_proto); + if (status != EFI_SUCCESS) + efi_mem_attrib_proto = NULL; +} + +/** + * efi_adjust_memory_range_protection() - change memory range protection attributes + * @start: memory range start address + * @size: memory range size + * + * Actual memory range for which memory attributes are modified is + * the smallest ranged with start address and size aligned to EFI_PAGE_SIZE + * that includes [start, start + size]. + * + * This function first attempts to use EFI_MEMORY_ATTRIBUTE_PROTOCOL, + * that is a part of UEFI Specification since version 2.10. + * If the protocol is unavailable it falls back to DXE services functions. + * + * @return: status code + */ +efi_status_t efi_adjust_memory_range_protection(unsigned long start, + unsigned long size, + unsigned long attributes) +{ + efi_status_t status; + efi_physical_addr_t rounded_start, rounded_end; + unsigned long attr_clear; + + /* + * This function should not be used to modify attributes + * other than writable/executable. + */ + + if ((attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_XP)) != 0) + return EFI_INVALID_PARAMETER; + + /* + * Warn if requested to make memory simultaneously + * executable and writable to enforce W^X policy. + */ + + if ((attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0) { + efi_warn("W^X violation at [%08lx,%08lx]", + (unsigned long)rounded_start, + (unsigned long)rounded_end); + } + + rounded_start = rounddown(start, EFI_PAGE_SIZE); + rounded_end = roundup(start + size, EFI_PAGE_SIZE); + + if (!efi_mem_attrib_proto) { + retrieve_memory_attributes_proto(); + + /* Fall back to DXE services if unsupported */ + if (!efi_mem_attrib_proto) { + return adjust_mem_attrib_dxe(rounded_start, + rounded_end, + attributes); + } + } + + /* + * Unlike DXE services functions, EFI_MEMORY_ATTRIBUTE_PROTOCOL + * does not clear unset protection bit, so it needs to be cleared + * explcitly + */ + + attr_clear = ~attributes & + (EFI_MEMORY_RO | EFI_MEMORY_XP | EFI_MEMORY_RP); + + status = efi_call_proto(efi_mem_attrib_proto, + clear_memory_attributes, + rounded_start, + rounded_end - rounded_start, + attr_clear); + if (status != EFI_SUCCESS) { + efi_warn("Failed to clear memory attributes at [%08lx,%08lx]: %lx", + (unsigned long)rounded_start, + (unsigned long)rounded_end, + status); + return status; + } + + status = efi_call_proto(efi_mem_attrib_proto, + set_memory_attributes, + rounded_start, + rounded_end - rounded_start, + attributes); + if (status != EFI_SUCCESS) { + efi_warn("Failed to set memory attributes at [%08lx,%08lx]: %lx", + (unsigned long)rounded_start, + (unsigned long)rounded_end, + status); + } + + return status; +} diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 56b8e7207361..eac55e9a5723 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -23,7 +23,6 @@ #define MAXMEM_X86_64_4LEVEL (1ull << 46) const efi_system_table_t *efi_system_table; -const efi_dxe_services_table_t *efi_dxe_table; extern u32 image_offset; static efi_loaded_image_t *image __section(".data"); @@ -357,15 +356,6 @@ void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) static void setup_sections_memory_protection(unsigned long image_base) { #ifdef CONFIG_EFI_DXE_MEM_ATTRIBUTES - efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); - - if (!efi_dxe_table || - efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { - efi_warn("Unable to locate EFI DXE services table\n"); - efi_dxe_table = NULL; - return; - } - /* .setup [image_base, _head] */ efi_adjust_memory_range_protection(image_base, (unsigned long)_head - image_base, @@ -732,13 +722,6 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) efi_exit(handle, EFI_INVALID_PARAMETER); - efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); - if (efi_dxe_table && - efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { - efi_warn("Ignoring DXE services table: invalid signature\n"); - efi_dxe_table = NULL; - } - setup_sections_memory_protection(bzimage_addr - image_offset); #ifdef CONFIG_CMDLINE_BOOL