Received: by 2002:a89:48b:0:b0:1f5:f2ab:c469 with SMTP id a11csp514499lqd; Wed, 24 Apr 2024 08:55:06 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCW0B2efclVlwJF09H3Dw+NPx3gRjiYyNXKOlZDVMAvHzLXhdzTdT8TmerfcxfOn/UV18Le9u1FO4SlWNhGEiE0fnOAvst/yXSuy/Kr+2A== X-Google-Smtp-Source: AGHT+IFUiqWv0UlWFbegIbEd1R38QJP1IWkdc4q+iq7pUCN77igELFHZC2iufrz3iOUhL/BuzhuM X-Received: by 2002:a17:906:40d1:b0:a52:6721:f276 with SMTP id a17-20020a17090640d100b00a526721f276mr1944992ejk.19.1713974105916; Wed, 24 Apr 2024 08:55:05 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713974105; cv=pass; d=google.com; s=arc-20160816; b=EGdZfNI2Nn0AZhAwXY3BW5I5mp+Z8m/JJRJ61yZbkPEf270ML8QSvvsXRn346azi0n CYloPpQKATKMutWR5FV5sm74KDdh8s8GR3b5BSmA4w5QeFbitKtH9UV1GWUf/JzUhLEu JXqqmm5rTI0UtpxaN749z+DNmtrJfobwPm5NrgqcR2pXQWPkOIIULJP+7w0peNXb29kF 4lj+5amu7Pe8SwvKQ48+0ne+GcwfBVXitNFxMYuzS4MXGEL9pPNHd7XAPcfN2sbCakUZ ic2nHrWoxNDRT0xHJcInvhtFoTu0wefAMBitGCcDOisYeSts87wwxg4MeD6miLztTZ/z 6CtA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :dkim-signature; bh=pEfb48Zw4FzaI31A4Yvo9b2JQcLeZ9Sid/iFgPsmsBc=; fh=FsvQoRfUYCb7YWgVN8g3QkTLNjgBrJZxscq7eE3+/Gs=; b=IBmeAhwydgH5a58EvtNRlPV6DkuN8RVaw5Q+3hIMwTGWtVCmeIfj7eYT1sVsAlIFNd a7UnpWINivZHSGp5E+emmh1UpMeYmeEQnzineEK0vMK4VA2usH/k8Ag5Pe8nmhDF6O5O 8ivg0Ta5uGAl03/rPAvluBCt5O/AlJQ4xCC3cPcIadlQqyz1vIJz4rYUAibRbpjQG0SH ijAENN2B64XtJ/2JaGosIw5EDP5mrEA4/wgeOICWFOwGdNnVkYPWv5zOsks1wEx/7HKL hnIQs1dvghG8w+mg+Crk1pGdUHmHnHU14rm65IxdgSVnWskyOwqAcK2JJNeXgePeaQN7 7PZg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="Rv/pDXj7"; arc=pass (i=1 spf=pass spfdomain=flex--ardb.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-157259-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-157259-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id gb35-20020a170907962300b00a526a7a6428si9398461ejc.221.2024.04.24.08.55.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Apr 2024 08:55:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-157259-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b="Rv/pDXj7"; arc=pass (i=1 spf=pass spfdomain=flex--ardb.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-157259-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-157259-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 7CB971F22CA6 for ; Wed, 24 Apr 2024 15:55:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 95CE016D31D; Wed, 24 Apr 2024 15:53:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Rv/pDXj7" Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 194A316C874 for ; Wed, 24 Apr 2024 15:53:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713974029; cv=none; b=V21pfgn+lQX18vlzo2W31bhXpUGNVti1c1VFBAIwCpTcAhM8ERthUVrw1VwkuK4toSMbeB8WJRs+skG8/gfx87JNKwUZKcmHis4ITgzbIxrLeuukYi/jDSK1WTWXjljJ++iIDN1efECPbIXUI2cXsrikfNSNfEy1ZbHB/rrPbQU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713974029; c=relaxed/simple; bh=1+VCxIzQcdwbTGlX9e1o9EFbgAwdNaFUnQJi6aPn/k4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=UC0nhDMva21jIOR9+7NpWXQn3U3PVaaZoEEQ80evPOUB6PmBvJANdj+FFel1iutZo0B+0PkvFlP+egKnv5jANWC/gT1Hl5DRpEiAe3huTTS6tpqILxQejEYzrYn8GS8Pg6fj4w7BYnLEYatQB8SNjgqxQthlSm28Hlo14fsotzc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Rv/pDXj7; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-de5823bd7eeso137744276.0 for ; Wed, 24 Apr 2024 08:53:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1713974027; x=1714578827; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=pEfb48Zw4FzaI31A4Yvo9b2JQcLeZ9Sid/iFgPsmsBc=; b=Rv/pDXj7oa9+h99JFEYoIkhTwaWpzk+3tbBLCUgiN73/tt+MPr3bbo8GIRt6QnuME7 /pS6UR8NBQ/wFkdIYR/4jHw4o87O/BjRHJEbMpHkCfJoAXhnP6UVgmEmlSomJSYJRoaM JwqSZtyzUEF1/TDDoHAGMsYLWiZgkknvOhHDbVOulG9eemaAiNIoCPikkQdx2CHOsqja mD6Ubaop7QynWzSNqAxw5+FD5CTOnQRWVNl5EK9eU6bwl0ry9yDPHKIb/0Iy00i5NF9k +3CbAPpSmF4L2KTv6tBaeD/tMD/wqtv6WQ9oPToh5MKvlC/afQvAxItwAI4RICY9v4iB +8iw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713974027; x=1714578827; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=pEfb48Zw4FzaI31A4Yvo9b2JQcLeZ9Sid/iFgPsmsBc=; b=RTluq9BwvcGGtqsr5n8lkdRsFCgBoRryj6byo2SyXnOBKLvvCZCBe5f243hfIqh9Ca ZTFp6LdK19uIDNkKnmI7c8j0QROaPMGzdexpclxfh/FBuSc+rVkFgsd3/a9rsTnqMKrt E24Y8D3yw0fjg2JGkgFN4a6mpHXCul1gQS9bYXUfrOp7YjA+Hk+8c4tdVeelynYvNWL9 d9oDzhnnM7mZwrUXEmVtufkXgewQQBbfvbvF0bE7PJiL950A0UzKWkAwS8hqZ7ssYddh MCc/CraovIU7MZoFYZKWI7lXcu6bfQWie4vYiMKX7NRHFNP6+I/u3fnKfBgkXyVuaGMn +jnw== X-Gm-Message-State: AOJu0Yw5VIOFhxsc+LIbpegJH71hdDo03XOLcazAO4FBBmcKAy8p3Jn3 uB5iYfZ6b+s5cfjSM/dNactABRBl+un2vF2GvcJYlAOPxwk3iwRCasByhta7DbiYt18uv++iPdt yqgyAPhj84gpeIM2YTw4QRt8wcYC0FR5MO9UjbT69R7sMWpNRuG57hxJNhYQZ13aE3hx07JOTZD +fb8kjIMIZ9ESR9zAqXG1om3pwl+Bgkw== X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:a25:c789:0:b0:dc6:b7c2:176e with SMTP id w131-20020a25c789000000b00dc6b7c2176emr4995ybe.4.1713974026968; Wed, 24 Apr 2024 08:53:46 -0700 (PDT) Date: Wed, 24 Apr 2024 17:53:16 +0200 In-Reply-To: <20240424155309.1719454-11-ardb+git@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240424155309.1719454-11-ardb+git@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=5039; i=ardb@kernel.org; h=from:subject; bh=KbB2fMI6RaaNb9qTs1/na+POkGeoOZURr4jcCaqB+Qw=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIU1T682aCbcVWayP97etXvKAe1Jmc/WfuFq7S1nTRTJ6I l8KH37YUcrCIMbBICumyCIw+++7nacnStU6z5KFmcPKBDKEgYtTACYS3sbIMD2FX52rem5U7pXq ytRHu2telH5M9vvg/i9Rb8nzrNCCIIb//kdzNfTuXL6vFdr7TXl/9bSzqhs+GpQ9eRf68MvGBJ4 +fgA= X-Mailer: git-send-email 2.44.0.769.g3c40516874-goog Message-ID: <20240424155309.1719454-17-ardb+git@google.com> Subject: [RFC PATCH 6/9] kexec: Add support for fully linked purgatory executables From: Ard Biesheuvel To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, Ard Biesheuvel , Arnd Bergmann , Eric Biederman , kexec@lists.infradead.org, Nathan Chancellor , Nick Desaulniers , Kees Cook , Bill Wendling , Justin Stitt , Masahiro Yamada Content-Type: text/plain; charset="UTF-8" From: Ard Biesheuvel The purgatory ELF object is typically a partially linked object, which puts the burden on the kexec loader to lay out the executable in memory, and this involves (among other things) deciding the placement of the sections in memory, and fixing up all relocations (relative and absolute ones) All of this can be greatly simplified by using a fully linked PIE ELF executable instead, constructed in a way that removes the need for any relocation processing or layout and allocation of individual sections. By gathering all allocatable sections into a single PT_LOAD segment, and relying on RIP-relative references, all relocations will be applied by the linker, and the segment simply needs to be copied into memory. So add a linker script and some minimal handling in generic code, which can be used by architectures to opt into this approach. This will be wired up for x86 in a subsequent patch. Signed-off-by: Ard Biesheuvel --- include/asm-generic/purgatory.lds | 34 ++++++++++ kernel/kexec_file.c | 68 +++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/include/asm-generic/purgatory.lds b/include/asm-generic/purgatory.lds new file mode 100644 index 000000000000..260c457f7608 --- /dev/null +++ b/include/asm-generic/purgatory.lds @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +PHDRS +{ + text PT_LOAD FLAGS(7) FILEHDR PHDRS; +} + +SECTIONS +{ + . = SIZEOF_HEADERS; + + .text : { + *(.text .rodata* .kexec-purgatory .data*) + } :text + + .bss : { + *(.bss .dynbss) + } :text + + .rela.dyn : { + *(.rela.*) + } + + .symtab 0 : { *(.symtab) } + .strtab 0 : { *(.strtab) } + .shstrtab 0 : { *(.shstrtab) } + + /DISCARD/ : { + *(.interp .modinfo .dynsym .dynstr .hash .gnu.* .dynamic .comment) + *(.got .plt .got.plt .plt.got .note.* .eh_frame .sframe) + } +} + +ASSERT(SIZEOF(.rela.dyn) == 0, "Absolute relocations detected"); diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index bef2f6f2571b..6379f8dfc29f 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -1010,6 +1010,62 @@ static int kexec_apply_relocations(struct kimage *image) return 0; } +/* + * kexec_load_purgatory_pie - Load the position independent purgatory object. + * @pi: Purgatory info struct. + * @kbuf: Memory parameters to use. + * + * Load a purgatory PIE executable. This is a fully linked executable + * consisting of a single PT_LOAD segment that does not require any relocation + * processing. + * + * Return: 0 on success, negative errno on error. + */ +static int kexec_load_purgatory_pie(struct purgatory_info *pi, + struct kexec_buf *kbuf) +{ + const Elf_Phdr *phdr = (void *)pi->ehdr + pi->ehdr->e_phoff; + int ret; + + if (pi->ehdr->e_phnum != 1) + return -EINVAL; + + kbuf->bufsz = phdr->p_filesz; + kbuf->memsz = phdr->p_memsz; + kbuf->buf_align = phdr->p_align; + + kbuf->buffer = vzalloc(kbuf->bufsz); + if (!kbuf->buffer) + return -ENOMEM; + + ret = kexec_add_buffer(kbuf); + if (ret) + goto out_free_kbuf; + + kbuf->image->start = kbuf->mem + pi->ehdr->e_entry; + + pi->sechdrs = vcalloc(pi->ehdr->e_shnum, pi->ehdr->e_shentsize); + if (!pi->sechdrs) + goto out_free_kbuf; + + pi->purgatory_buf = memcpy(kbuf->buffer, + (void *)pi->ehdr + phdr->p_offset, + kbuf->bufsz); + + memcpy(pi->sechdrs, (void *)pi->ehdr + pi->ehdr->e_shoff, + pi->ehdr->e_shnum * pi->ehdr->e_shentsize); + + for (int i = 0; i < pi->ehdr->e_shnum; i++) + if (pi->sechdrs[i].sh_flags & SHF_ALLOC) + pi->sechdrs[i].sh_addr += kbuf->mem; + + return 0; + +out_free_kbuf: + vfree(kbuf->buffer); + return ret; +} + /* * kexec_load_purgatory - Load and relocate the purgatory object. * @image: Image to add the purgatory to. @@ -1031,6 +1087,9 @@ int kexec_load_purgatory(struct kimage *image, struct kexec_buf *kbuf) pi->ehdr = (const Elf_Ehdr *)kexec_purgatory; + if (pi->ehdr->e_type != ET_REL) + return kexec_load_purgatory_pie(pi, kbuf); + ret = kexec_purgatory_setup_kbuf(pi, kbuf); if (ret) return ret; @@ -1087,7 +1146,8 @@ static const Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi, /* Go through symbols for a match */ for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) { - if (ELF_ST_BIND(syms[k].st_info) != STB_GLOBAL) + if (pi->ehdr->e_type == ET_REL && + ELF_ST_BIND(syms[k].st_info) != STB_GLOBAL) continue; if (strcmp(strtab + syms[k].st_name, name) != 0) @@ -1159,6 +1219,12 @@ int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name, sym_buf = (char *)pi->purgatory_buf + sec->sh_offset + sym->st_value; + if (pi->ehdr->e_type != ET_REL) { + const Elf_Shdr *shdr = (void *)pi->ehdr + pi->ehdr->e_shoff; + + sym_buf -= shdr[sym->st_shndx].sh_addr; + } + if (get_value) memcpy((void *)buf, sym_buf, size); else -- 2.44.0.769.g3c40516874-goog