From patchwork Tue Aug 1 14:54:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 13336899 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 14165C001E0 for ; Tue, 1 Aug 2023 14:54:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232771AbjHAOy2 (ORCPT ); Tue, 1 Aug 2023 10:54:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231916AbjHAOy1 (ORCPT ); Tue, 1 Aug 2023 10:54:27 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 4BAD9120 for ; Tue, 1 Aug 2023 07:54:26 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 93BC01063; Tue, 1 Aug 2023 07:55:09 -0700 (PDT) Received: from merodach.members.linode.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AE21C3F5A1; Tue, 1 Aug 2023 07:54:24 -0700 (PDT) From: James Morse To: linux-modules@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Luis Chamberlain , Catalin Marinas , Will Deacon , Russell King , Russell King , Jessica Yu , james.morse@arm.com, Adam Johnston Subject: [PATCH 1/3] module: Expose module_init_layout_section() Date: Tue, 1 Aug 2023 14:54:07 +0000 Message-Id: <20230801145409.8935-2-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230801145409.8935-1-james.morse@arm.com> References: <20230801145409.8935-1-james.morse@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: module_init_layout_section() choses whether the core module loader considers a section as init or not. This affects the placement of the exit section when module unloading is disabled. This code will never run, so it can be free()d once the module has been initialised. arm and arm64 need to count the number of PLTs they need before applying relocations based on the section name. The init PLTs are stored separately so they can be free()d. arm and arm64 both use within_module_init() to decide which list of PLTs to use when applying the relocation. Because within_module_init()'s behaviour changes when module unloading is disabled, both architecture would need to take this into account when counting the PLTs. Today neither architecture does this, meaning when module unloading is disabled there are insufficient PLTs in the init section to load some modules, resulting in warnings: | WARNING: CPU: 2 PID: 51 at arch/arm64/kernel/module-plts.c:99 module_emit_plt_entry+0x184/0x1cc | Modules linked in: crct10dif_common | CPU: 2 PID: 51 Comm: modprobe Not tainted 6.5.0-rc4-yocto-standard-dirty #15208 | Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 | pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : module_emit_plt_entry+0x184/0x1cc | lr : module_emit_plt_entry+0x94/0x1cc | sp : ffffffc0803bba60 [...] | Call trace: | module_emit_plt_entry+0x184/0x1cc | apply_relocate_add+0x2bc/0x8e4 | load_module+0xe34/0x1bd4 | init_module_from_file+0x84/0xc0 | __arm64_sys_finit_module+0x1b8/0x27c | invoke_syscall.constprop.0+0x5c/0x104 | do_el0_svc+0x58/0x160 | el0_svc+0x38/0x110 | el0t_64_sync_handler+0xc0/0xc4 | el0t_64_sync+0x190/0x194 Instead of duplicating module_init_layout_section()s logic, expose it. Reported-by: Adam Johnston Fixes: 055f23b74b20 ("module: check for exit sections in layout_sections() instead of module_init_section()") Cc: stable@vger.kernel.org Signed-off-by: James Morse --- Adam has seen this in Yocto using the v6.1 stable kernel --- include/linux/moduleloader.h | 5 +++++ kernel/module/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 03be088fb439..001b2ce83832 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -42,6 +42,11 @@ bool module_init_section(const char *name); */ bool module_exit_section(const char *name); +/* Describes whether within_module_init() will consider this an init section + * or not. This behaviour changes with CONFIG_MODULE_UNLOAD. + */ +bool module_init_layout_section(const char *sname); + /* * Apply the given relocation to the (simplified) ELF. Return -error * or 0. diff --git a/kernel/module/main.c b/kernel/module/main.c index 59b1d067e528..ff7cc4e29299 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1484,7 +1484,7 @@ long module_get_offset_and_type(struct module *mod, enum mod_mem_type type, return offset | mask; } -static bool module_init_layout_section(const char *sname) +bool module_init_layout_section(const char *sname) { #ifndef CONFIG_MODULE_UNLOAD if (module_exit_section(sname)) From patchwork Tue Aug 1 14:54:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 13336900 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 486F8C00528 for ; Tue, 1 Aug 2023 14:54:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231916AbjHAOya (ORCPT ); Tue, 1 Aug 2023 10:54:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233638AbjHAOy3 (ORCPT ); Tue, 1 Aug 2023 10:54:29 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A0141120 for ; Tue, 1 Aug 2023 07:54:28 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id F0BED12FC; Tue, 1 Aug 2023 07:55:11 -0700 (PDT) Received: from merodach.members.linode.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 170113F5A1; Tue, 1 Aug 2023 07:54:26 -0700 (PDT) From: James Morse To: linux-modules@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Luis Chamberlain , Catalin Marinas , Will Deacon , Russell King , Russell King , Jessica Yu , james.morse@arm.com, Adam Johnston Subject: [PATCH 2/3] arm64: module: Use module_init_layout_section() to spot init sections Date: Tue, 1 Aug 2023 14:54:08 +0000 Message-Id: <20230801145409.8935-3-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230801145409.8935-1-james.morse@arm.com> References: <20230801145409.8935-1-james.morse@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: Today module_frob_arch_sections() spots init sections from their 'init' prefix, and uses this to keep the init PLTs separate from the rest. module_emit_plt_entry() uses within_module_init() to determine if a location is in the init text or not, but this depends on whether core code thought this was an init section. Naturally the logic is different. module_init_layout_section() groups the init and exit text together if module unloading is disabled, as the exit code will never run. The result is kernels with this configuration can't load all their modules because there are not enough PLTs for the combined init+exit section. This results in the following: | WARNING: CPU: 2 PID: 51 at arch/arm64/kernel/module-plts.c:99 module_emit_plt_entry+0x184/0x1cc | Modules linked in: crct10dif_common | CPU: 2 PID: 51 Comm: modprobe Not tainted 6.5.0-rc4-yocto-standard-dirty #15208 | Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 | pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : module_emit_plt_entry+0x184/0x1cc | lr : module_emit_plt_entry+0x94/0x1cc | sp : ffffffc0803bba60 [...] | Call trace: | module_emit_plt_entry+0x184/0x1cc | apply_relocate_add+0x2bc/0x8e4 | load_module+0xe34/0x1bd4 | init_module_from_file+0x84/0xc0 | __arm64_sys_finit_module+0x1b8/0x27c | invoke_syscall.constprop.0+0x5c/0x104 | do_el0_svc+0x58/0x160 | el0_svc+0x38/0x110 | el0t_64_sync_handler+0xc0/0xc4 | el0t_64_sync+0x190/0x194 A previous patch exposed module_init_layout_section(), use that so the logic is the same. Reported-by: Adam Johnston Tested-by: Adam Johnston Fixes: 055f23b74b20 ("module: check for exit sections in layout_sections() instead of module_init_section()") Cc: # 5.15.x: 60a0aab7463ee69 arm64: module-plts: inline linux/moduleloader.h Cc: # 5.15.x Signed-off-by: James Morse Acked-by: Catalin Marinas --- --- arch/arm64/kernel/module-plts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c index ad02058756b5..bd69a4e7cd60 100644 --- a/arch/arm64/kernel/module-plts.c +++ b/arch/arm64/kernel/module-plts.c @@ -339,7 +339,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, if (nents) sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL); - if (!str_has_prefix(secstrings + dstsec->sh_name, ".init")) + if (!module_init_layout_section(secstrings + dstsec->sh_name)) core_plts += count_plts(syms, rels, numrels, sechdrs[i].sh_info, dstsec); else From patchwork Tue Aug 1 14:54:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Morse X-Patchwork-Id: 13336901 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 61FACC001DF for ; Tue, 1 Aug 2023 14:54:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233757AbjHAOyc (ORCPT ); Tue, 1 Aug 2023 10:54:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35876 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233638AbjHAOyb (ORCPT ); Tue, 1 Aug 2023 10:54:31 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C2BCB120 for ; Tue, 1 Aug 2023 07:54:30 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 21C4313D5; Tue, 1 Aug 2023 07:55:14 -0700 (PDT) Received: from merodach.members.linode.com (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3AC313F5A1; Tue, 1 Aug 2023 07:54:29 -0700 (PDT) From: James Morse To: linux-modules@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Luis Chamberlain , Catalin Marinas , Will Deacon , Russell King , Russell King , Jessica Yu , james.morse@arm.com, Adam Johnston Subject: [PATCH 3/3] ARM: module: Use module_init_layout_section() to spot init sections Date: Tue, 1 Aug 2023 14:54:09 +0000 Message-Id: <20230801145409.8935-4-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230801145409.8935-1-james.morse@arm.com> References: <20230801145409.8935-1-james.morse@arm.com> MIME-Version: 1.0 Precedence: bulk List-ID: Today module_frob_arch_sections() spots init sections from their 'init' prefix, and uses this to keep the init PLTs separate from the rest. get_module_plt() uses within_module_init() to determine if a location is in the init text or not, but this depends on whether core code thought this was an init section. Naturally the logic is different. module_init_layout_section() groups the init and exit text together if module unloading is disabled, as the exit code will never run. The result is kernels with this configuration can't load all their modules because there are not enough PLTs for the combined init+exit section. A previous patch exposed module_init_layout_section(), use that so the logic is the same. Fixes: 055f23b74b20 ("module: check for exit sections in layout_sections() instead of module_init_section()") Cc: stable@vger.kernel.org Signed-off-by: James Morse --- I've not managed to get 32bit to call get_module_plt(), but it looks possible to hit the BUG_ON() because of this. --- arch/arm/kernel/module-plts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c index f5a43fd8c163..da2ee8d6ef1a 100644 --- a/arch/arm/kernel/module-plts.c +++ b/arch/arm/kernel/module-plts.c @@ -251,7 +251,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, /* sort by type and symbol index */ sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL); - if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0) + if (!module_init_layout_section(secstrings + dstsec->sh_name)) core_plts += count_plts(syms, dstsec->sh_addr, rels, numrels, s->sh_info); else