From patchwork Mon Jan 30 15:13:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 92874 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp1484329qgi; Mon, 30 Jan 2017 07:14:47 -0800 (PST) X-Received: by 10.99.99.5 with SMTP id x5mr24360117pgb.225.1485789287835; Mon, 30 Jan 2017 07:14:47 -0800 (PST) Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id d17si8679250pgh.312.2017.01.30.07.14.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 30 Jan 2017 07:14:47 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cYDfK-0006Nb-46; Mon, 30 Jan 2017 15:14:46 +0000 Received: from mail-wj0-f181.google.com ([209.85.210.181]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cYDfF-0006Kr-IQ for linux-arm-kernel@lists.infradead.org; Mon, 30 Jan 2017 15:14:44 +0000 Received: by mail-wj0-f181.google.com with SMTP id uo9so6819073wjc.1 for ; Mon, 30 Jan 2017 07:14:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=aBrwkA0YsgcJakSOACW/yznCr9tsVEvp+13n11/08J0=; b=X0ngnDbLXjOYNQ7dB9R7EkQw2eI20Kr0F4LaK6ipeg8KAA+/pzYsNfjdXqlery7L13 FO/UKllfoN31SLrDd33bjdMBLVDhtzWO0i/6rJclEaEEuYxnxOniNXSDtVU0fWn1jZL1 oWQ9zbAx0L6BFCTHZNe02R2oF5tIF1+jLXF9g= 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=aBrwkA0YsgcJakSOACW/yznCr9tsVEvp+13n11/08J0=; b=AS6NhRWTLCSmhT9jOfd/Sizq1mzJnAC79UKhcOOeo12JGGvQ9fiZLtkgFXYgif9JC0 pi1ZvhchCb9WS4g3WnKHqPl28OK1pxs+f4tQbnj2fPw6ZCKRerz9TaGWCvf4mvAo/hw7 DUpE4cohzVNssbIvKOlp4c/vo1ygO2K6q5F3yKaA/ZE4iYF80ckOuU3SjSfd6xfWX0it BlAww/SVmu0w5xxdXTBro7XLmrYxvxsMKQ4Yyfb6KhwZsHDzE+pB6xwk5FBU+zVsGO0L BCXiIUGKsLDsIK6Bl3tjAc8h8gCXY5sb0pwrEFH6j3Rk/x1+5ku10m//0cOuvSK2FWTc idAQ== X-Gm-Message-State: AIkVDXJAnF2SbLvPMO/KwJTEuyCvhzuRU7dd99rucfqJ2f89dG8jKAQtCBbGNwXaas/DRdLw X-Received: by 10.223.173.181 with SMTP id w50mr18883227wrc.177.1485789199006; Mon, 30 Jan 2017 07:13:19 -0800 (PST) Received: from localhost.localdomain ([105.130.17.13]) by smtp.gmail.com with ESMTPSA id p7sm23176078wrc.2.2017.01.30.07.13.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 30 Jan 2017 07:13:18 -0800 (PST) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, linux@armlinux.org.uk, catalin.marinas@arm.com Subject: [PATCH v2] arm: module: handle negative R_ARM_PREL31 addends correctly Date: Mon, 30 Jan 2017 15:13:12 +0000 Message-Id: <1485789192-6218-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170130_071441_769305_AA2AF05E X-CRM114-Status: GOOD ( 12.35 ) X-Spam-Score: -1.5 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.5 RCVD_IN_SORBS_SPAM RBL: SORBS: sender is a spam source [209.85.210.181 listed in dnsbl.sorbs.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [209.85.210.181 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.210.181 listed in wl.mailspike.net] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ard Biesheuvel MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org According to the spec 'ELF for the ARM Architecture' (IHI 0044E), addends for R_ARM_PREL31 relocations are 31-bit signed quantities, so we need to sign extend the value to 32 bits before it can be used as an offset in the calculation of the relocated value. We have not been bitten by this because these relocations are usually emitted against the start of a section, which means the addends never assume negative values in practice. But it is a bug nonetheless, so fix it. Signed-off-by: Ard Biesheuvel --- v2: preserve bit 31 of the relocation target arch/arm/kernel/module.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 4f14b5ce6535..80254b47dc34 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -155,8 +155,17 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, break; case R_ARM_PREL31: - offset = *(u32 *)loc + sym->st_value - loc; - *(u32 *)loc = offset & 0x7fffffff; + offset = (*(s32 *)loc << 1) >> 1; /* sign extend */ + offset += sym->st_value - loc; + if (offset >= 0x40000000 || offset < -0x40000000) { + pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", + module->name, relindex, i, symname, + ELF32_R_TYPE(rel->r_info), loc, + sym->st_value); + return -ENOEXEC; + } + *(u32 *)loc &= 0x80000000; + *(u32 *)loc |= offset & 0x7fffffff; break; case R_ARM_MOVW_ABS_NC: