From patchwork Mon Dec 16 04:58:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1210084 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47bpvx1qnyz9sPn for ; Mon, 16 Dec 2019 15:59:09 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mAN+XSJr"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 47bpvw4lG4zDqHZ for ; Mon, 16 Dec 2019 15:59:08 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::444; helo=mail-pf1-x444.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mAN+XSJr"; dkim-atps=neutral Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 47bpvm3KvyzDqS8 for ; Mon, 16 Dec 2019 15:59:00 +1100 (AEDT) Received: by mail-pf1-x444.google.com with SMTP id h14so3009370pfe.10 for ; Sun, 15 Dec 2019 20:59:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=DZN6N2Lh2LK7R5yG54S3SumHm4ZulYqTbxpfwfb7yoU=; b=mAN+XSJr7Yc5XpRAZl6q8qWdFnFieekzYcC5S6uzAvGX+3hiL26wQ44/5p2WmrKf9P f/vjxFwrK1JgUVRKFKCyM+qK2IkkV5/h09eXkSeK30hww73q/Aah6PTSfkea0Qx052qt m9X4pv4j6fAM+oIGzT8hR+5N2wj+zcYDgDF0vkY6Pnq2YVhXasoI3jbfgUYOxrhRyx4e W4ni0Wl6eN3hO5kUg+4GFmzxJY1d5MW0WUOxB8conzFXhmIWDGCg1sdk/pH7tKTSYAPw IkW3Usbykr2DFJaApMI+tLn0NMhphG53NFyqznzAtlMWjbSI5m5ISZ7xGcZn/dPEatVO 608A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=DZN6N2Lh2LK7R5yG54S3SumHm4ZulYqTbxpfwfb7yoU=; b=A4EdC+C7sgR33SPbEGAfgIp0TB2fNt3lzsAvIIpj8SZ+h8AJzdG5kcZwM77LLRmHLD NcjiwUPSaX9QxNOwrp8qrG0FUBpugWw4MCAO4hiaNEaKl1g9mGfLKAMFrO67IecWXf4W 4jL+2Rppfdh6Wf2+J2ujN8p55SOqa7WXAHCeI0oVuaqCPigG7U0NNxVmz0/xF3AxTJLk /IDaoK4t+t2zDc/LJ5o5cTIeQ5FiG/hH2mgpTJ0RrC2RBDc8ZgFZvMZeMtLedvnJqGPP FZo6RhjIcjkKfSBpZfJb8Tw0nrgxj24Zl2OsS0+z0yYCyAI0yZ14en9ZkAaxVlWYMlv/ FHgQ== X-Gm-Message-State: APjAAAU6sFmoQmoDyh/exsQmxz/GfPsaKpodFZ+0hfhJ3xPhL9JGO/jn 0Gv5LpWqT9DgH/Gwv/GmPNb92guj X-Google-Smtp-Source: APXvYqx3dVIKRMDXv72Ld51QQ07edC+DxjNDErcgjweARH8cTYhr4ei1h7fjhXfwF47YRml/E/L9qg== X-Received: by 2002:a63:3e03:: with SMTP id l3mr16035447pga.118.1576472336099; Sun, 15 Dec 2019 20:58:56 -0800 (PST) Received: from tee480.au.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id y128sm19842163pfg.17.2019.12.15.20.58.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Dec 2019 20:58:55 -0800 (PST) From: Jordan Niethe To: skiboot@lists.ozlabs.org Date: Mon, 16 Dec 2019 15:58:26 +1100 Message-Id: <20191216045826.18231-1-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [Skiboot] [PATCH] core/init: Check BE elf version before assuming behaviour X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" On big-endian, ELF ABIv1 is typically used. For ELF ABIv1, the entry point is a function description. However, for ELF ABIv2 the entry points directly at code. The big-endian loader assumes this behaviour regardless of what ELF ABI version is set in the elf's flags. This can result in entering at the wrong locations for non ABIv1 elfs. Add a check for the ELF ABI version before assuming ABIv1 behaviour. If no version is set, default to ELF ABIv2 behaviour - that is the entry points directly to code. Signed-off-by: Jordan Niethe --- core/init.c | 15 ++++++++++----- include/elf.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/core/init.c b/core/init.c index a7083456e5cb..ade91e07ba5b 100644 --- a/core/init.c +++ b/core/init.c @@ -183,11 +183,15 @@ static bool try_load_elf64(struct elf_hdr *header) return false; } - /* For the normal big-endian ELF ABI, the kernel entry points - * to a function descriptor in the data section. Linux instead - * has it point directly to code. Test whether it is pointing + /* On big-endian, typically ELF ABIv1 is used. With ELF ABIv1, + * the kernel entry points to a function descriptor in the + * data section. Linux instead has it point directly to code, + * which is ELF ABIv2 behaviour. + * + * If the ELF ABIv1 flag is set, test whether it is pointing * into an executable section or not to figure this out. Default - * to assuming it obeys the ABI. + * to assuming it obeys the ABI version set in its flags. If no + * ABI version is set, default to ELF ABIv2 behaviour. */ sh = (struct elf64_shdr *)(load_base + kh->e_shoff); for (i = 0; i < kh->e_shnum; i++, sh++) { @@ -196,7 +200,8 @@ static bool try_load_elf64(struct elf_hdr *header) break; } - if (i == kh->e_shnum || !(sh->sh_flags & ELF_SFLAGS_X)) { + if ((kh->e_flags & EF_ELF_ABI_V1) && + (i == kh->e_shnum || !(sh->sh_flags & ELF_SFLAGS_X))) { kernel_entry = *(uint64_t *)(kernel_entry + load_base); kernel_entry = kernel_entry - ph->p_vaddr + ph->p_offset; } diff --git a/include/elf.h b/include/elf.h index 93524bb99a4a..f981b374ea32 100644 --- a/include/elf.h +++ b/include/elf.h @@ -39,6 +39,8 @@ struct elf64_hdr { uint64_t e_phoff; uint64_t e_shoff; uint32_t e_flags; +#define EF_ELF_ABI_V1 0x1 +#define EF_ELF_ABI_V2 0x2 uint16_t e_ehsize; uint16_t e_phentsize; uint16_t e_phnum;