Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA1F3C433EF for ; Mon, 20 Dec 2021 15:01:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239228AbhLTPA6 (ORCPT ); Mon, 20 Dec 2021 10:00:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238561AbhLTOyZ (ORCPT ); Mon, 20 Dec 2021 09:54:25 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A21DC08EB37; Mon, 20 Dec 2021 06:47:50 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F042E611BE; Mon, 20 Dec 2021 14:47:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D5F24C36AE7; Mon, 20 Dec 2021 14:47:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1640011669; bh=GYR1Wgh0HO4YY+mBpA57RoUFz6fyYrJxzqkN0yCQXbQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MYamIYMANFjKIQixhyZtQWRg02WdnwM+b/wYmjBcygSjGdyjrPPZ+zEFEhDYqYwt+ 3XfN8i7mdsjzFFSlAizmV3RuTlFAdwpuhmxVbT5v1+tBUWj5h72pIT+UHLPKQyJeC2 MFyNOVxZ7n9sqPWxumzf4YawA0eJU7Z2K+TAWsUE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Tao Liu , Philipp Rudo , Heiko Carstens , Sasha Levin Subject: [PATCH 5.10 32/99] s390/kexec_file: fix error handling when applying relocations Date: Mon, 20 Dec 2021 15:34:05 +0100 Message-Id: <20211220143030.436956543@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211220143029.352940568@linuxfoundation.org> References: <20211220143029.352940568@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Philipp Rudo [ Upstream commit 41967a37b8eedfee15b81406a9f3015be90d3980 ] arch_kexec_apply_relocations_add currently ignores all errors returned by arch_kexec_do_relocs. This means that every unknown relocation is silently skipped causing unpredictable behavior while the relocated code runs. Fix this by checking for errors and fail kexec_file_load if an unknown relocation type is encountered. The problem was found after gcc changed its behavior and used R_390_PLT32DBL relocations for brasl instruction and relied on ld to resolve the relocations in the final link in case direct calls are possible. As the purgatory code is only linked partially (option -r) ld didn't resolve the relocations leaving them for arch_kexec_do_relocs. But arch_kexec_do_relocs doesn't know how to handle R_390_PLT32DBL relocations so they were silently skipped. This ultimately caused an endless loop in the purgatory as the brasl instructions kept branching to itself. Fixes: 71406883fd35 ("s390/kexec_file: Add kexec_file_load system call") Reported-by: Tao Liu Signed-off-by: Philipp Rudo Link: https://lore.kernel.org/r/20211208130741.5821-3-prudo@redhat.com Signed-off-by: Heiko Carstens Signed-off-by: Sasha Levin --- arch/s390/kernel/machine_kexec_file.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index e7435f3a3d2d2..76cd09879eaf4 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -277,6 +277,7 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, { Elf_Rela *relas; int i, r_type; + int ret; relas = (void *)pi->ehdr + relsec->sh_offset; @@ -311,7 +312,11 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi, addr = section->sh_addr + relas[i].r_offset; r_type = ELF64_R_TYPE(relas[i].r_info); - arch_kexec_do_relocs(r_type, loc, val, addr); + ret = arch_kexec_do_relocs(r_type, loc, val, addr); + if (ret) { + pr_err("Unknown rela relocation: %d\n", r_type); + return -ENOEXEC; + } } return 0; } -- 2.33.0