]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Apr 2024 07:11:10 +0000 (09:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Apr 2024 07:11:10 +0000 (09:11 +0200)
added patches:
x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch

queue-6.6/series
queue-6.6/x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch [new file with mode: 0644]

index 5c8b4d3b963e0a5e857fb2cb6bc0284b507233b6..7ad5f3f104712a5fb1098864ff4ab56be1f53d5d 100644 (file)
@@ -250,3 +250,4 @@ efi-libstub-add-generic-support-for-parsing-mem_encrypt.patch
 x86-sme-move-early-sme-kernel-encryption-handling-into-.head.text.patch
 x86-sev-move-early-startup-code-into-.head.text-section.patch
 x86-efistub-remap-kernel-text-read-only-before-dropping-nx-attribute.patch
+x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch
diff --git a/queue-6.6/x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch b/queue-6.6/x86-boot-move-mem_encrypt-parsing-to-the-decompressor.patch
new file mode 100644 (file)
index 0000000..b53d7ad
--- /dev/null
@@ -0,0 +1,194 @@
+From cd0d9d92c8bb46e77de62efd7df13069ddd61e7d Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Tue, 27 Feb 2024 16:19:14 +0100
+Subject: x86/boot: Move mem_encrypt= parsing to the decompressor
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit cd0d9d92c8bb46e77de62efd7df13069ddd61e7d upstream.
+
+The early SME/SEV code parses the command line very early, in order to
+decide whether or not memory encryption should be enabled, which needs
+to occur even before the initial page tables are created.
+
+This is problematic for a number of reasons:
+- this early code runs from the 1:1 mapping provided by the decompressor
+  or firmware, which uses a different translation than the one assumed by
+  the linker, and so the code needs to be built in a special way;
+- parsing external input while the entire kernel image is still mapped
+  writable is a bad idea in general, and really does not belong in
+  security minded code;
+- the current code ignores the built-in command line entirely (although
+  this appears to be the case for the entire decompressor)
+
+Given that the decompressor/EFI stub is an intrinsic part of the x86
+bootable kernel image, move the command line parsing there and out of
+the core kernel. This removes the need to build lib/cmdline.o in a
+special way, or to use RIP-relative LEA instructions in inline asm
+blocks.
+
+This involves a new xloadflag in the setup header to indicate
+that mem_encrypt=on appeared on the kernel command line.
+
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
+Tested-by: Tom Lendacky <thomas.lendacky@amd.com>
+Link: https://lore.kernel.org/r/20240227151907.387873-17-ardb+git@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/boot/compressed/misc.c         |   15 +++++++++++++++
+ arch/x86/include/uapi/asm/bootparam.h   |    1 +
+ arch/x86/lib/Makefile                   |   13 -------------
+ arch/x86/mm/mem_encrypt_identity.c      |   32 +++-----------------------------
+ drivers/firmware/efi/libstub/x86-stub.c |    3 +++
+ 5 files changed, 22 insertions(+), 42 deletions(-)
+
+--- a/arch/x86/boot/compressed/misc.c
++++ b/arch/x86/boot/compressed/misc.c
+@@ -359,6 +359,19 @@ unsigned long decompress_kernel(unsigned
+ }
+ /*
++ * Set the memory encryption xloadflag based on the mem_encrypt= command line
++ * parameter, if provided.
++ */
++static void parse_mem_encrypt(struct setup_header *hdr)
++{
++      int on = cmdline_find_option_bool("mem_encrypt=on");
++      int off = cmdline_find_option_bool("mem_encrypt=off");
++
++      if (on > off)
++              hdr->xloadflags |= XLF_MEM_ENCRYPTION;
++}
++
++/*
+  * 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
+  * image (VO) and the execution environment (.bss, .brk), which makes sure
+@@ -388,6 +401,8 @@ asmlinkage __visible void *extract_kerne
+       /* Clear flags intended for solely in-kernel use. */
+       boot_params->hdr.loadflags &= ~KASLR_FLAG;
++      parse_mem_encrypt(&boot_params->hdr);
++
+       sanitize_boot_params(boot_params);
+       if (boot_params->screen_info.orig_video_mode == 7) {
+--- a/arch/x86/include/uapi/asm/bootparam.h
++++ b/arch/x86/include/uapi/asm/bootparam.h
+@@ -38,6 +38,7 @@
+ #define XLF_EFI_KEXEC                 (1<<4)
+ #define XLF_5LEVEL                    (1<<5)
+ #define XLF_5LEVEL_ENABLED            (1<<6)
++#define XLF_MEM_ENCRYPTION            (1<<7)
+ #ifndef __ASSEMBLY__
+--- a/arch/x86/lib/Makefile
++++ b/arch/x86/lib/Makefile
+@@ -14,19 +14,6 @@ ifdef CONFIG_KCSAN
+ CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE)
+ endif
+-# Early boot use of cmdline; don't instrument it
+-ifdef CONFIG_AMD_MEM_ENCRYPT
+-KCOV_INSTRUMENT_cmdline.o := n
+-KASAN_SANITIZE_cmdline.o  := n
+-KCSAN_SANITIZE_cmdline.o  := n
+-
+-ifdef CONFIG_FUNCTION_TRACER
+-CFLAGS_REMOVE_cmdline.o = -pg
+-endif
+-
+-CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables
+-endif
+-
+ inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
+ inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
+ quiet_cmd_inat_tables = GEN     $@
+--- a/arch/x86/mm/mem_encrypt_identity.c
++++ b/arch/x86/mm/mem_encrypt_identity.c
+@@ -44,7 +44,6 @@
+ #include <asm/init.h>
+ #include <asm/setup.h>
+ #include <asm/sections.h>
+-#include <asm/cmdline.h>
+ #include <asm/coco.h>
+ #include <asm/sev.h>
+@@ -96,9 +95,6 @@ struct sme_populate_pgd_data {
+  */
+ static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch");
+-static char sme_cmdline_arg[] __initdata = "mem_encrypt";
+-static char sme_cmdline_on[]  __initdata = "on";
+-
+ static void __head sme_clear_pgd(struct sme_populate_pgd_data *ppd)
+ {
+       unsigned long pgd_start, pgd_end, pgd_size;
+@@ -496,11 +492,9 @@ void __head sme_encrypt_kernel(struct bo
+ void __head sme_enable(struct boot_params *bp)
+ {
+-      const char *cmdline_ptr, *cmdline_arg, *cmdline_on;
+       unsigned int eax, ebx, ecx, edx;
+       unsigned long feature_mask;
+       unsigned long me_mask;
+-      char buffer[16];
+       bool snp;
+       u64 msr;
+@@ -543,6 +537,9 @@ void __head sme_enable(struct boot_param
+       /* Check if memory encryption is enabled */
+       if (feature_mask == AMD_SME_BIT) {
++              if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION))
++                      return;
++
+               /*
+                * No SME if Hypervisor bit is set. This check is here to
+                * prevent a guest from trying to enable SME. For running as a
+@@ -562,31 +559,8 @@ void __head sme_enable(struct boot_param
+               msr = __rdmsr(MSR_AMD64_SYSCFG);
+               if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT))
+                       return;
+-      } else {
+-              /* SEV state cannot be controlled by a command line option */
+-              goto out;
+       }
+-      /*
+-       * Fixups have not been applied to phys_base yet and we're running
+-       * identity mapped, so we must obtain the address to the SME command
+-       * line argument data using rip-relative addressing.
+-       */
+-      asm ("lea sme_cmdline_arg(%%rip), %0"
+-           : "=r" (cmdline_arg)
+-           : "p" (sme_cmdline_arg));
+-      asm ("lea sme_cmdline_on(%%rip), %0"
+-           : "=r" (cmdline_on)
+-           : "p" (sme_cmdline_on));
+-
+-      cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
+-                                   ((u64)bp->ext_cmd_line_ptr << 32));
+-
+-      if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0 ||
+-          strncmp(buffer, cmdline_on, sizeof(buffer)))
+-              return;
+-
+-out:
+       RIP_REL_REF(sme_me_mask) = me_mask;
+       physical_mask &= ~me_mask;
+       cc_vendor = CC_VENDOR_AMD;
+--- a/drivers/firmware/efi/libstub/x86-stub.c
++++ b/drivers/firmware/efi/libstub/x86-stub.c
+@@ -897,6 +897,9 @@ void __noreturn efi_stub_entry(efi_handl
+               }
+       }
++      if (efi_mem_encrypt > 0)
++              hdr->xloadflags |= XLF_MEM_ENCRYPTION;
++
+       status = efi_decompress_kernel(&kernel_entry);
+       if (status != EFI_SUCCESS) {
+               efi_err("Failed to decompress kernel\n");