From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, Ard Biesheuvel <ardb@kernel.org>,
Arnd Bergmann <arnd@arndb.de>,
Eric Biederman <ebiederm@xmission.com>,
kexec@lists.infradead.org, Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Kees Cook <keescook@chromium.org>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
Masahiro Yamada <masahiroy@kernel.org>
Subject: [RFC PATCH 7/9] x86/purgatory: Use fully linked PIE ELF executable
Date: Wed, 24 Apr 2024 17:53:17 +0200 [thread overview]
Message-ID: <20240424155309.1719454-18-ardb+git@google.com> (raw)
In-Reply-To: <20240424155309.1719454-11-ardb+git@google.com>
From: Ard Biesheuvel <ardb@kernel.org>
Now that the generic support is in place, switch to a fully linked PIE
ELF executable for the purgatory, so that it can be loaded as a single,
fully relocated image. This allows a lot of ugly post-processing logic
to simply be dropped.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/include/asm/kexec.h | 7 --
arch/x86/kernel/machine_kexec_64.c | 127 --------------------
arch/x86/purgatory/Makefile | 14 +--
3 files changed, 5 insertions(+), 143 deletions(-)
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index ee7b32565e5f..c7cacc2e9dfb 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -191,13 +191,6 @@ void arch_kexec_unprotect_crashkres(void);
#define arch_kexec_unprotect_crashkres arch_kexec_unprotect_crashkres
#ifdef CONFIG_KEXEC_FILE
-struct purgatory_info;
-int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
- Elf_Shdr *section,
- const Elf_Shdr *relsec,
- const Elf_Shdr *symtab);
-#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add
-
int arch_kimage_file_post_load_cleanup(struct kimage *image);
#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
#endif
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index bc0a5348b4a6..ded924423e50 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -371,133 +371,6 @@ void machine_kexec(struct kimage *image)
/* arch-dependent functionality related to kexec file-based syscall */
#ifdef CONFIG_KEXEC_FILE
-/*
- * Apply purgatory relocations.
- *
- * @pi: Purgatory to be relocated.
- * @section: Section relocations applying to.
- * @relsec: Section containing RELAs.
- * @symtabsec: Corresponding symtab.
- *
- * TODO: Some of the code belongs to generic code. Move that in kexec.c.
- */
-int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
- Elf_Shdr *section, const Elf_Shdr *relsec,
- const Elf_Shdr *symtabsec)
-{
- unsigned int i;
- Elf64_Rela *rel;
- Elf64_Sym *sym;
- void *location;
- unsigned long address, sec_base, value;
- const char *strtab, *name, *shstrtab;
- const Elf_Shdr *sechdrs;
-
- /* String & section header string table */
- sechdrs = (void *)pi->ehdr + pi->ehdr->e_shoff;
- strtab = (char *)pi->ehdr + sechdrs[symtabsec->sh_link].sh_offset;
- shstrtab = (char *)pi->ehdr + sechdrs[pi->ehdr->e_shstrndx].sh_offset;
-
- rel = (void *)pi->ehdr + relsec->sh_offset;
-
- pr_debug("Applying relocate section %s to %u\n",
- shstrtab + relsec->sh_name, relsec->sh_info);
-
- for (i = 0; i < relsec->sh_size / sizeof(*rel); i++) {
-
- /*
- * rel[i].r_offset contains byte offset from beginning
- * of section to the storage unit affected.
- *
- * This is location to update. This is temporary buffer
- * where section is currently loaded. This will finally be
- * loaded to a different address later, pointed to by
- * ->sh_addr. kexec takes care of moving it
- * (kexec_load_segment()).
- */
- location = pi->purgatory_buf;
- location += section->sh_offset;
- location += rel[i].r_offset;
-
- /* Final address of the location */
- address = section->sh_addr + rel[i].r_offset;
-
- /*
- * rel[i].r_info contains information about symbol table index
- * w.r.t which relocation must be made and type of relocation
- * to apply. ELF64_R_SYM() and ELF64_R_TYPE() macros get
- * these respectively.
- */
- sym = (void *)pi->ehdr + symtabsec->sh_offset;
- sym += ELF64_R_SYM(rel[i].r_info);
-
- if (sym->st_name)
- name = strtab + sym->st_name;
- else
- name = shstrtab + sechdrs[sym->st_shndx].sh_name;
-
- pr_debug("Symbol: %s info: %02x shndx: %02x value=%llx size: %llx\n",
- name, sym->st_info, sym->st_shndx, sym->st_value,
- sym->st_size);
-
- if (sym->st_shndx == SHN_UNDEF) {
- pr_err("Undefined symbol: %s\n", name);
- return -ENOEXEC;
- }
-
- if (sym->st_shndx == SHN_COMMON) {
- pr_err("symbol '%s' in common section\n", name);
- return -ENOEXEC;
- }
-
- if (sym->st_shndx == SHN_ABS)
- sec_base = 0;
- else if (sym->st_shndx >= pi->ehdr->e_shnum) {
- pr_err("Invalid section %d for symbol %s\n",
- sym->st_shndx, name);
- return -ENOEXEC;
- } else
- sec_base = pi->sechdrs[sym->st_shndx].sh_addr;
-
- value = sym->st_value;
- value += sec_base;
- value += rel[i].r_addend;
-
- switch (ELF64_R_TYPE(rel[i].r_info)) {
- case R_X86_64_NONE:
- break;
- case R_X86_64_64:
- *(u64 *)location = value;
- break;
- case R_X86_64_32:
- *(u32 *)location = value;
- if (value != *(u32 *)location)
- goto overflow;
- break;
- case R_X86_64_32S:
- *(s32 *)location = value;
- if ((s64)value != *(s32 *)location)
- goto overflow;
- break;
- case R_X86_64_PC32:
- case R_X86_64_PLT32:
- value -= (u64)address;
- *(u32 *)location = value;
- break;
- default:
- pr_err("Unknown rela relocation: %llu\n",
- ELF64_R_TYPE(rel[i].r_info));
- return -ENOEXEC;
- }
- }
- return 0;
-
-overflow:
- pr_err("Overflow in relocation type %d value 0x%lx\n",
- (int)ELF64_R_TYPE(rel[i].r_info), value);
- return -ENOEXEC;
-}
-
int arch_kimage_file_post_load_cleanup(struct kimage *image)
{
vfree(image->elf_headers);
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 2df4a4b70ff5..acc09799af2a 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -26,12 +26,11 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS))
# Drop the function entry padding, which is not needed here
KBUILD_CFLAGS := $(filter-out $(PADDING_CFLAGS),$(KBUILD_CFLAGS))
-# When linking purgatory.ro with -r unresolved symbols are not checked,
-# also link a purgatory.chk binary without -r to check for unresolved symbols.
PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
-LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
-LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
-targets += purgatory.ro purgatory.chk
+PURGATORY_LDFLAGS += -T $(srctree)/include/asm-generic/purgatory.lds -pie
+PURGATORY_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
+LDFLAGS_purgatory.ro := $(PURGATORY_LDFLAGS)
+targets += purgatory.ro
# Sanitizer, etc. runtimes are unavailable and cannot be linked here.
GCOV_PROFILE := n
@@ -87,9 +86,6 @@ asflags-remove-y += $(foreach x, -g -gdwarf-4 -gdwarf-5, $(x) -Wa,$(x))
$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
$(call if_changed,ld)
-$(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
- $(call if_changed,ld)
-
-$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro $(obj)/purgatory.chk
+$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro
obj-y += kexec-purgatory.o
--
2.44.0.769.g3c40516874-goog
next prev parent reply other threads:[~2024-04-24 15:53 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-24 15:53 [RFC PATCH 0/9] kexec x86 purgatory cleanup Ard Biesheuvel
2024-04-24 15:53 ` [RFC PATCH 1/9] x86/purgatory: Drop function entry padding from purgatory Ard Biesheuvel
2024-04-24 15:53 ` [RFC PATCH 2/9] x86/purgatory: Simplify stack handling Ard Biesheuvel
2024-04-24 18:26 ` Nathan Chancellor
2024-04-26 21:32 ` Justin Stitt
2024-04-26 21:53 ` Nathan Chancellor
2024-04-26 22:01 ` Justin Stitt
2024-04-24 15:53 ` [RFC PATCH 3/9] x86/purgatory: Drop pointless GDT switch Ard Biesheuvel
2024-04-24 15:53 ` [RFC PATCH 4/9] x86/purgatory: Avoid absolute reference to GDT Ard Biesheuvel
2024-04-24 17:38 ` Brian Gerst
2024-04-24 17:53 ` Ard Biesheuvel
2024-04-24 19:00 ` Brian Gerst
2024-04-24 15:53 ` [RFC PATCH 5/9] x86/purgatory: Simplify GDT and drop data segment Ard Biesheuvel
2024-04-24 15:53 ` [RFC PATCH 6/9] kexec: Add support for fully linked purgatory executables Ard Biesheuvel
2024-04-24 15:53 ` Ard Biesheuvel [this message]
2024-04-24 15:53 ` [RFC PATCH 8/9] x86/purgatory: Simplify references to regs array Ard Biesheuvel
2024-04-24 15:53 ` [RFC PATCH 9/9] kexec: Drop support for partially linked purgatory executables Ard Biesheuvel
2024-04-24 20:04 ` [RFC PATCH 0/9] kexec x86 purgatory cleanup Eric W. Biederman
2024-04-24 20:52 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240424155309.1719454-18-ardb+git@google.com \
--to=ardb+git@google.com \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=ebiederm@xmission.com \
--cc=justinstitt@google.com \
--cc=keescook@chromium.org \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masahiroy@kernel.org \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).