From patchwork Thu Dec 21 07:24:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 182025 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2483:b0:fb:cd0c:d3e with SMTP id q3csp242072dyi; Wed, 20 Dec 2023 23:25:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IFfilj7Y9pTPJ1yrNTnDjAIc3i0n4zVQPRsxU13qW+Vr2SD9o7UqsVtgH06Y7ijdlAhbyLc X-Received: by 2002:a05:6358:514d:b0:170:982:5611 with SMTP id 13-20020a056358514d00b0017009825611mr833104rwj.32.1703143524470; Wed, 20 Dec 2023 23:25:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703143524; cv=none; d=google.com; s=arc-20160816; b=T1B8O5mFbLG+NE2FarJqErqwj8Bcj458CnUCQ7CP5U64ZX/rbmvG8b08EpBcpf+5E1 XxbeYdPXzmNGy3kFJUW+CIwnADMyHcmkTQlMtDvqDlhm7ECxWL4EUZHvxKJTrfcoi8Y1 6NqMnv3sq4JQgt9Y6Z7eYqrPhWYYmfzRJMDGQODN1TIg1R4rsPh+SGt8PYuWSjhGigzF KkbH0h6eAZTkh9IpdJSh7frHER91Q+xfb4jg7OubsWJUimdOnj1Yq9SEZI3n2TksY7fj 6lEn5BnpS9bPbjvFKYR/mTfli72TdMHOPnuVLyt78h8Z6ax8HNjcUUHE4JL0BcMlooML YREg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=gTVldQgq+9e/N/NSVNms87TVuh/M2dF0Sv8GR3kFuZo=; fh=3Rmw3hrCZr4/YM66VoDQzei5WEe1xbduHySxKhuslJo=; b=DVjGtImG7ijfLDWqxAEZeGuFMC4E5UGeNME0rbsu55Y5p0g+wREi3hkCRf30r7NhBW B1kgSA49XnpM5HCpsKEPIIxO7HsXwfnvNUI+8bEn+ykJxvwoS43ypN9pYUGI399siHqk XRVttE3+sSO6DBk1KQgSbXTUHYYaDCLzIt7+G/FKyr4kl9GGDD7GbC626zeMZki38EOW FNgU4KU6wvvSmsZMhCqu4OYXP9oGbV3jocMy4e5IndWzhXXpOxY/FY6dRgWEhWpVN78J KcYFVOQJlvscV8rZhgc4ek+8B7VK/yVe4U+DwmLHhOGslM4Q6yul5iVa86v0Ky0lxXni CGGw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-7930-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-7930-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=csgroup.eu Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id w10-20020a17090aea0a00b0028b673555d0si1553531pjy.32.2023.12.20.23.25.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Dec 2023 23:25:24 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-7930-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-7930-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-7930-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=csgroup.eu 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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 38EAB286F21 for ; Thu, 21 Dec 2023 07:25:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9658C16431; Thu, 21 Dec 2023 07:24:47 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from pegase1.c-s.fr (pegase1.c-s.fr [93.17.236.30]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FA3E15AE9; Thu, 21 Dec 2023 07:24:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4Swhl16bdKz9v7S; Thu, 21 Dec 2023 08:24:29 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yer27FJBrBxH; Thu, 21 Dec 2023 08:24:29 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4Swhl02G7Qz9syd; Thu, 21 Dec 2023 08:24:28 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 4A2AD8B765; Thu, 21 Dec 2023 08:24:28 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id I1ETZd44Eo2D; Thu, 21 Dec 2023 08:24:28 +0100 (CET) Received: from PO20335.idsi0.si.c-s.fr (PO25106.IDSI0.si.c-s.fr [192.168.232.169]) by messagerie.si.c-s.fr (Postfix) with ESMTP id EBC488B788; Thu, 21 Dec 2023 08:24:27 +0100 (CET) From: Christophe Leroy To: Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH 3/3] module: Don't ignore errors from set_memory_XX() Date: Thu, 21 Dec 2023 08:24:25 +0100 Message-ID: <90d6698d32841ac15f6616d7bf02b0b488b867c9.1703143382.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.41.0 In-Reply-To: <98d4db94f19737fe05fd811a4188ff277b83a334.1703143382.git.christophe.leroy@csgroup.eu> References: <98d4db94f19737fe05fd811a4188ff277b83a334.1703143382.git.christophe.leroy@csgroup.eu> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1703143462; l=5572; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=B8NSNulQUqM9b0rkRsYEGn1/i1x8QVDr7Mrn6+JIkQg=; b=TQ7EyGle6pMMnVsDoXKuRCK4fpTgrpKnPKETBVY84COsP6nQUkXnvKm3NLIw/5oNZx/CDBLPD PXDO1TPTXLlBLLxOvlo7zqu/zpvZWkKe4y9fWDx1T4pwXwBrqHP6a0Y X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785875424727222727 X-GMAIL-MSGID: 1785875424727222727 set_memory_ro(), set_memory_nx(), set_memory_x() and other helps can fail an return an error. In that case the memory might not be protected as expected and the module loading has to be aborted to avoid security issues. Check return value of all calls to set_memory_XX() and handle error if any. Signed-off-by: Christophe Leroy --- kernel/module/internal.h | 6 ++--- kernel/module/main.c | 18 ++++++++++---- kernel/module/strict_rwx.c | 48 ++++++++++++++++++++++++++------------ 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 4f1b98f011da..2ebece8a789f 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -322,9 +322,9 @@ static inline struct module *mod_find(unsigned long addr, struct mod_tree_root * } #endif /* CONFIG_MODULES_TREE_LOOKUP */ -void module_enable_rodata_ro(const struct module *mod, bool after_init); -void module_enable_data_nx(const struct module *mod); -void module_enable_text_rox(const struct module *mod); +int module_enable_rodata_ro(const struct module *mod, bool after_init); +int module_enable_data_nx(const struct module *mod); +int module_enable_text_rox(const struct module *mod); int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod); diff --git a/kernel/module/main.c b/kernel/module/main.c index 64662e55e275..cfe197455d64 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2568,7 +2568,9 @@ static noinline int do_init_module(struct module *mod) /* Switch to core kallsyms now init is done: kallsyms may be walking! */ rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); #endif - module_enable_rodata_ro(mod, true); + ret = module_enable_rodata_ro(mod, true); + if (ret) + goto fail_mutex_unlock; mod_tree_remove_init(mod); module_arch_freeing_init(mod); for_class_mod_mem_type(type, init) { @@ -2606,6 +2608,8 @@ static noinline int do_init_module(struct module *mod) return 0; +fail_mutex_unlock: + mutex_unlock(&module_mutex); fail_free_freeinit: kfree(freeinit); fail: @@ -2733,9 +2737,15 @@ static int complete_formation(struct module *mod, struct load_info *info) module_bug_finalize(info->hdr, info->sechdrs, mod); module_cfi_finalize(info->hdr, info->sechdrs, mod); - module_enable_rodata_ro(mod, false); - module_enable_data_nx(mod); - module_enable_text_rox(mod); + err = module_enable_rodata_ro(mod, false); + if (err) + goto out; + err = module_enable_data_nx(mod); + if (err) + goto out; + err = module_enable_text_rox(mod); + if (err) + goto out; /* * Mark state as coming so strong_try_module_get() ignores us, diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c index 9b2d58a8d59d..a14df9655dbe 100644 --- a/kernel/module/strict_rwx.c +++ b/kernel/module/strict_rwx.c @@ -11,13 +11,13 @@ #include #include "internal.h" -static void module_set_memory(const struct module *mod, enum mod_mem_type type, +static int module_set_memory(const struct module *mod, enum mod_mem_type type, int (*set_memory)(unsigned long start, int num_pages)) { const struct module_memory *mod_mem = &mod->mem[type]; set_vm_flush_reset_perms(mod_mem->base); - set_memory((unsigned long)mod_mem->base, mod_mem->size >> PAGE_SHIFT); + return set_memory((unsigned long)mod_mem->base, mod_mem->size >> PAGE_SHIFT); } /* @@ -26,39 +26,57 @@ static void module_set_memory(const struct module *mod, enum mod_mem_type type, * CONFIG_STRICT_MODULE_RWX because they are needed regardless of whether we * are strict. */ -void module_enable_text_rox(const struct module *mod) +int module_enable_text_rox(const struct module *mod) { for_class_mod_mem_type(type, text) { + int ret; + if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - module_set_memory(mod, type, set_memory_rox); + ret = module_set_memory(mod, type, set_memory_rox); else - module_set_memory(mod, type, set_memory_x); + ret = module_set_memory(mod, type, set_memory_x); + if (ret) + return ret; } + return 0; } -void module_enable_rodata_ro(const struct module *mod, bool after_init) +int module_enable_rodata_ro(const struct module *mod, bool after_init) { + int ret; + if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - return; + return 0; #ifdef CONFIG_STRICT_MODULE_RWX if (!rodata_enabled) - return; + return 0; #endif - module_set_memory(mod, MOD_RODATA, set_memory_ro); - module_set_memory(mod, MOD_INIT_RODATA, set_memory_ro); + ret = module_set_memory(mod, MOD_RODATA, set_memory_ro); + if (ret) + return ret; + ret = module_set_memory(mod, MOD_INIT_RODATA, set_memory_ro); + if (ret) + return ret; if (after_init) - module_set_memory(mod, MOD_RO_AFTER_INIT, set_memory_ro); + return module_set_memory(mod, MOD_RO_AFTER_INIT, set_memory_ro); + + return 0; } -void module_enable_data_nx(const struct module *mod) +int module_enable_data_nx(const struct module *mod) { if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - return; + return 0; + + for_class_mod_mem_type(type, data) { + int ret = module_set_memory(mod, type, set_memory_nx); - for_class_mod_mem_type(type, data) - module_set_memory(mod, type, set_memory_nx); + if (ret) + return ret; + } + return 0; } int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,