From nobody Wed Jul 1 06:47:50 2026 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 68981C433FE for ; Tue, 28 Dec 2021 21:30:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237495AbhL1Var (ORCPT ); Tue, 28 Dec 2021 16:30:47 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:28438 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237447AbhL1Vaq (ORCPT ); Tue, 28 Dec 2021 16:30:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727045; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oyE/rafatlrcvSG+3VXfXdUjnRRYymu/M4FMEAKWVLk=; b=O1dlcc3++/rp553RyHIRWE39RYIylHb35sQNr2x1Q+sbaeL3Wnx1V2VQyZg9O+i1xWDRR7 G5NkwmGbWzcrIgKx3Z7y9O3VvcafefTVgM2tb7ehHRFJiOsCIuwrr0A6QXyqg1zSPKUDD1 +fqrFdm2Bn106xQe1Zn2yoHkI86jyEg= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-619-kwq-Dd8tOkWyqc-HhHxh2w-1; Tue, 28 Dec 2021 16:30:44 -0500 X-MC-Unique: kwq-Dd8tOkWyqc-HhHxh2w-1 Received: by mail-wm1-f72.google.com with SMTP id r10-20020a1c440a000000b003456b2594e0so6554215wma.8 for ; Tue, 28 Dec 2021 13:30:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oyE/rafatlrcvSG+3VXfXdUjnRRYymu/M4FMEAKWVLk=; b=MgQsRpOBVCpJS3sdblFNX0VTs20sdyr0Z+yaWAC8O7UT/v9Fm11O5nmrGykegMxol8 dC91zBe1G4UE+BETygECWzs0KZbBqcs9cRBA5ePnoCbWIuiRcv8rn0HfPzNVgxNFGAPb CNQ4Py7oU6s8HOJO7W29hg57qNXwqp+KV2tda8wAQUfzAC3uQHynkkXGIYIarqQQE4UG yCFrADEMwF1viOsUh1a/4AogtBj6upREvwum989u9FuKurfogdBeLRAqKuVrrg5yKsR3 qsDbIBFM4154vODmxkpQdNyLobT9IPysf3ajcALzGxDbP9fPkgTDmT8rCHwcfpLwuJHu cTzQ== X-Gm-Message-State: AOAM530MnDgqtpksxAtKz3dmqI4ooBUBZ6vNFZYc3GzKZWMfdX6lD+4Y 1BMpRAiAV50zjipQynhaTjC49UcFmFaO3k8nGOCcumhjLGt/lqG91bia81RwVzbfLWzAKkBHbRK wojKZd4S9UjyfRsqAReuuz/8= X-Received: by 2002:a05:600c:2188:: with SMTP id e8mr19105568wme.55.1640727043361; Tue, 28 Dec 2021 13:30:43 -0800 (PST) X-Google-Smtp-Source: ABdhPJzZHfJMfcZLPD5yQXbfVt8K3bzE/CJ+msCts6gqaz5PrvaaUDNxWD20Dv2Qb6qrcJDLH2vLww== X-Received: by 2002:a05:600c:2188:: with SMTP id e8mr19105557wme.55.1640727043182; Tue, 28 Dec 2021 13:30:43 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id l13sm21118900wrs.73.2021.12.28.13.30.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:42 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 01/12] module: Move all into module/ Date: Tue, 28 Dec 2021 21:30:30 +0000 Message-Id: <20211228213041.1356334-2-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional changes. This patch moves all module related code into a separate directory, modifies each file name and creates a new Makefile. Note: this effort is in preparation to refactor core module code. Signed-off-by: Aaron Tomlin --- kernel/Makefile | 4 +--- kernel/module/Makefile | 8 ++++++++ kernel/{module-internal.h =3D> module/internal.h} | 0 kernel/{module.c =3D> module/main.c} | 2 +- kernel/{module_signature.c =3D> module/signature.c} | 0 kernel/{module_signing.c =3D> module/signing.c} | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 kernel/module/Makefile rename kernel/{module-internal.h =3D> module/internal.h} (100%) rename kernel/{module.c =3D> module/main.c} (99%) rename kernel/{module_signature.c =3D> module/signature.c} (100%) rename kernel/{module_signing.c =3D> module/signing.c} (97%) diff --git a/kernel/Makefile b/kernel/Makefile index 4df609be42d0..466477d4dafe 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -53,6 +53,7 @@ obj-y +=3D rcu/ obj-y +=3D livepatch/ obj-y +=3D dma/ obj-y +=3D entry/ +obj-y +=3D module/ =20 obj-$(CONFIG_KCMP) +=3D kcmp.o obj-$(CONFIG_FREEZER) +=3D freezer.o @@ -66,9 +67,6 @@ ifneq ($(CONFIG_SMP),y) obj-y +=3D up.o endif obj-$(CONFIG_UID16) +=3D uid16.o -obj-$(CONFIG_MODULES) +=3D module.o -obj-$(CONFIG_MODULE_SIG) +=3D module_signing.o -obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D module_signature.o obj-$(CONFIG_KALLSYMS) +=3D kallsyms.o obj-$(CONFIG_BSD_PROCESS_ACCT) +=3D acct.o obj-$(CONFIG_CRASH_CORE) +=3D crash_core.o diff --git a/kernel/module/Makefile b/kernel/module/Makefile new file mode 100644 index 000000000000..a9cf6e822075 --- /dev/null +++ b/kernel/module/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for linux kernel module support +# + +obj-$(CONFIG_MODULES) +=3D main.o +obj-$(CONFIG_MODULE_SIG) +=3D signing.o +obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D signature.o diff --git a/kernel/module-internal.h b/kernel/module/internal.h similarity index 100% rename from kernel/module-internal.h rename to kernel/module/internal.h diff --git a/kernel/module.c b/kernel/module/main.c similarity index 99% rename from kernel/module.c rename to kernel/module/main.c index ed13917ea5f3..bc997c3e2c95 100644 --- a/kernel/module.c +++ b/kernel/module/main.c @@ -58,7 +58,7 @@ #include #include #include -#include "module-internal.h" +#include "internal.h" =20 #define CREATE_TRACE_POINTS #include diff --git a/kernel/module_signature.c b/kernel/module/signature.c similarity index 100% rename from kernel/module_signature.c rename to kernel/module/signature.c diff --git a/kernel/module_signing.c b/kernel/module/signing.c similarity index 97% rename from kernel/module_signing.c rename to kernel/module/signing.c index 8723ae70ea1f..8aeb6d2ee94b 100644 --- a/kernel/module_signing.c +++ b/kernel/module/signing.c @@ -12,7 +12,7 @@ #include #include #include -#include "module-internal.h" +#include "internal.h" =20 /* * Verify the signature on a module. --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 43CC6C433F5 for ; Tue, 28 Dec 2021 21:30:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237524AbhL1Vau (ORCPT ); Tue, 28 Dec 2021 16:30:50 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:31957 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237471AbhL1Var (ORCPT ); Tue, 28 Dec 2021 16:30:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727046; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7kJi6QbhQe0UKqaYog/4fs8E9UhX+TpYHbtJQ2kzdak=; b=hbop5jSnE+BTiFCVm2J6DwAT81q49tG8+2dEA+nW2m5/lBeCqdGSoQ1jb9eXmeSR/AaY84 zbhX6gv6Olp2wt1jKCwS7jyZWJmRuYCSs87rkz1a7PTCGVCbAvWPrYPNhm1r5Iw7C7VtnB EGOx7Qxb2bvI4017Xy4eXDewu+HIE8Y= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-280-RC0eyZifPoO0S_EjMd7g7A-1; Tue, 28 Dec 2021 16:30:45 -0500 X-MC-Unique: RC0eyZifPoO0S_EjMd7g7A-1 Received: by mail-wr1-f70.google.com with SMTP id t30-20020adfa2de000000b001a24004e1fbso4297446wra.10 for ; Tue, 28 Dec 2021 13:30:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7kJi6QbhQe0UKqaYog/4fs8E9UhX+TpYHbtJQ2kzdak=; b=Ks3I+eFEaCxAhGTgltNs6q0O3Gdhsh5RMPGwkgzkaknTwQxhbj7ELGmTG0N5FLC5CX 86ppyOSIw1tPgK0AvglXJX5ykYy8rTh3iRZvtAS0h0L90RwRLxUEzxXpmkg0c2ozwjr1 AlsNYTi4cSyiHlqDUPF17cBBtLGuH3xju5x2XihRmcyba40qw85pb5ixFRY0hP1j/xfn M+h/vQXtPUVB6Ljr/UZN1+DJh54h/bUVfutZPKxHMLvtdjZwf1B9aTU5vnfkZby7ATAy Z/AoJOIMTIn0cnSWzr5etDvolNi67SXXFqxQDfSHOYvhEEst2aYqKfR8DNtq+fnnKh/N 0Caw== X-Gm-Message-State: AOAM5333Ua+E+sZdPE8kEY6fYjXBlHgDOIhj6lsjWsHWvBcvvBCIixG7 ehUymDRnj+6aJMTa6sVcX5Rs5ZTopaKi+g4JV1UtPYBfjp15GweF5nhqTuPUSDZWy/RBfr8nvL0 oZ2aHQwWJLBU+Im/6eUK6cAI= X-Received: by 2002:adf:f40b:: with SMTP id g11mr17714784wro.645.1640727044320; Tue, 28 Dec 2021 13:30:44 -0800 (PST) X-Google-Smtp-Source: ABdhPJwbqBZEjYGOyh2QSHDIyFzBjjvk3ujK70INOECBs15JXNRoREc+6f2quKphIDOOu8dbecImnQ== X-Received: by 2002:adf:f40b:: with SMTP id g11mr17714769wro.645.1640727044176; Tue, 28 Dec 2021 13:30:44 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id h3sm19232220wrt.94.2021.12.28.13.30.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:43 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 02/12] module: Simple refactor in preparation for split Date: Tue, 28 Dec 2021 21:30:31 +0000 Message-Id: <20211228213041.1356334-3-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch makes it possible to move non-essential code out of core module code. Signed-off-by: Aaron Tomlin --- kernel/module/internal.h | 22 ++++++++++++++++++++++ kernel/module/main.c | 23 ++--------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 33783abc377b..ffc50df010a7 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -7,6 +7,28 @@ =20 #include #include +#include + +#ifndef ARCH_SHF_SMALL +#define ARCH_SHF_SMALL 0 +#endif + +/* If this is set, the section belongs in the init part of the module */ +#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) +/* Maximum number of characters written by module_flags() */ +#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4) +#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4)) + +extern struct mutex module_mutex; +extern struct list_head modules; + +/* Provided by the linker */ +extern const struct kernel_symbol __start___ksymtab[]; +extern const struct kernel_symbol __stop___ksymtab[]; +extern const struct kernel_symbol __start___ksymtab_gpl[]; +extern const struct kernel_symbol __stop___ksymtab_gpl[]; +extern const s32 __start___kcrctab[]; +extern const s32 __start___kcrctab_gpl[]; =20 struct load_info { const char *name; diff --git a/kernel/module/main.c b/kernel/module/main.c index bc997c3e2c95..2a6b859716c0 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -63,10 +63,6 @@ #define CREATE_TRACE_POINTS #include =20 -#ifndef ARCH_SHF_SMALL -#define ARCH_SHF_SMALL 0 -#endif - /* * Modules' sections will be aligned on page boundaries * to ensure complete separation of code and data, but @@ -78,9 +74,6 @@ # define debug_align(X) (X) #endif =20 -/* If this is set, the section belongs in the init part of the module */ -#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) - /* * Mutex protects: * 1) List of modules (also safely readable with preempt_disable), @@ -88,8 +81,8 @@ * 3) module_addr_min/module_addr_max. * (delete and add uses RCU list operations). */ -static DEFINE_MUTEX(module_mutex); -static LIST_HEAD(modules); +DEFINE_MUTEX(module_mutex); +LIST_HEAD(modules); =20 /* Work queue for freeing init sections in success case */ static void do_free_init(struct work_struct *w); @@ -408,14 +401,6 @@ static __maybe_unused void *any_section_objs(const str= uct load_info *info, return (void *)info->sechdrs[sec].sh_addr; } =20 -/* Provided by the linker */ -extern const struct kernel_symbol __start___ksymtab[]; -extern const struct kernel_symbol __stop___ksymtab[]; -extern const struct kernel_symbol __start___ksymtab_gpl[]; -extern const struct kernel_symbol __stop___ksymtab_gpl[]; -extern const s32 __start___kcrctab[]; -extern const s32 __start___kcrctab_gpl[]; - #ifndef CONFIG_MODVERSIONS #define symversion(base, idx) NULL #else @@ -1491,7 +1476,6 @@ struct module_sect_attrs { struct module_sect_attr attrs[]; }; =20 -#define MODULE_SECT_READ_SIZE (3 /* "0x", "\n" */ + (BITS_PER_LONG / 4)) static ssize_t module_sect_read(struct file *file, struct kobject *kobj, struct bin_attribute *battr, char *buf, loff_t pos, size_t count) @@ -4498,9 +4482,6 @@ static void cfi_cleanup(struct module *mod) #endif } =20 -/* Maximum number of characters written by module_flags() */ -#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4) - /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */ static char *module_flags(struct module *mod, char *buf) { --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 D192BC43217 for ; Tue, 28 Dec 2021 21:30:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237558AbhL1Vaw (ORCPT ); Tue, 28 Dec 2021 16:30:52 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:30902 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237500AbhL1Vas (ORCPT ); Tue, 28 Dec 2021 16:30:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727048; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pSjRwfWfC6TRwI79+5Cdb0GwAHoA8kDMFqEtGap/jfs=; b=Vgp5z6NkIZkFybj1xXbQN4JCYw9TcE+ox4SVfSLv1/SfJXN82zF5UJcNTiQ44QGPtW2iWT NLDLXhQPXwBqI0RH5MOMzxLOodrWl19UXWSvj+GJLqk3jTzZSAhMlH5kKulATZQUGpVumB fzHjUKz0wNPKNDx7mgIm8xdMAlaws/c= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-673-R5VRlgDxPSGM-yYLz-UWFw-1; Tue, 28 Dec 2021 16:30:46 -0500 X-MC-Unique: R5VRlgDxPSGM-yYLz-UWFw-1 Received: by mail-wr1-f71.google.com with SMTP id q21-20020adfab15000000b001a24b36e47eso4282455wrc.2 for ; Tue, 28 Dec 2021 13:30:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pSjRwfWfC6TRwI79+5Cdb0GwAHoA8kDMFqEtGap/jfs=; b=NutyuUbyw5vxM8Ywi7n9W1miD543qcXZVqn086jU4AKK3oZzMKh0GOvi7DD2RfZmKh 7uhMKucpEipwm8Yp9LAts1sP0154XFXC7dXqO7kKhImjkFt59kqKNUpakodRG9MGufZ1 SbcKqPZVtVl0gEOta/UWb7I7r9o/NPhL/TFynZOuv6x13LRTuKD+QH38m1aihI3EiZXg sZYNoUZ4zj5URJjhgpCmLzKUVOP1Oj3aXr/BTs6kvxfF6A5oFPqvImLfXok0B9QrsAIc 0zu4HfxMbn09lXUoH3pzR49nS6g3wFsU+BXsR1FAmIdQaMzbf7hyZ32k7N67Bu3Xkyro +Usg== X-Gm-Message-State: AOAM530Iw+/5FxXgvMb6PBE0VEh9SM+0TtkZyQchmH2E+WAmJBsNja7R 0KCg/O6zLOkZj5SZOs/ZjJNcGvuRcSqC1fbMXKxhpX20jtJzsDdUFmy9CheiPiJhDkb/h8zgxLF m7FItbu86GZF0j0LO7q9hmVc= X-Received: by 2002:a05:600c:3c84:: with SMTP id bg4mr13093256wmb.190.1640727045272; Tue, 28 Dec 2021 13:30:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJyjpOoXQT6HgiXt9+XxGLg/eP4hezShDWUozZdG8eMn130cQxvJgnJNXdDb51ljSQZAbDPE0g== X-Received: by 2002:a05:600c:3c84:: with SMTP id bg4mr13093248wmb.190.1640727045094; Tue, 28 Dec 2021 13:30:45 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id 1sm21331501wry.33.2021.12.28.13.30.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:44 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 03/12] module: Move livepatch support to a separate file Date: Tue, 28 Dec 2021 21:30:32 +0000 Message-Id: <20211228213041.1356334-4-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates livepatch support (i.e. used during module add/or load and remove/or deletion) from core module code into kernel/module/livepatch.c. At the moment it contains code to persist Elf information about a given livepatch module, only. Signed-off-by: Aaron Tomlin --- kernel/module/Makefile | 1 + kernel/module/internal.h | 12 ++++++ kernel/module/livepatch.c | 75 +++++++++++++++++++++++++++++++++ kernel/module/main.c | 89 +-------------------------------------- 4 files changed, 89 insertions(+), 88 deletions(-) create mode 100644 kernel/module/livepatch.c diff --git a/kernel/module/Makefile b/kernel/module/Makefile index a9cf6e822075..47d70bb18da3 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_MODULES) +=3D main.o obj-$(CONFIG_MODULE_SIG) +=3D signing.o obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D signature.o +obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o diff --git a/kernel/module/internal.h b/kernel/module/internal.h index ffc50df010a7..91ef152aeffb 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -51,3 +51,15 @@ struct load_info { }; =20 extern int mod_verify_sig(const void *mod, struct load_info *info); + +#ifdef CONFIG_LIVEPATCH +extern int copy_module_elf(struct module *mod, struct load_info *info); +extern void free_module_elf(struct module *mod); +extern int check_modinfo_livepatch(struct module *mod, struct load_info *i= nfo); +#else /* !CONFIG_LIVEPATCH */ +static inline int copy_module_elf(struct module *mod, struct load_info *in= fo) +{ + return 0; +} +static inline void free_module_elf(struct module *mod) { } +#endif /* CONFIG_LIVEPATCH */ diff --git a/kernel/module/livepatch.c b/kernel/module/livepatch.c new file mode 100644 index 000000000000..e147f5418327 --- /dev/null +++ b/kernel/module/livepatch.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/livepatch.c - module livepatch support + * + * Copyright (C) 2016 Jessica Yu + */ + +#include +#include +#include +#include "internal.h" + +/* + * Persist Elf information about a module. Copy the Elf header, + * section header table, section string table, and symtab section + * index from info to mod->klp_info. + */ +int copy_module_elf(struct module *mod, struct load_info *info) +{ + unsigned int size, symndx; + int ret; + + size =3D sizeof(*mod->klp_info); + mod->klp_info =3D kmalloc(size, GFP_KERNEL); + if (mod->klp_info =3D=3D NULL) + return -ENOMEM; + + /* Elf header */ + size =3D sizeof(mod->klp_info->hdr); + memcpy(&mod->klp_info->hdr, info->hdr, size); + + /* Elf section header table */ + size =3D sizeof(*info->sechdrs) * info->hdr->e_shnum; + mod->klp_info->sechdrs =3D kmemdup(info->sechdrs, size, GFP_KERNEL); + if (mod->klp_info->sechdrs =3D=3D NULL) { + ret =3D -ENOMEM; + goto free_info; + } + + /* Elf section name string table */ + size =3D info->sechdrs[info->hdr->e_shstrndx].sh_size; + mod->klp_info->secstrings =3D kmemdup(info->secstrings, size, GFP_KERNEL); + if (mod->klp_info->secstrings =3D=3D NULL) { + ret =3D -ENOMEM; + goto free_sechdrs; + } + + /* Elf symbol section index */ + symndx =3D info->index.sym; + mod->klp_info->symndx =3D symndx; + + /* + * For livepatch modules, core_kallsyms.symtab is a complete + * copy of the original symbol table. Adjust sh_addr to point + * to core_kallsyms.symtab since the copy of the symtab in module + * init memory is freed at the end of do_init_module(). + */ + mod->klp_info->sechdrs[symndx].sh_addr =3D \ + (unsigned long) mod->core_kallsyms.symtab; + + return 0; + +free_sechdrs: + kfree(mod->klp_info->sechdrs); +free_info: + kfree(mod->klp_info); + return ret; +} + +void free_module_elf(struct module *mod) +{ + kfree(mod->klp_info->sechdrs); + kfree(mod->klp_info->secstrings); + kfree(mod->klp_info); +} diff --git a/kernel/module/main.c b/kernel/module/main.c index 2a6b859716c0..9bcaf251e109 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2043,81 +2043,6 @@ static int module_enforce_rwx_sections(Elf_Ehdr *hdr= , Elf_Shdr *sechdrs, } #endif /* CONFIG_STRICT_MODULE_RWX */ =20 -#ifdef CONFIG_LIVEPATCH -/* - * Persist Elf information about a module. Copy the Elf header, - * section header table, section string table, and symtab section - * index from info to mod->klp_info. - */ -static int copy_module_elf(struct module *mod, struct load_info *info) -{ - unsigned int size, symndx; - int ret; - - size =3D sizeof(*mod->klp_info); - mod->klp_info =3D kmalloc(size, GFP_KERNEL); - if (mod->klp_info =3D=3D NULL) - return -ENOMEM; - - /* Elf header */ - size =3D sizeof(mod->klp_info->hdr); - memcpy(&mod->klp_info->hdr, info->hdr, size); - - /* Elf section header table */ - size =3D sizeof(*info->sechdrs) * info->hdr->e_shnum; - mod->klp_info->sechdrs =3D kmemdup(info->sechdrs, size, GFP_KERNEL); - if (mod->klp_info->sechdrs =3D=3D NULL) { - ret =3D -ENOMEM; - goto free_info; - } - - /* Elf section name string table */ - size =3D info->sechdrs[info->hdr->e_shstrndx].sh_size; - mod->klp_info->secstrings =3D kmemdup(info->secstrings, size, GFP_KERNEL); - if (mod->klp_info->secstrings =3D=3D NULL) { - ret =3D -ENOMEM; - goto free_sechdrs; - } - - /* Elf symbol section index */ - symndx =3D info->index.sym; - mod->klp_info->symndx =3D symndx; - - /* - * For livepatch modules, core_kallsyms.symtab is a complete - * copy of the original symbol table. Adjust sh_addr to point - * to core_kallsyms.symtab since the copy of the symtab in module - * init memory is freed at the end of do_init_module(). - */ - mod->klp_info->sechdrs[symndx].sh_addr =3D \ - (unsigned long) mod->core_kallsyms.symtab; - - return 0; - -free_sechdrs: - kfree(mod->klp_info->sechdrs); -free_info: - kfree(mod->klp_info); - return ret; -} - -static void free_module_elf(struct module *mod) -{ - kfree(mod->klp_info->sechdrs); - kfree(mod->klp_info->secstrings); - kfree(mod->klp_info); -} -#else /* !CONFIG_LIVEPATCH */ -static int copy_module_elf(struct module *mod, struct load_info *info) -{ - return 0; -} - -static void free_module_elf(struct module *mod) -{ -} -#endif /* CONFIG_LIVEPATCH */ - void __weak module_memfree(void *module_region) { /* @@ -3052,19 +2977,7 @@ static int copy_chunked_from_user(void *dst, const v= oid __user *usrc, unsigned l return 0; } =20 -#ifdef CONFIG_LIVEPATCH -static int check_modinfo_livepatch(struct module *mod, struct load_info *i= nfo) -{ - if (get_modinfo(info, "livepatch")) { - mod->klp =3D true; - add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK); - pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n", - mod->name); - } - - return 0; -} -#else /* !CONFIG_LIVEPATCH */ +#ifndef CONFIG_LIVEPATCH static int check_modinfo_livepatch(struct module *mod, struct load_info *i= nfo) { if (get_modinfo(info, "livepatch")) { --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 D8B92C433EF for ; Tue, 28 Dec 2021 21:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237576AbhL1Vay (ORCPT ); Tue, 28 Dec 2021 16:30:54 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:48032 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237447AbhL1Vat (ORCPT ); Tue, 28 Dec 2021 16:30:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727048; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qglGEuGp2EruX7zdhZlheeGYqPXPPaBDozoY2l4KtaY=; b=hwxEd59m3jtoa5vph9LcBDNlpsAgXs4GDwJdu37vJXQWE+BDPeaXr0LlipkXxZdxAs/I8M Az1WIlJLokqTQWxvsNKoIy6fcYCNXla9u87lzN8F2//z863nzpX6GLkrl8cZNIwfAyhDeq gjuUrOEsrYwYHRSVgMW4zV9cSQ5QCX0= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-654--0G3v8jOOqyx8b-J8jq7uQ-1; Tue, 28 Dec 2021 16:30:47 -0500 X-MC-Unique: -0G3v8jOOqyx8b-J8jq7uQ-1 Received: by mail-wm1-f69.google.com with SMTP id r2-20020a05600c35c200b00345c3b82b22so9800951wmq.0 for ; Tue, 28 Dec 2021 13:30:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qglGEuGp2EruX7zdhZlheeGYqPXPPaBDozoY2l4KtaY=; b=04MurVHGQkHXKfdCiv+vam2BGpT3EITdMSy5L4jC7sI5Ebl/5YLPAOFyp87biN7mdu CaOMhjrloJrja+jag0KY3lIfB/g0yImc8t0Vizicg4C9JTN0RsngmJEkrcthWripbME6 r0XAmhc/Udzf7q6CZJ4cwKIZWw6h3aJb4EeDn+g2lsi+GCYcFDmlq0UnBVzWgSEKHzkK MWUvCdJYqyiP6MbRXnVN3fZDHxKFkkfyUVqkFqQ/QIbNSVzghJsBz1smMbGvrDVOHWTh YSNdj+2E3ij8gkPkfZBicaRmLt+xISklSNLt9pJSidFS7PsUSjQQ6/yji+k+r5jrQpqX +9gQ== X-Gm-Message-State: AOAM5300S/5Jp0BpUiW2ZoKuqGVDkxTBqLiUzEg0T4rEimQBrL8LY7XA aqHlklYS/qCALF9m/EXfxCBHrN5X55WK6iZBN0Z0zKClHq+9WjeZ9anXWWhAusUjiGx4Y3KoiH+ Eyus78zY5cHF2DSSD2EtKvzg= X-Received: by 2002:a05:6000:1ac6:: with SMTP id i6mr18120496wry.373.1640727046238; Tue, 28 Dec 2021 13:30:46 -0800 (PST) X-Google-Smtp-Source: ABdhPJwkWlGdQz1IYEMJGo0TXzlFTLc6do5V5jM6k+mhFPu1apWlBs93FdpIb/++/gtXCnJXPJZjQw== X-Received: by 2002:a05:6000:1ac6:: with SMTP id i6mr18120484wry.373.1640727046075; Tue, 28 Dec 2021 13:30:46 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id o11sm21961448wmq.15.2021.12.28.13.30.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:45 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 04/12] module: Move latched RB-tree support to a separate file Date: Tue, 28 Dec 2021 21:30:33 +0000 Message-Id: <20211228213041.1356334-5-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates module latched RB-tree support (e.g. see __module_address()) from core module code into kernel/module/tree_lookup.c. Signed-off-by: Aaron Tomlin --- include/linux/module.h | 37 +++++++++- kernel/module/Makefile | 1 + kernel/module/main.c | 134 ------------------------------------ kernel/module/tree_lookup.c | 108 +++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 136 deletions(-) create mode 100644 kernel/module/tree_lookup.c diff --git a/include/linux/module.h b/include/linux/module.h index 8a298d820dbc..8b4d254a84c0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -339,11 +339,44 @@ struct module_layout { }; =20 #ifdef CONFIG_MODULES_TREE_LOOKUP +struct mod_tree_root { + struct latch_tree_root root; + unsigned long addr_min; + unsigned long addr_max; +} mod_tree __cacheline_aligned =3D { + .addr_min =3D -1UL, +}; + +#define module_addr_min mod_tree.addr_min +#define module_addr_max mod_tree.addr_max + +extern void mod_tree_insert(struct module *mod); +extern void mod_tree_remove_init(struct module *mod); +extern void mod_tree_remove(struct module *mod); +extern struct module *mod_find(unsigned long addr); /* Only touch one cacheline for common rbtree-for-core-layout case. */ #define __module_layout_align ____cacheline_aligned -#else +#else /* !CONFIG_MODULES_TREE_LOOKUP */ + +static unsigned long module_addr_min =3D -1UL, module_addr_max =3D 0; + +static void mod_tree_insert(struct module *mod) { } +static void mod_tree_remove_init(struct module *mod) { } +static void mod_tree_remove(struct module *mod) { } +static struct module *mod_find(unsigned long addr) +{ + struct module *mod; + + list_for_each_entry_rcu(mod, &modules, list, + lockdep_is_held(&module_mutex)) { + if (within_module(addr, mod)) + return mod; + } + + return NULL; +} #define __module_layout_align -#endif +#endif /* CONFIG_MODULES_TREE_LOOKUP */ =20 struct mod_kallsyms { Elf_Sym *symtab; diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 47d70bb18da3..9d593362156d 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_MODULES) +=3D main.o obj-$(CONFIG_MODULE_SIG) +=3D signing.o obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D signature.o obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o +obj-$(CONFIG_MODULES_TREE_LOOKUP) +=3D tree_lookup.o diff --git a/kernel/module/main.c b/kernel/module/main.c index 9bcaf251e109..692cc520420d 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -89,140 +89,6 @@ static void do_free_init(struct work_struct *w); static DECLARE_WORK(init_free_wq, do_free_init); static LLIST_HEAD(init_free_list); =20 -#ifdef CONFIG_MODULES_TREE_LOOKUP - -/* - * Use a latched RB-tree for __module_address(); this allows us to use - * RCU-sched lookups of the address from any context. - * - * This is conditional on PERF_EVENTS || TRACING because those can really = hit - * __module_address() hard by doing a lot of stack unwinding; potentially = from - * NMI context. - */ - -static __always_inline unsigned long __mod_tree_val(struct latch_tree_node= *n) -{ - struct module_layout *layout =3D container_of(n, struct module_layout, mt= n.node); - - return (unsigned long)layout->base; -} - -static __always_inline unsigned long __mod_tree_size(struct latch_tree_nod= e *n) -{ - struct module_layout *layout =3D container_of(n, struct module_layout, mt= n.node); - - return (unsigned long)layout->size; -} - -static __always_inline bool -mod_tree_less(struct latch_tree_node *a, struct latch_tree_node *b) -{ - return __mod_tree_val(a) < __mod_tree_val(b); -} - -static __always_inline int -mod_tree_comp(void *key, struct latch_tree_node *n) -{ - unsigned long val =3D (unsigned long)key; - unsigned long start, end; - - start =3D __mod_tree_val(n); - if (val < start) - return -1; - - end =3D start + __mod_tree_size(n); - if (val >=3D end) - return 1; - - return 0; -} - -static const struct latch_tree_ops mod_tree_ops =3D { - .less =3D mod_tree_less, - .comp =3D mod_tree_comp, -}; - -static struct mod_tree_root { - struct latch_tree_root root; - unsigned long addr_min; - unsigned long addr_max; -} mod_tree __cacheline_aligned =3D { - .addr_min =3D -1UL, -}; - -#define module_addr_min mod_tree.addr_min -#define module_addr_max mod_tree.addr_max - -static noinline void __mod_tree_insert(struct mod_tree_node *node) -{ - latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops); -} - -static void __mod_tree_remove(struct mod_tree_node *node) -{ - latch_tree_erase(&node->node, &mod_tree.root, &mod_tree_ops); -} - -/* - * These modifications: insert, remove_init and remove; are serialized by = the - * module_mutex. - */ -static void mod_tree_insert(struct module *mod) -{ - mod->core_layout.mtn.mod =3D mod; - mod->init_layout.mtn.mod =3D mod; - - __mod_tree_insert(&mod->core_layout.mtn); - if (mod->init_layout.size) - __mod_tree_insert(&mod->init_layout.mtn); -} - -static void mod_tree_remove_init(struct module *mod) -{ - if (mod->init_layout.size) - __mod_tree_remove(&mod->init_layout.mtn); -} - -static void mod_tree_remove(struct module *mod) -{ - __mod_tree_remove(&mod->core_layout.mtn); - mod_tree_remove_init(mod); -} - -static struct module *mod_find(unsigned long addr) -{ - struct latch_tree_node *ltn; - - ltn =3D latch_tree_find((void *)addr, &mod_tree.root, &mod_tree_ops); - if (!ltn) - return NULL; - - return container_of(ltn, struct mod_tree_node, node)->mod; -} - -#else /* MODULES_TREE_LOOKUP */ - -static unsigned long module_addr_min =3D -1UL, module_addr_max =3D 0; - -static void mod_tree_insert(struct module *mod) { } -static void mod_tree_remove_init(struct module *mod) { } -static void mod_tree_remove(struct module *mod) { } - -static struct module *mod_find(unsigned long addr) -{ - struct module *mod; - - list_for_each_entry_rcu(mod, &modules, list, - lockdep_is_held(&module_mutex)) { - if (within_module(addr, mod)) - return mod; - } - - return NULL; -} - -#endif /* MODULES_TREE_LOOKUP */ - /* * Bounds of module text, for speeding up __module_address. * Protected by module_mutex. diff --git a/kernel/module/tree_lookup.c b/kernel/module/tree_lookup.c new file mode 100644 index 000000000000..7703687c6e2e --- /dev/null +++ b/kernel/module/tree_lookup.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/tree_lookup.c - modules tree lookup + * + * Copyright (C) 2015 Peter Zijlstra + * Copyright (C) 2015 Rusty Russell + */ + +#include +#include + +/* + * Use a latched RB-tree for __module_address(); this allows us to use + * RCU-sched lookups of the address from any context. + * + * This is conditional on PERF_EVENTS || TRACING because those can really = hit + * __module_address() hard by doing a lot of stack unwinding; potentially = from + * NMI context. + */ + +__always_inline unsigned long __mod_tree_val(struct latch_tree_node *n) +{ + struct module_layout *layout =3D container_of(n, struct module_layout, mt= n.node); + + return (unsigned long)layout->base; +} + +__always_inline unsigned long __mod_tree_size(struct latch_tree_node *n) +{ + struct module_layout *layout =3D container_of(n, struct module_layout, mt= n.node); + + return (unsigned long)layout->size; +} + +__always_inline bool +mod_tree_less(struct latch_tree_node *a, struct latch_tree_node *b) +{ + return __mod_tree_val(a) < __mod_tree_val(b); +} + +__always_inline int +mod_tree_comp(void *key, struct latch_tree_node *n) +{ + unsigned long val =3D (unsigned long)key; + unsigned long start, end; + + start =3D __mod_tree_val(n); + if (val < start) + return -1; + + end =3D start + __mod_tree_size(n); + if (val >=3D end) + return 1; + + return 0; +} + +const struct latch_tree_ops mod_tree_ops =3D { + .less =3D mod_tree_less, + .comp =3D mod_tree_comp, +}; + +noinline void __mod_tree_insert(struct mod_tree_node *node) +{ + latch_tree_insert(&node->node, &mod_tree.root, &mod_tree_ops); +} + +void __mod_tree_remove(struct mod_tree_node *node) +{ + latch_tree_erase(&node->node, &mod_tree.root, &mod_tree_ops); +} + +/* + * These modifications: insert, remove_init and remove; are serialized by = the + * module_mutex. + */ +void mod_tree_insert(struct module *mod) +{ + mod->core_layout.mtn.mod =3D mod; + mod->init_layout.mtn.mod =3D mod; + + __mod_tree_insert(&mod->core_layout.mtn); + if (mod->init_layout.size) + __mod_tree_insert(&mod->init_layout.mtn); +} + +void mod_tree_remove_init(struct module *mod) +{ + if (mod->init_layout.size) + __mod_tree_remove(&mod->init_layout.mtn); +} + +void mod_tree_remove(struct module *mod) +{ + __mod_tree_remove(&mod->core_layout.mtn); + mod_tree_remove_init(mod); +} + +struct module *mod_find(unsigned long addr) +{ + struct latch_tree_node *ltn; + + ltn =3D latch_tree_find((void *)addr, &mod_tree.root, &mod_tree_ops); + if (!ltn) + return NULL; + + return container_of(ltn, struct mod_tree_node, node)->mod; +} --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 D644DC433F5 for ; Tue, 28 Dec 2021 21:30:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237599AbhL1Va5 (ORCPT ); Tue, 28 Dec 2021 16:30:57 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24998 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237513AbhL1Vau (ORCPT ); Tue, 28 Dec 2021 16:30:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727049; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NOXz+O07LBQHEUssdkx6GwmEYZ1hrM8RRSVfzn//wI8=; b=BjSNCPzsDUgD1GbdGe37j4120WGvQFLCIonijboyjA3SD+mgn9/ekJ0tTsrz9oLYCz/CXO bv53jUBLH6iM8M5INlouzO5GlssxVl7nAceVGk9xMsLRapXKWiAtgIYCnRAWNkspn/tH0M IOX6skgunGliTEcO5CsHoaDsLcMfO7I= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-634-OdxUTj8WON6hrda2MzcZwA-1; Tue, 28 Dec 2021 16:30:48 -0500 X-MC-Unique: OdxUTj8WON6hrda2MzcZwA-1 Received: by mail-wm1-f69.google.com with SMTP id n3-20020a05600c3b8300b00345c3fc40b0so9719161wms.3 for ; Tue, 28 Dec 2021 13:30:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NOXz+O07LBQHEUssdkx6GwmEYZ1hrM8RRSVfzn//wI8=; b=6VRG6Dlj4HRXg1GcCcB7KjP+YEOEFHUndwD2hh7eM1jteisfnvVX9TdJIxdObgings 1BQGDw6uIFoLMEiDrFLc+F/Hkn8B2+0SG52cMXmdzYQu6uXvjEhWVIcVa0+Yrj8rNtJ1 5q5Hx3yq6dvGAwYkkg2X+aAgZFLRqElEHxCS/4Pk6xWMSszrXnqJIXD5FUmf7vfS6Tr9 gfPi5cD8QHBD3OgxSF1uQSZ8FlTShNR5QwwCbGP+sckcGsd9j+nHLMPX5DdzA4YVifkB AsyAOkNZZs2wzSltTtSWo7C6oavYZkqEsM3qotrp2zNmM/LHdbicVO04LK+mfyc1Lko1 mTMQ== X-Gm-Message-State: AOAM530NfhpJgpHQrLtG2bJ4myDR+2x744e5Vp75/HK/dUBQr3sZ3Mz8 M31pzLatU+iaunL3KWoF7f5NQI7KCiJPkXbs+q4uZBuOSfQ5icXB0eoZA0Fvj0rSC17sNZKSh48 5QtIUOP51jbLiwmcn8mNbuBw= X-Received: by 2002:a05:600c:510f:: with SMTP id o15mr18896718wms.104.1640727047333; Tue, 28 Dec 2021 13:30:47 -0800 (PST) X-Google-Smtp-Source: ABdhPJxjpnlOaqFRUgSq8sfKk6ja8TSc54MC+oQzyCfy9yX6FfHKeKlJyp9VFxHu2VPPClkvot8puA== X-Received: by 2002:a05:600c:510f:: with SMTP id o15mr18896698wms.104.1640727047134; Tue, 28 Dec 2021 13:30:47 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id r62sm19064369wmr.35.2021.12.28.13.30.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:46 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 05/12] module: Move arch strict rwx support to a separate file Date: Tue, 28 Dec 2021 21:30:34 +0000 Message-Id: <20211228213041.1356334-6-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates applicable architecture code that support strict module rwx from core module code into kernel/module/arch_strict_rwx.c Signed-off-by: Aaron Tomlin --- include/linux/module.h | 16 +++++++++++ kernel/module/Makefile | 1 + kernel/module/arch_strict_rwx.c | 44 ++++++++++++++++++++++++++++ kernel/module/main.c | 51 --------------------------------- 4 files changed, 61 insertions(+), 51 deletions(-) create mode 100644 kernel/module/arch_strict_rwx.c diff --git a/include/linux/module.h b/include/linux/module.h index 8b4d254a84c0..caa7212cf754 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -338,6 +338,22 @@ struct module_layout { #endif }; =20 +/* + * Modules' sections will be aligned on page boundaries + * to ensure complete separation of code and data, but + * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=3Dy + */ +#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX +# define debug_align(X) ALIGN(X, PAGE_SIZE) + +extern void frob_text(const struct module_layout *layout, int (*set_memory= )(unsigned long start, int num_pages)); +extern void module_enable_x(const struct module *mod); +#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ +# define debug_align(X) (X) + +static void module_enable_x(const struct module *mod) { } +#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ + #ifdef CONFIG_MODULES_TREE_LOOKUP struct mod_tree_root { struct latch_tree_root root; diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 9d593362156d..95fad95a0549 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_MODULE_SIG) +=3D signing.o obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D signature.o obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o obj-$(CONFIG_MODULES_TREE_LOOKUP) +=3D tree_lookup.o +obj-$(CONFIG_ARCH_HAS_STRICT_MODULE_RWX) +=3D arch_strict_rwx.o diff --git a/kernel/module/arch_strict_rwx.c b/kernel/module/arch_strict_rw= x.c new file mode 100644 index 000000000000..68e970671ec5 --- /dev/null +++ b/kernel/module/arch_strict_rwx.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/arch_strict_rwx.c - module arch strict rwx + * + * Copyright (C) 2015 Rusty Russell + */ + +#include +#include + +/* + * LKM RO/NX protection: protect module's text/ro-data + * from modification and any data from execution. + * + * General layout of module is: + * [text] [read-only-data] [ro-after-init] [writable data] + * text_size -----^ ^ ^ ^ + * ro_size ------------------------| | | + * ro_after_init_size -----------------------------| | + * size -----------------------------------------------------------| + * + * These values are always page-aligned (as is base) + */ + +/* + * Since some arches are moving towards PAGE_KERNEL module allocations ins= tead + * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of = the + * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless= of + * whether we are strict. + */ +void frob_text(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base, + layout->text_size >> PAGE_SHIFT); +} + +void module_enable_x(const struct module *mod) +{ + frob_text(&mod->core_layout, set_memory_x); + frob_text(&mod->init_layout, set_memory_x); +} diff --git a/kernel/module/main.c b/kernel/module/main.c index 692cc520420d..a0619256b343 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -63,17 +62,6 @@ #define CREATE_TRACE_POINTS #include =20 -/* - * Modules' sections will be aligned on page boundaries - * to ensure complete separation of code and data, but - * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=3Dy - */ -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX -# define debug_align(X) ALIGN(X, PAGE_SIZE) -#else -# define debug_align(X) (X) -#endif - /* * Mutex protects: * 1) List of modules (also safely readable with preempt_disable), @@ -1786,45 +1774,6 @@ static void mod_sysfs_teardown(struct module *mod) mod_sysfs_fini(mod); } =20 -/* - * LKM RO/NX protection: protect module's text/ro-data - * from modification and any data from execution. - * - * General layout of module is: - * [text] [read-only-data] [ro-after-init] [writable data] - * text_size -----^ ^ ^ ^ - * ro_size ------------------------| | | - * ro_after_init_size -----------------------------| | - * size -----------------------------------------------------------| - * - * These values are always page-aligned (as is base) - */ - -/* - * Since some arches are moving towards PAGE_KERNEL module allocations ins= tead - * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of = the - * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless= of - * whether we are strict. - */ -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX -static void frob_text(const struct module_layout *layout, - int (*set_memory)(unsigned long start, int num_pages)) -{ - BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base, - layout->text_size >> PAGE_SHIFT); -} - -static void module_enable_x(const struct module *mod) -{ - frob_text(&mod->core_layout, set_memory_x); - frob_text(&mod->init_layout, set_memory_x); -} -#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ -static void module_enable_x(const struct module *mod) { } -#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ - #ifdef CONFIG_STRICT_MODULE_RWX static void frob_rodata(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 06C08C433F5 for ; Tue, 28 Dec 2021 21:31:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237622AbhL1VbB (ORCPT ); Tue, 28 Dec 2021 16:31:01 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:56801 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237471AbhL1Vav (ORCPT ); Tue, 28 Dec 2021 16:30:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727050; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uueBGakT/gT7TUjBGwoofDgqQKuu/ItyPgp72/wDjB0=; b=UV64UiE0cenDMbREPH7RzEW1hviqMgY63FEvojA3HethXh0+ST59pczzjPQYIv6vMuk7+i Nt0M73TFKjEoCMcNYVaBBVk0Bm4KMqF/j5cFq0vdBtgj7LrubTPi16So8Yn/4Aszph29CD /2z927tkqo76COFXs+LBvH4RjTpmgcs= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-608-ALKAxLRNM36UE_-a3r44WQ-1; Tue, 28 Dec 2021 16:30:49 -0500 X-MC-Unique: ALKAxLRNM36UE_-a3r44WQ-1 Received: by mail-wm1-f70.google.com with SMTP id a69-20020a1c7f48000000b00345d3d135caso5378339wmd.7 for ; Tue, 28 Dec 2021 13:30:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uueBGakT/gT7TUjBGwoofDgqQKuu/ItyPgp72/wDjB0=; b=dY514ScqyzhUtXvoTfPcGnLCeZgcqMoP9x5xz18fNOW7HFCp+00x+SKECkK8fyoibD 0cumMim8B90oc3GQZwdBcUgmOBms4+EQdtMjagF2Ch/SH7JEdggmKEQkVRVqdC1/WL8H NWsSxkDn9RIub9FjrCJdaId1qJU2FGnPSSaYCUAQY3NPu6vZuxiGwXWL28O3XNuINFlL 3/up0YjY4sa832UvjbvF8/8N6IuW0ruBZL/Uk/zfp8vyT68dQEp6SJRtSjFLS3Ebvaz+ erZ0SU22Eub6h5Oh1CDgy1c/9v0lpMGbPi7xZH507f0FYHENnbsbfuIAdKBLvNblcEqh hAfA== X-Gm-Message-State: AOAM532d1Ysd1eanY7Byahzzgj4jsEPI/IFCORkRLeJ0o1rz8A2Fozxs 9v4shPnhwMa3gGQsDnXTQDJ1evRouHHzSY0o7e33pn+ThaYofCIfN3vXAUnUwG0/7eWdIZrYJmA DT5LxAgEWEDCd+7KQoOEfcSE= X-Received: by 2002:a5d:64e7:: with SMTP id g7mr17559928wri.203.1640727048357; Tue, 28 Dec 2021 13:30:48 -0800 (PST) X-Google-Smtp-Source: ABdhPJws6dB1esH1e3GaF+mmVl28v1qQERbn6j07cqiDgOXtM4kgKG6I+CwoPZ6kiT0DmOhpvOraGg== X-Received: by 2002:a5d:64e7:: with SMTP id g7mr17559910wri.203.1640727048120; Tue, 28 Dec 2021 13:30:48 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id c2sm21117243wri.50.2021.12.28.13.30.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:47 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 06/12] module: Move strict rwx support to a separate file Date: Tue, 28 Dec 2021 21:30:35 +0000 Message-Id: <20211228213041.1356334-7-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates code that makes module text and rodata memory read-only and non-text memory non-executable from core module code into kernel/module/strict_rwx.c. Signed-off-by: Aaron Tomlin --- include/linux/module.h | 18 ++++++++ kernel/module/Makefile | 1 + kernel/module/main.c | 84 -------------------------------------- kernel/module/strict_rwx.c | 83 +++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 84 deletions(-) create mode 100644 kernel/module/strict_rwx.c diff --git a/include/linux/module.h b/include/linux/module.h index caa7212cf754..218ac6768433 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -354,6 +354,24 @@ extern void module_enable_x(const struct module *mod); static void module_enable_x(const struct module *mod) { } #endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ =20 +#ifdef CONFIG_STRICT_MODULE_RWX +extern void frob_rodata(const struct module_layout *layout, int (*set_memo= ry)(unsigned long start, int num_pages)); +extern void frob_ro_after_init(const struct module_layout *layout, int (*s= et_memory)(unsigned long start, int num_pages)); +extern void frob_writable_data(const struct module_layout *layout, int (*s= et_memory)(unsigned long start, int num_pages)); +extern void module_enable_ro(const struct module *mod, bool after_init); +extern void module_enable_nx(const struct module *mod); +extern int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, c= har *secstrings, struct module *mod); + +#else /* !CONFIG_STRICT_MODULE_RWX */ +static void module_enable_nx(const struct module *mod) { } +static void module_enable_ro(const struct module *mod, bool after_init) {} +static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, + char *secstrings, struct module *mod) +{ + return 0; +} +#endif /* CONFIG_STRICT_MODULE_RWX */ + #ifdef CONFIG_MODULES_TREE_LOOKUP struct mod_tree_root { struct latch_tree_root root; diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 95fad95a0549..795fe10ac530 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_MODULE_SIG_FORMAT) +=3D signature.o obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o obj-$(CONFIG_MODULES_TREE_LOOKUP) +=3D tree_lookup.o obj-$(CONFIG_ARCH_HAS_STRICT_MODULE_RWX) +=3D arch_strict_rwx.o +obj-$(CONFIG_STRICT_MODULE_RWX) +=3D strict_rwx.o diff --git a/kernel/module/main.c b/kernel/module/main.c index a0619256b343..c404d00f7958 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1774,90 +1774,6 @@ static void mod_sysfs_teardown(struct module *mod) mod_sysfs_fini(mod); } =20 -#ifdef CONFIG_STRICT_MODULE_RWX -static void frob_rodata(const struct module_layout *layout, - int (*set_memory)(unsigned long start, int num_pages)) -{ - BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base + layout->text_size, - (layout->ro_size - layout->text_size) >> PAGE_SHIFT); -} - -static void frob_ro_after_init(const struct module_layout *layout, - int (*set_memory)(unsigned long start, int num_pages)) -{ - BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base + layout->ro_size, - (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT); -} - -static void frob_writable_data(const struct module_layout *layout, - int (*set_memory)(unsigned long start, int num_pages)) -{ - BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); - set_memory((unsigned long)layout->base + layout->ro_after_init_size, - (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); -} - -static void module_enable_ro(const struct module *mod, bool after_init) -{ - if (!rodata_enabled) - return; - - set_vm_flush_reset_perms(mod->core_layout.base); - set_vm_flush_reset_perms(mod->init_layout.base); - frob_text(&mod->core_layout, set_memory_ro); - - frob_rodata(&mod->core_layout, set_memory_ro); - frob_text(&mod->init_layout, set_memory_ro); - frob_rodata(&mod->init_layout, set_memory_ro); - - if (after_init) - frob_ro_after_init(&mod->core_layout, set_memory_ro); -} - -static void module_enable_nx(const struct module *mod) -{ - frob_rodata(&mod->core_layout, set_memory_nx); - frob_ro_after_init(&mod->core_layout, set_memory_nx); - frob_writable_data(&mod->core_layout, set_memory_nx); - frob_rodata(&mod->init_layout, set_memory_nx); - frob_writable_data(&mod->init_layout, set_memory_nx); -} - -static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *mod) -{ - const unsigned long shf_wx =3D SHF_WRITE|SHF_EXECINSTR; - int i; - - for (i =3D 0; i < hdr->e_shnum; i++) { - if ((sechdrs[i].sh_flags & shf_wx) =3D=3D shf_wx) { - pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n", - mod->name, secstrings + sechdrs[i].sh_name, i); - return -ENOEXEC; - } - } - - return 0; -} - -#else /* !CONFIG_STRICT_MODULE_RWX */ -static void module_enable_nx(const struct module *mod) { } -static void module_enable_ro(const struct module *mod, bool after_init) {} -static int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *mod) -{ - return 0; -} -#endif /* CONFIG_STRICT_MODULE_RWX */ - void __weak module_memfree(void *module_region) { /* diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c new file mode 100644 index 000000000000..8a513ced02c6 --- /dev/null +++ b/kernel/module/strict_rwx.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/strict_rwx.c - module strict rwx + * + * Copyright (C) 2015 Rusty Russell + */ + +#include +#include +#include + +void frob_rodata(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base + layout->text_size, + (layout->ro_size - layout->text_size) >> PAGE_SHIFT); +} + +void frob_ro_after_init(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_size & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base + layout->ro_size, + (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT); +} + +void frob_writable_data(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->ro_after_init_size & (PAGE_SIZE-1)); + BUG_ON((unsigned long)layout->size & (PAGE_SIZE-1)); + set_memory((unsigned long)layout->base + layout->ro_after_init_size, + (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); +} + +void module_enable_ro(const struct module *mod, bool after_init) +{ + if (!rodata_enabled) + return; + + set_vm_flush_reset_perms(mod->core_layout.base); + set_vm_flush_reset_perms(mod->init_layout.base); + frob_text(&mod->core_layout, set_memory_ro); + + frob_rodata(&mod->core_layout, set_memory_ro); + frob_text(&mod->init_layout, set_memory_ro); + frob_rodata(&mod->init_layout, set_memory_ro); + + if (after_init) + frob_ro_after_init(&mod->core_layout, set_memory_ro); +} + +void module_enable_nx(const struct module *mod) +{ + frob_rodata(&mod->core_layout, set_memory_nx); + frob_ro_after_init(&mod->core_layout, set_memory_nx); + frob_writable_data(&mod->core_layout, set_memory_nx); + frob_rodata(&mod->init_layout, set_memory_nx); + frob_writable_data(&mod->init_layout, set_memory_nx); +} + +int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, + char *secstrings, struct module *mod) +{ + const unsigned long shf_wx =3D SHF_WRITE|SHF_EXECINSTR; + int i; + + for (i =3D 0; i < hdr->e_shnum; i++) { + if ((sechdrs[i].sh_flags & shf_wx) =3D=3D shf_wx) { + pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n", + mod->name, secstrings + sechdrs[i].sh_name, i); + return -ENOEXEC; + } + } + + return 0; +} --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 83C2DC433EF for ; Tue, 28 Dec 2021 21:31:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237528AbhL1VbI (ORCPT ); Tue, 28 Dec 2021 16:31:08 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:47183 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237544AbhL1Vaw (ORCPT ); Tue, 28 Dec 2021 16:30:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mCGQaji14i2F94mV0DWpkRKJAs6KEBhnNJRRFLq3kec=; b=KHP/iBuj0mVxuWZg+4mz/hLRs3dZ0oVwxk2Rtjn9zY36nRIMcjkTFojvNVLjPFPDpDSGpB DJNS2jAZY27ySMEJEwmmEFnuPbY78hYn8m5jJoCowvjZr+c0Hz/GEsJu9tzMJ2U3ZUYcPL Rp0OM3rOS1u8C16NGd3N2/yJ5qQKHkg= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-345-7DTjs7L7N12-BwpG4yY-FQ-1; Tue, 28 Dec 2021 16:30:50 -0500 X-MC-Unique: 7DTjs7L7N12-BwpG4yY-FQ-1 Received: by mail-wr1-f69.google.com with SMTP id l9-20020adfa389000000b001a23bd1c661so4300386wrb.6 for ; Tue, 28 Dec 2021 13:30:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mCGQaji14i2F94mV0DWpkRKJAs6KEBhnNJRRFLq3kec=; b=U/OCZxYrGkFh7T/HL8nRClfdiEtC2xENgdIWGEBdX1V/X+18g6X8lGkXGZ+PxrCiNt 4mSuMZy6k60yGC/9MtvwReBU6HjxF6FNl1yR0A9CkbEz0tq3yI1m+yAoZJrCqEG7m3Ga w/fq0XwNZ0N1agmRF6NlHMEgDZKQn0uVypWEvyxdFViFMQGAJ4/Td2z3G/Ru7WRqzlhZ Kj+b3Ghyc20m+Rg14sqmB1UhKjGQAOk++eLi5BVjjCGzteNDuBPNs5jzLfebRShzSIH+ qDgZ679Ygfv2Y5o10rA+ZI67aKcORj0ai+5VXAVpVW0ZN0+D3gpN3lcBy9JIW4hbVrgX i7Pw== X-Gm-Message-State: AOAM5303raUkRlfbhmioriJ2RoFBCAXJR1eAf815ICaQQ1Y14kosiGRa ARiMgRfB18BQGL4Af0d2YmTsRkpBhCFNHpji0g+cKLcU2X7EkS51p0nDSjVNUR6IaXRdirXA0oK 8VG+DHsFC/6GVo51cCnCux70= X-Received: by 2002:a5d:4ac1:: with SMTP id y1mr7059444wrs.588.1640727049361; Tue, 28 Dec 2021 13:30:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJzIYphcVIhT3nBANNBEk2578Lhh5pmlGNiiIxOfT+c3XgWX4iunwncZgmKGb+Z/glmSo3vB4A== X-Received: by 2002:a5d:4ac1:: with SMTP id y1mr7059433wrs.588.1640727049201; Tue, 28 Dec 2021 13:30:49 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id l4sm18975858wrm.62.2021.12.28.13.30.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:48 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 07/12] module: Move extra signature support out of core code Date: Tue, 28 Dec 2021 21:30:36 +0000 Message-Id: <20211228213041.1356334-8-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates additional module signature check code from core module code into kernel/module/signing.c. Signed-off-by: Aaron Tomlin --- include/linux/module.h | 5 ++- kernel/module/internal.h | 9 +++++ kernel/module/main.c | 86 ---------------------------------------- kernel/module/signing.c | 75 +++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 88 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index 218ac6768433..3383912268af 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -736,8 +736,8 @@ static inline bool is_livepatch_module(struct module *m= od) } #endif /* CONFIG_LIVEPATCH */ =20 -bool is_module_sig_enforced(void); -void set_module_sig_enforced(void); +extern bool is_module_sig_enforced(void); +extern void set_module_sig_enforced(void); =20 #else /* !CONFIG_MODULES... */ =20 @@ -927,6 +927,7 @@ static inline bool module_sig_ok(struct module *module) { return true; } +#define sig_enforce false #endif /* CONFIG_MODULE_SIG */ =20 int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 91ef152aeffb..b4db57bafcd3 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -63,3 +63,12 @@ static inline int copy_module_elf(struct module *mod, st= ruct load_info *info) } static inline void free_module_elf(struct module *mod) { } #endif /* CONFIG_LIVEPATCH */ + +#ifdef CONFIG_MODULE_SIG +extern int module_sig_check(struct load_info *info, int flags); +#else /* !CONFIG_MODULE_SIG */ +static int module_sig_check(struct load_info *info, int flags) +{ + return 0; +} +#endif /* !CONFIG_MODULE_SIG */ diff --git a/kernel/module/main.c b/kernel/module/main.c index c404d00f7958..8f8a904d5ba7 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -114,28 +113,6 @@ static void module_assert_mutex_or_preempt(void) #endif } =20 -#ifdef CONFIG_MODULE_SIG -static bool sig_enforce =3D IS_ENABLED(CONFIG_MODULE_SIG_FORCE); -module_param(sig_enforce, bool_enable_only, 0644); - -void set_module_sig_enforced(void) -{ - sig_enforce =3D true; -} -#else -#define sig_enforce false -#endif - -/* - * Export sig_enforce kernel cmdline parameter to allow other subsystems r= ely - * on that instead of directly to CONFIG_MODULE_SIG_FORCE config. - */ -bool is_module_sig_enforced(void) -{ - return sig_enforce; -} -EXPORT_SYMBOL(is_module_sig_enforced); - /* Block module loading/unloading? */ int modules_disabled =3D 0; core_param(nomodule, modules_disabled, bint, 0); @@ -2517,69 +2494,6 @@ static inline void kmemleak_load_module(const struct= module *mod, } #endif =20 -#ifdef CONFIG_MODULE_SIG -static int module_sig_check(struct load_info *info, int flags) -{ - int err =3D -ENODATA; - const unsigned long markerlen =3D sizeof(MODULE_SIG_STRING) - 1; - const char *reason; - const void *mod =3D info->hdr; - - /* - * Require flags =3D=3D 0, as a module with version information - * removed is no longer the module that was signed - */ - if (flags =3D=3D 0 && - info->len > markerlen && - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) =3D= =3D 0) { - /* We truncate the module to discard the signature */ - info->len -=3D markerlen; - err =3D mod_verify_sig(mod, info); - if (!err) { - info->sig_ok =3D true; - return 0; - } - } - - /* - * We don't permit modules to be loaded into the trusted kernels - * without a valid signature on them, but if we're not enforcing, - * certain errors are non-fatal. - */ - switch (err) { - case -ENODATA: - reason =3D "unsigned module"; - break; - case -ENOPKG: - reason =3D "module with unsupported crypto"; - break; - case -ENOKEY: - reason =3D "module with unavailable key"; - break; - - default: - /* - * All other errors are fatal, including lack of memory, - * unparseable signatures, and signature check failures -- - * even if signatures aren't required. - */ - return err; - } - - if (is_module_sig_enforced()) { - pr_notice("Loading of %s is rejected\n", reason); - return -EKEYREJECTED; - } - - return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); -} -#else /* !CONFIG_MODULE_SIG */ -static int module_sig_check(struct load_info *info, int flags) -{ - return 0; -} -#endif /* !CONFIG_MODULE_SIG */ - static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) { unsigned long secend; diff --git a/kernel/module/signing.c b/kernel/module/signing.c index 8aeb6d2ee94b..ff41541e982a 100644 --- a/kernel/module/signing.c +++ b/kernel/module/signing.c @@ -11,9 +11,28 @@ #include #include #include +#include #include #include "internal.h" =20 +static bool sig_enforce =3D IS_ENABLED(CONFIG_MODULE_SIG_FORCE); +module_param(sig_enforce, bool_enable_only, 0644); + +/* + * Export sig_enforce kernel cmdline parameter to allow other subsystems r= ely + * on that instead of directly to CONFIG_MODULE_SIG_FORCE config. + */ +bool is_module_sig_enforced(void) +{ + return sig_enforce; +} +EXPORT_SYMBOL(is_module_sig_enforced); + +void set_module_sig_enforced(void) +{ + sig_enforce =3D true; +} + /* * Verify the signature on a module. */ @@ -43,3 +62,59 @@ int mod_verify_sig(const void *mod, struct load_info *in= fo) VERIFYING_MODULE_SIGNATURE, NULL, NULL); } + +int module_sig_check(struct load_info *info, int flags) +{ + int err =3D -ENODATA; + const unsigned long markerlen =3D sizeof(MODULE_SIG_STRING) - 1; + const char *reason; + const void *mod =3D info->hdr; + + /* + * Require flags =3D=3D 0, as a module with version information + * removed is no longer the module that was signed + */ + if (flags =3D=3D 0 && + info->len > markerlen && + memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) =3D= =3D 0) { + /* We truncate the module to discard the signature */ + info->len -=3D markerlen; + err =3D mod_verify_sig(mod, info); + if (!err) { + info->sig_ok =3D true; + return 0; + } + } + + /* + * We don't permit modules to be loaded into the trusted kernels + * without a valid signature on them, but if we're not enforcing, + * certain errors are non-fatal. + */ + switch (err) { + case -ENODATA: + reason =3D "unsigned module"; + break; + case -ENOPKG: + reason =3D "module with unsupported crypto"; + break; + case -ENOKEY: + reason =3D "module with unavailable key"; + break; + + default: + /* + * All other errors are fatal, including lack of memory, + * unparseable signatures, and signature check failures -- + * even if signatures aren't required. + */ + return err; + } + + if (is_module_sig_enforced()) { + pr_notice("Loading of %s is rejected\n", reason); + return -EKEYREJECTED; + } + + return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); +} --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 C0999C43217 for ; Tue, 28 Dec 2021 21:31:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237634AbhL1VbC (ORCPT ); Tue, 28 Dec 2021 16:31:02 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:55863 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237500AbhL1Vax (ORCPT ); Tue, 28 Dec 2021 16:30:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727052; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BdvMqON2+g29uF5MGNt8FJ0hyaTFBqbggeNzWwGO7Ms=; b=DMJE9waWCIjZlvFWNlhuZn2N6kyGfdgiULqhoE6de+omDvUnsmykFxiS/5lzLwkjm+vIxy gPRj/LvHOyUBKPCRBcVePFcUZJQgdvC3adiG+PI8sEyY0QZTl/sAsdKNcf1cxFUR6TR3q7 IaK4XAwxeiL97Qe1kT8COwz/pZxNtEQ= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-310-K-hH1ZR5ObK8yeBbfLegIg-1; Tue, 28 Dec 2021 16:30:51 -0500 X-MC-Unique: K-hH1ZR5ObK8yeBbfLegIg-1 Received: by mail-wr1-f69.google.com with SMTP id h7-20020adfaa87000000b001885269a937so4330511wrc.17 for ; Tue, 28 Dec 2021 13:30:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BdvMqON2+g29uF5MGNt8FJ0hyaTFBqbggeNzWwGO7Ms=; b=XUmkRZSP0FaAMddnEFaG2JAScQCn8ZCJ8G7uML6QJ8iXLcmETqVVgLUYqYmwtDN53U k6JzZXz1b4jt87oUtVF2A2neMTt0XGge3wpp8uTvVPoXhznfAUWnZNoZBMatO7I7MEFv khm2Gs+k1aTWeK19J9DpVBt97Qg3NFrJZ/TiC3XBjwJHjTy87QyC7TlGI0mtSL6hxHGM e6pV38G0TEcz65RDV/slCWbgYL7KTCbw795reUrEQ9M1p/+pK8ih2TAoVfF8WKVsDFgP mbFxWrJyuFS0k+eWncNtmE7h/HRrgjsxASNsOp5U82Qd1+wZn+e+frSwiNde9uNuFUfV EYAg== X-Gm-Message-State: AOAM5310FzYVKusU0vRGtQSbMjd9ORk7DkQZ8ht3BZGOzhoAqV6TC7R0 Ar9sQRAqjjh1OVEkx80yjkR7wAwGGjAu3K/21g6aDJYxyASnJA4p6i+PoWd76jC6/PYSZ6xYTE0 1PONk8nPSLWU5UQUgx3kxHR0= X-Received: by 2002:adf:d1a6:: with SMTP id w6mr17330566wrc.274.1640727050412; Tue, 28 Dec 2021 13:30:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJwa/mdwd5RP9WlrJlprOyPdltkjlK5AWEEYB/GP6aDuIFA61L/iYsiVp0nPYfPfNVYFImXi+Q== X-Received: by 2002:adf:d1a6:: with SMTP id w6mr17330554wrc.274.1640727050268; Tue, 28 Dec 2021 13:30:50 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id r7sm18530335wrt.77.2021.12.28.13.30.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:50 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 08/12] module: Move kmemleak support to a separate file Date: Tue, 28 Dec 2021 21:30:37 +0000 Message-Id: <20211228213041.1356334-9-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates kmemleak code out of core module code into kernel/module/debug_kmemleak.c Signed-off-by: Aaron Tomlin --- kernel/module/Makefile | 1 + kernel/module/debug_kmemleak.c | 30 ++++++++++++++++++++++++++++++ kernel/module/internal.h | 7 +++++++ kernel/module/main.c | 27 --------------------------- 4 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 kernel/module/debug_kmemleak.c diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 795fe10ac530..2e03da799833 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o obj-$(CONFIG_MODULES_TREE_LOOKUP) +=3D tree_lookup.o obj-$(CONFIG_ARCH_HAS_STRICT_MODULE_RWX) +=3D arch_strict_rwx.o obj-$(CONFIG_STRICT_MODULE_RWX) +=3D strict_rwx.o +obj-$(CONFIG_DEBUG_KMEMLEAK) +=3D debug_kmemleak.o diff --git a/kernel/module/debug_kmemleak.c b/kernel/module/debug_kmemleak.c new file mode 100644 index 000000000000..818c9d168aed --- /dev/null +++ b/kernel/module/debug_kmemleak.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/debug_kmemleak.c - module kmemleak support + * + * Copyright (C) 2009 Catalin Marinas + */ + +#include +#include +#include "internal.h" + +void kmemleak_load_module(const struct module *mod, + const struct load_info *info) +{ + unsigned int i; + + /* only scan the sections containing data */ + kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); + + for (i =3D 1; i < info->hdr->e_shnum; i++) { + /* Scan all writable sections that's not executable */ + if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) || + !(info->sechdrs[i].sh_flags & SHF_WRITE) || + (info->sechdrs[i].sh_flags & SHF_EXECINSTR)) + continue; + + kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, + info->sechdrs[i].sh_size, GFP_KERNEL); + } +} diff --git a/kernel/module/internal.h b/kernel/module/internal.h index b4db57bafcd3..31d767416f0c 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -6,6 +6,7 @@ */ =20 #include +#include #include #include =20 @@ -72,3 +73,9 @@ static int module_sig_check(struct load_info *info, int f= lags) return 0; } #endif /* !CONFIG_MODULE_SIG */ + +#ifdef CONFIG_DEBUG_KMEMLEAK +extern void kmemleak_load_module(const struct module *mod, const struct lo= ad_info *info); +#else /* !CONFIG_DEBUG_KMEMLEAK */ +static inline void __maybe_unused kmemleak_load_module(const struct module= *mod, const struct load_info *info) { } +#endif /* CONFIG_DEBUG_KMEMLEAK */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 8f8a904d5ba7..672a977b1320 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2467,33 +2467,6 @@ bool __weak module_exit_section(const char *name) return strstarts(name, ".exit"); } =20 -#ifdef CONFIG_DEBUG_KMEMLEAK -static void kmemleak_load_module(const struct module *mod, - const struct load_info *info) -{ - unsigned int i; - - /* only scan the sections containing data */ - kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); - - for (i =3D 1; i < info->hdr->e_shnum; i++) { - /* Scan all writable sections that's not executable */ - if (!(info->sechdrs[i].sh_flags & SHF_ALLOC) || - !(info->sechdrs[i].sh_flags & SHF_WRITE) || - (info->sechdrs[i].sh_flags & SHF_EXECINSTR)) - continue; - - kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, - info->sechdrs[i].sh_size, GFP_KERNEL); - } -} -#else -static inline void kmemleak_load_module(const struct module *mod, - const struct load_info *info) -{ -} -#endif - static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) { unsigned long secend; --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 35052C433EF for ; Tue, 28 Dec 2021 21:31:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229847AbhL1VbU (ORCPT ); Tue, 28 Dec 2021 16:31:20 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:20074 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237588AbhL1Va5 (ORCPT ); Tue, 28 Dec 2021 16:30:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727056; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZUEkJWsxXP6BsETJkrvhPjouaNdbfj3jiXJF/PlhK0o=; b=gS4MiBIXQ6h0HCWDbP//D6U+FwEwATV8Ar2S0m7oiR1meIcxkJaEC5pWfg1XSVO5HYydP2 1KSvTMYWIK2uqSCsp9wLWzQ2KZIcrtaDZCbfu8HatP1gpijpB6PwuAPy/SWW7qEh1nZQ22 0QcOEHkOTo0n+jUs+ij1DsDICAhBJG4= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-454-iirFBhd7NJ-GiMyC2rLvDg-1; Tue, 28 Dec 2021 16:30:53 -0500 X-MC-Unique: iirFBhd7NJ-GiMyC2rLvDg-1 Received: by mail-wr1-f71.google.com with SMTP id l9-20020adfa389000000b001a23bd1c661so4300443wrb.6 for ; Tue, 28 Dec 2021 13:30:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZUEkJWsxXP6BsETJkrvhPjouaNdbfj3jiXJF/PlhK0o=; b=l6rM2P1gePARh3DFyPwiQkSudj5t89xVxGsjyYkVW9mYsH23UgDT/7/6Gkr0tsEsT3 MRkLxLVehpiwj5BiV5LltuAWr1rVL1uUSmR1pTFbyKhX7Q+m4HpU+P6Z1PGeTxW01n1z uhKqjDjy4tyd+ALCq9Sr5sgp5yI78ExSGxB6qpMu0IQpb+/SkZ0pJQq1MelkWRJG1ynL CJMHsqDHJEFX20p+UZVgsbBFaWKgYj/eDH8YfRB/ixA2lBQ9bRHULJkMJU9QcDVYNebq a2+Dr48qLtAnwiv+Do6p37p7BKGwSx9CGP3+2Jx4OU92IuQNW8hn9W7lBwJQjxo4uq0K 7avQ== X-Gm-Message-State: AOAM532v6jYxdBfNUBLAuIATwEWKiPf30gOw+eFlz6ZCXFgdH7t/9XTs gMOeZ3zqsxLgAEAtUT/wz4U9fnMQRnMxlCjEaXmdTpfrtwyjpa8I69A2oxwBiXUJRap4BI1i1C5 kCWIYPv0JeP5B2ZC5gREDfZ4= X-Received: by 2002:a5d:4568:: with SMTP id a8mr18494048wrc.471.1640727051621; Tue, 28 Dec 2021 13:30:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJzoOpCT9b9YngsldqtjvWCX+4PsCaEviuSQZDsPGpVJLimvBlMoZxnPQrkUYZ0MNF2ibJDFSQ== X-Received: by 2002:a5d:4568:: with SMTP id a8mr18494032wrc.471.1640727051290; Tue, 28 Dec 2021 13:30:51 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id o14sm19380517wms.4.2021.12.28.13.30.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:50 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 09/12] module: Move kallsyms support into a separate file Date: Tue, 28 Dec 2021 21:30:38 +0000 Message-Id: <20211228213041.1356334-10-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates kallsyms code out of core module code kernel/module/kallsyms.c Signed-off-by: Aaron Tomlin --- kernel/module/Makefile | 1 + kernel/module/internal.h | 20 ++ kernel/module/kallsyms.c | 506 ++++++++++++++++++++++++++++++++++++++ kernel/module/main.c | 516 +-------------------------------------- 4 files changed, 531 insertions(+), 512 deletions(-) create mode 100644 kernel/module/kallsyms.c diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 2e03da799833..23582011ab08 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_MODULES_TREE_LOOKUP) +=3D tree_lookup.o obj-$(CONFIG_ARCH_HAS_STRICT_MODULE_RWX) +=3D arch_strict_rwx.o obj-$(CONFIG_STRICT_MODULE_RWX) +=3D strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) +=3D debug_kmemleak.o +obj-$(CONFIG_KALLSYMS) +=3D kallsyms.o diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 31d767416f0c..119d42c304a1 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -79,3 +79,23 @@ extern void kmemleak_load_module(const struct module *mo= d, const struct load_inf #else /* !CONFIG_DEBUG_KMEMLEAK */ static inline void __maybe_unused kmemleak_load_module(const struct module= *mod, const struct load_info *info) { } #endif /* CONFIG_DEBUG_KMEMLEAK */ + +#ifdef CONFIG_KALLSYMS +#ifdef CONFIG_STACKTRACE_BUILD_ID +extern void init_build_id(struct module *mod, const struct load_info *info= ); +#else /* !CONFIG_STACKTRACE_BUILD_ID */ +static inline void init_build_id(struct module *mod, const struct load_inf= o *info) { } + +#endif +extern void layout_symtab(struct module *mod, struct load_info *info); +extern void add_kallsyms(struct module *mod, const struct load_info *info); +extern bool sect_empty(const Elf_Shdr *sect); +extern const char *find_kallsyms_symbol(struct module *mod, unsigned long = addr, unsigned long *size, unsigned long *offset); +#else /* !CONFIG_KALLSYMS */ +static inline void layout_symtab(struct module *mod, struct load_info *inf= o) { } +static inline void add_kallsyms(struct module *mod, const struct load_info= *info) { } +static inline char *find_kallsyms_symbol(struct module *mod, unsigned long= addr, unsigned long *size, unsigned long *offset) +{ + return NULL; +} +#endif /* CONFIG_KALLSYMS */ diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c new file mode 100644 index 000000000000..f682415459fe --- /dev/null +++ b/kernel/module/kallsyms.c @@ -0,0 +1,506 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/kallsyms.c - module kallsyms support + * + * Copyright (C) 2010 Rusty Russell + */ + +#include +#include +#include +#include +#include "internal.h" + +extern struct module *find_module_all(const char *name, size_t len, bool e= ven_unformed); +extern unsigned long kernel_symbol_value(const struct kernel_symbol *sym); +extern int cmp_name(const void *name, const void *sym); +extern long get_offset(struct module *mod, unsigned int *size, Elf_Shdr *s= echdr, unsigned int section); + +/* Lookup exported symbol in given range of kernel_symbols */ +static const struct kernel_symbol *lookup_exported_symbol(const char *name, + const struct kernel_symbol *start, + const struct kernel_symbol *stop) +{ + return bsearch(name, start, stop - start, + sizeof(struct kernel_symbol), cmp_name); +} + +static int is_exported(const char *name, unsigned long value, + const struct module *mod) +{ + const struct kernel_symbol *ks; + if (!mod) + ks =3D lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab); + else + ks =3D lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms= ); + + return ks !=3D NULL && kernel_symbol_value(ks) =3D=3D value; +} + +/* As per nm */ +static char elf_type(const Elf_Sym *sym, const struct load_info *info) +{ + const Elf_Shdr *sechdrs =3D info->sechdrs; + + if (ELF_ST_BIND(sym->st_info) =3D=3D STB_WEAK) { + if (ELF_ST_TYPE(sym->st_info) =3D=3D STT_OBJECT) + return 'v'; + else + return 'w'; + } + if (sym->st_shndx =3D=3D SHN_UNDEF) + return 'U'; + if (sym->st_shndx =3D=3D SHN_ABS || sym->st_shndx =3D=3D info->index.pcpu) + return 'a'; + if (sym->st_shndx >=3D SHN_LORESERVE) + return '?'; + if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR) + return 't'; + if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC + && sechdrs[sym->st_shndx].sh_type !=3D SHT_NOBITS) { + if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE)) + return 'r'; + else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) + return 'g'; + else + return 'd'; + } + if (sechdrs[sym->st_shndx].sh_type =3D=3D SHT_NOBITS) { + if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) + return 's'; + else + return 'b'; + } + if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name, + ".debug")) { + return 'n'; + } + return '?'; +} + +static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, + unsigned int shnum, unsigned int pcpundx) +{ + const Elf_Shdr *sec; + + if (src->st_shndx =3D=3D SHN_UNDEF + || src->st_shndx >=3D shnum + || !src->st_name) + return false; + +#ifdef CONFIG_KALLSYMS_ALL + if (src->st_shndx =3D=3D pcpundx) + return true; +#endif + + sec =3D sechdrs + src->st_shndx; + if (!(sec->sh_flags & SHF_ALLOC) +#ifndef CONFIG_KALLSYMS_ALL + || !(sec->sh_flags & SHF_EXECINSTR) +#endif + || (sec->sh_entsize & INIT_OFFSET_MASK)) + return false; + + return true; +} + +/* + * We only allocate and copy the strings needed by the parts of symtab + * we keep. This is simple, but has the effect of making multiple + * copies of duplicates. We could be more sophisticated, see + * linux-kernel thread starting with + * <73defb5e4bca04a6431392cc341112b1@localhost>. + */ +void layout_symtab(struct module *mod, struct load_info *info) +{ + Elf_Shdr *symsect =3D info->sechdrs + info->index.sym; + Elf_Shdr *strsect =3D info->sechdrs + info->index.str; + const Elf_Sym *src; + unsigned int i, nsrc, ndst, strtab_size =3D 0; + + /* Put symbol section at end of init part of module. */ + symsect->sh_flags |=3D SHF_ALLOC; + symsect->sh_entsize =3D get_offset(mod, &mod->init_layout.size, symsect, + info->index.sym) | INIT_OFFSET_MASK; + pr_debug("\t%s\n", info->secstrings + symsect->sh_name); + + src =3D (void *)info->hdr + symsect->sh_offset; + nsrc =3D symsect->sh_size / sizeof(*src); + + /* Compute total space required for the core symbols' strtab. */ + for (ndst =3D i =3D 0; i < nsrc; i++) { + if (i =3D=3D 0 || is_livepatch_module(mod) || + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, + info->index.pcpu)) { + strtab_size +=3D strlen(&info->strtab[src[i].st_name])+1; + ndst++; + } + } + + /* Append room for core symbols at end of core part. */ + info->symoffs =3D ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1= ); + info->stroffs =3D mod->core_layout.size =3D info->symoffs + ndst * sizeof= (Elf_Sym); + mod->core_layout.size +=3D strtab_size; + info->core_typeoffs =3D mod->core_layout.size; + mod->core_layout.size +=3D ndst * sizeof(char); + mod->core_layout.size =3D debug_align(mod->core_layout.size); + + /* Put string table section at end of init part of module. */ + strsect->sh_flags |=3D SHF_ALLOC; + strsect->sh_entsize =3D get_offset(mod, &mod->init_layout.size, strsect, + info->index.str) | INIT_OFFSET_MASK; + pr_debug("\t%s\n", info->secstrings + strsect->sh_name); + + /* We'll tack temporary mod_kallsyms on the end. */ + mod->init_layout.size =3D ALIGN(mod->init_layout.size, + __alignof__(struct mod_kallsyms)); + info->mod_kallsyms_init_off =3D mod->init_layout.size; + mod->init_layout.size +=3D sizeof(struct mod_kallsyms); + info->init_typeoffs =3D mod->init_layout.size; + mod->init_layout.size +=3D nsrc * sizeof(char); + mod->init_layout.size =3D debug_align(mod->init_layout.size); +} + +/* + * We use the full symtab and strtab which layout_symtab arranged to + * be appended to the init section. Later we switch to the cut-down + * core-only ones. + */ +void add_kallsyms(struct module *mod, const struct load_info *info) +{ + unsigned int i, ndst; + const Elf_Sym *src; + Elf_Sym *dst; + char *s; + Elf_Shdr *symsec =3D &info->sechdrs[info->index.sym]; + + /* Set up to point into init section. */ + mod->kallsyms =3D mod->init_layout.base + info->mod_kallsyms_init_off; + + mod->kallsyms->symtab =3D (void *)symsec->sh_addr; + mod->kallsyms->num_symtab =3D symsec->sh_size / sizeof(Elf_Sym); + /* Make sure we get permanent strtab: don't use info->strtab. */ + mod->kallsyms->strtab =3D (void *)info->sechdrs[info->index.str].sh_addr; + mod->kallsyms->typetab =3D mod->init_layout.base + info->init_typeoffs; + + /* + * Now populate the cut down core kallsyms for after init + * and set types up while we still have access to sections. + */ + mod->core_kallsyms.symtab =3D dst =3D mod->core_layout.base + info->symof= fs; + mod->core_kallsyms.strtab =3D s =3D mod->core_layout.base + info->stroffs; + mod->core_kallsyms.typetab =3D mod->core_layout.base + info->core_typeoff= s; + src =3D mod->kallsyms->symtab; + for (ndst =3D i =3D 0; i < mod->kallsyms->num_symtab; i++) { + mod->kallsyms->typetab[i] =3D elf_type(src + i, info); + if (i =3D=3D 0 || is_livepatch_module(mod) || + is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, + info->index.pcpu)) { + mod->core_kallsyms.typetab[ndst] =3D + mod->kallsyms->typetab[i]; + dst[ndst] =3D src[i]; + dst[ndst++].st_name =3D s - mod->core_kallsyms.strtab; + s +=3D strlcpy(s, &mod->kallsyms->strtab[src[i].st_name], + KSYM_NAME_LEN) + 1; + } + } + mod->core_kallsyms.num_symtab =3D ndst; +} + +inline bool sect_empty(const Elf_Shdr *sect) +{ + return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size =3D=3D 0; +} + +#ifdef CONFIG_STACKTRACE_BUILD_ID +void init_build_id(struct module *mod, const struct load_info *info) +{ + const Elf_Shdr *sechdr; + unsigned int i; + + for (i =3D 0; i < info->hdr->e_shnum; i++) { + sechdr =3D &info->sechdrs[i]; + if (!sect_empty(sechdr) && sechdr->sh_type =3D=3D SHT_NOTE && + !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id, + sechdr->sh_size)) + break; + } +} +#endif + +/* + * This ignores the intensely annoying "mapping symbols" found + * in ARM ELF files: $a, $t and $d. + */ +static inline int is_arm_mapping_symbol(const char *str) +{ + if (str[0] =3D=3D '.' && str[1] =3D=3D 'L') + return true; + return str[0] =3D=3D '$' && strchr("axtd", str[1]) + && (str[2] =3D=3D '\0' || str[2] =3D=3D '.'); +} + +static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, uns= igned int symnum) +{ + return kallsyms->strtab + kallsyms->symtab[symnum].st_name; +} + +/* + * Given a module and address, find the corresponding symbol and return it= s name + * while providing its size and offset if needed. + */ +const char *find_kallsyms_symbol(struct module *mod, + unsigned long addr, + unsigned long *size, + unsigned long *offset) +{ + unsigned int i, best =3D 0; + unsigned long nextval, bestval; + struct mod_kallsyms *kallsyms =3D rcu_dereference_sched(mod->kallsyms); + + /* At worse, next value is at end of module */ + if (within_module_init(addr, mod)) + nextval =3D (unsigned long)mod->init_layout.base+mod->init_layout.text_s= ize; + else + nextval =3D (unsigned long)mod->core_layout.base+mod->core_layout.text_s= ize; + + bestval =3D kallsyms_symbol_value(&kallsyms->symtab[best]); + + /* + * Scan for closest preceding symbol, and next symbol. (ELF + * starts real symbols at 1). + */ + for (i =3D 1; i < kallsyms->num_symtab; i++) { + const Elf_Sym *sym =3D &kallsyms->symtab[i]; + unsigned long thisval =3D kallsyms_symbol_value(sym); + + if (sym->st_shndx =3D=3D SHN_UNDEF) + continue; + + /* + * We ignore unnamed symbols: they're uninformative + * and inserted at a whim. + */ + if (*kallsyms_symbol_name(kallsyms, i) =3D=3D '\0' + || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) + continue; + + if (thisval <=3D addr && thisval > bestval) { + best =3D i; + bestval =3D thisval; + } + if (thisval > addr && thisval < nextval) + nextval =3D thisval; + } + + if (!best) + return NULL; + + if (size) + *size =3D nextval - bestval; + if (offset) + *offset =3D addr - bestval; + + return kallsyms_symbol_name(kallsyms, best); +} + +void * __weak dereference_module_function_descriptor(struct module *mod, + void *ptr) +{ + return ptr; +} + +/* + * For kallsyms to ask for address resolution. NULL means not found. Car= eful + * not to lock to avoid deadlock on oopses, simply disable preemption. + */ +const char *module_address_lookup(unsigned long addr, + unsigned long *size, + unsigned long *offset, + char **modname, + const unsigned char **modbuildid, + char *namebuf) +{ + const char *ret =3D NULL; + struct module *mod; + + preempt_disable(); + mod =3D __module_address(addr); + if (mod) { + if (modname) + *modname =3D mod->name; + if (modbuildid) { +#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) + *modbuildid =3D mod->build_id; +#else + *modbuildid =3D NULL; +#endif + } + + ret =3D find_kallsyms_symbol(mod, addr, size, offset); + } + /* Make a copy in here where it's safe */ + if (ret) { + strncpy(namebuf, ret, KSYM_NAME_LEN - 1); + ret =3D namebuf; + } + preempt_enable(); + + return ret; +} + +int lookup_module_symbol_name(unsigned long addr, char *symname) +{ + struct module *mod; + + preempt_disable(); + list_for_each_entry_rcu(mod, &modules, list) { + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + continue; + if (within_module(addr, mod)) { + const char *sym; + + sym =3D find_kallsyms_symbol(mod, addr, NULL, NULL); + if (!sym) + goto out; + + strlcpy(symname, sym, KSYM_NAME_LEN); + preempt_enable(); + return 0; + } + } +out: + preempt_enable(); + return -ERANGE; +} + +int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, + unsigned long *offset, char *modname, char *name) +{ + struct module *mod; + + preempt_disable(); + list_for_each_entry_rcu(mod, &modules, list) { + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + continue; + if (within_module(addr, mod)) { + const char *sym; + + sym =3D find_kallsyms_symbol(mod, addr, size, offset); + if (!sym) + goto out; + if (modname) + strlcpy(modname, mod->name, MODULE_NAME_LEN); + if (name) + strlcpy(name, sym, KSYM_NAME_LEN); + preempt_enable(); + return 0; + } + } +out: + preempt_enable(); + return -ERANGE; +} + +int module_get_kallsym(unsigned int symnum, unsigned long *value, char *ty= pe, + char *name, char *module_name, int *exported) +{ + struct module *mod; + + preempt_disable(); + list_for_each_entry_rcu(mod, &modules, list) { + struct mod_kallsyms *kallsyms; + + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + continue; + kallsyms =3D rcu_dereference_sched(mod->kallsyms); + if (symnum < kallsyms->num_symtab) { + const Elf_Sym *sym =3D &kallsyms->symtab[symnum]; + + *value =3D kallsyms_symbol_value(sym); + *type =3D kallsyms->typetab[symnum]; + strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); + strlcpy(module_name, mod->name, MODULE_NAME_LEN); + *exported =3D is_exported(name, *value, mod); + preempt_enable(); + return 0; + } + symnum -=3D kallsyms->num_symtab; + } + preempt_enable(); + return -ERANGE; +} + +/* Given a module and name of symbol, find and return the symbol's value */ +static unsigned long find_kallsyms_symbol_value(struct module *mod, const = char *name) +{ + unsigned int i; + struct mod_kallsyms *kallsyms =3D rcu_dereference_sched(mod->kallsyms); + + for (i =3D 0; i < kallsyms->num_symtab; i++) { + const Elf_Sym *sym =3D &kallsyms->symtab[i]; + + if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) =3D=3D 0 && + sym->st_shndx !=3D SHN_UNDEF) + return kallsyms_symbol_value(sym); + } + return 0; +} + +/* Look for this name: can be of form module:name. */ +unsigned long module_kallsyms_lookup_name(const char *name) +{ + struct module *mod; + char *colon; + unsigned long ret =3D 0; + + /* Don't lock: we're in enough trouble already. */ + preempt_disable(); + if ((colon =3D strnchr(name, MODULE_NAME_LEN, ':')) !=3D NULL) { + if ((mod =3D find_module_all(name, colon - name, false)) !=3D NULL) + ret =3D find_kallsyms_symbol_value(mod, colon+1); + } else { + list_for_each_entry_rcu(mod, &modules, list) { + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + continue; + if ((ret =3D find_kallsyms_symbol_value(mod, name)) !=3D 0) + break; + } + } + preempt_enable(); + return ret; +} + +#ifdef CONFIG_LIVEPATCH +int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, + struct module *, unsigned long), + void *data) +{ + struct module *mod; + unsigned int i; + int ret =3D 0; + + mutex_lock(&module_mutex); + list_for_each_entry(mod, &modules, list) { + /* We hold module_mutex: no need for rcu_dereference_sched */ + struct mod_kallsyms *kallsyms =3D mod->kallsyms; + + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + continue; + for (i =3D 0; i < kallsyms->num_symtab; i++) { + const Elf_Sym *sym =3D &kallsyms->symtab[i]; + + if (sym->st_shndx =3D=3D SHN_UNDEF) + continue; + + ret =3D fn(data, kallsyms_symbol_name(kallsyms, i), + mod, kallsyms_symbol_value(sym)); + if (ret !=3D 0) + goto out; + } + } +out: + mutex_unlock(&module_mutex); + return ret; +} +#endif /* CONFIG_LIVEPATCH */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 672a977b1320..9813e1672d8c 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -275,7 +275,7 @@ static bool check_exported_symbol(const struct symsearc= h *syms, return true; } =20 -static unsigned long kernel_symbol_value(const struct kernel_symbol *sym) +unsigned long kernel_symbol_value(const struct kernel_symbol *sym) { #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS return (unsigned long)offset_to_ptr(&sym->value_offset); @@ -304,7 +304,7 @@ static const char *kernel_symbol_namespace(const struct= kernel_symbol *sym) #endif } =20 -static int cmp_name(const void *name, const void *sym) +int cmp_name(const void *name, const void *sym) { return strcmp(name, kernel_symbol_name(sym)); } @@ -374,7 +374,7 @@ static bool find_symbol(struct find_symbol_arg *fsa) * Search for module by name: must hold module_mutex (or preempt disabled * for read-only access). */ -static struct module *find_module_all(const char *name, size_t len, +struct module *find_module_all(const char *name, size_t len, bool even_unformed) { struct module *mod; @@ -1282,13 +1282,6 @@ resolve_symbol_wait(struct module *mod, return ksym; } =20 -#ifdef CONFIG_KALLSYMS -static inline bool sect_empty(const Elf_Shdr *sect) -{ - return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size =3D=3D 0; -} -#endif - /* * /sys/module/foo/sections stuff * J. Corbet @@ -2013,7 +2006,7 @@ unsigned int __weak arch_mod_section_prepend(struct m= odule *mod, } =20 /* Update size with this section: return offset. */ -static long get_offset(struct module *mod, unsigned int *size, +long get_offset(struct module *mod, unsigned int *size, Elf_Shdr *sechdr, unsigned int section) { long ret; @@ -2215,228 +2208,6 @@ static void free_modinfo(struct module *mod) } } =20 -#ifdef CONFIG_KALLSYMS - -/* Lookup exported symbol in given range of kernel_symbols */ -static const struct kernel_symbol *lookup_exported_symbol(const char *name, - const struct kernel_symbol *start, - const struct kernel_symbol *stop) -{ - return bsearch(name, start, stop - start, - sizeof(struct kernel_symbol), cmp_name); -} - -static int is_exported(const char *name, unsigned long value, - const struct module *mod) -{ - const struct kernel_symbol *ks; - if (!mod) - ks =3D lookup_exported_symbol(name, __start___ksymtab, __stop___ksymtab); - else - ks =3D lookup_exported_symbol(name, mod->syms, mod->syms + mod->num_syms= ); - - return ks !=3D NULL && kernel_symbol_value(ks) =3D=3D value; -} - -/* As per nm */ -static char elf_type(const Elf_Sym *sym, const struct load_info *info) -{ - const Elf_Shdr *sechdrs =3D info->sechdrs; - - if (ELF_ST_BIND(sym->st_info) =3D=3D STB_WEAK) { - if (ELF_ST_TYPE(sym->st_info) =3D=3D STT_OBJECT) - return 'v'; - else - return 'w'; - } - if (sym->st_shndx =3D=3D SHN_UNDEF) - return 'U'; - if (sym->st_shndx =3D=3D SHN_ABS || sym->st_shndx =3D=3D info->index.pcpu) - return 'a'; - if (sym->st_shndx >=3D SHN_LORESERVE) - return '?'; - if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR) - return 't'; - if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC - && sechdrs[sym->st_shndx].sh_type !=3D SHT_NOBITS) { - if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE)) - return 'r'; - else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) - return 'g'; - else - return 'd'; - } - if (sechdrs[sym->st_shndx].sh_type =3D=3D SHT_NOBITS) { - if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL) - return 's'; - else - return 'b'; - } - if (strstarts(info->secstrings + sechdrs[sym->st_shndx].sh_name, - ".debug")) { - return 'n'; - } - return '?'; -} - -static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, - unsigned int shnum, unsigned int pcpundx) -{ - const Elf_Shdr *sec; - - if (src->st_shndx =3D=3D SHN_UNDEF - || src->st_shndx >=3D shnum - || !src->st_name) - return false; - -#ifdef CONFIG_KALLSYMS_ALL - if (src->st_shndx =3D=3D pcpundx) - return true; -#endif - - sec =3D sechdrs + src->st_shndx; - if (!(sec->sh_flags & SHF_ALLOC) -#ifndef CONFIG_KALLSYMS_ALL - || !(sec->sh_flags & SHF_EXECINSTR) -#endif - || (sec->sh_entsize & INIT_OFFSET_MASK)) - return false; - - return true; -} - -/* - * We only allocate and copy the strings needed by the parts of symtab - * we keep. This is simple, but has the effect of making multiple - * copies of duplicates. We could be more sophisticated, see - * linux-kernel thread starting with - * <73defb5e4bca04a6431392cc341112b1@localhost>. - */ -static void layout_symtab(struct module *mod, struct load_info *info) -{ - Elf_Shdr *symsect =3D info->sechdrs + info->index.sym; - Elf_Shdr *strsect =3D info->sechdrs + info->index.str; - const Elf_Sym *src; - unsigned int i, nsrc, ndst, strtab_size =3D 0; - - /* Put symbol section at end of init part of module. */ - symsect->sh_flags |=3D SHF_ALLOC; - symsect->sh_entsize =3D get_offset(mod, &mod->init_layout.size, symsect, - info->index.sym) | INIT_OFFSET_MASK; - pr_debug("\t%s\n", info->secstrings + symsect->sh_name); - - src =3D (void *)info->hdr + symsect->sh_offset; - nsrc =3D symsect->sh_size / sizeof(*src); - - /* Compute total space required for the core symbols' strtab. */ - for (ndst =3D i =3D 0; i < nsrc; i++) { - if (i =3D=3D 0 || is_livepatch_module(mod) || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, - info->index.pcpu)) { - strtab_size +=3D strlen(&info->strtab[src[i].st_name])+1; - ndst++; - } - } - - /* Append room for core symbols at end of core part. */ - info->symoffs =3D ALIGN(mod->core_layout.size, symsect->sh_addralign ?: 1= ); - info->stroffs =3D mod->core_layout.size =3D info->symoffs + ndst * sizeof= (Elf_Sym); - mod->core_layout.size +=3D strtab_size; - info->core_typeoffs =3D mod->core_layout.size; - mod->core_layout.size +=3D ndst * sizeof(char); - mod->core_layout.size =3D debug_align(mod->core_layout.size); - - /* Put string table section at end of init part of module. */ - strsect->sh_flags |=3D SHF_ALLOC; - strsect->sh_entsize =3D get_offset(mod, &mod->init_layout.size, strsect, - info->index.str) | INIT_OFFSET_MASK; - pr_debug("\t%s\n", info->secstrings + strsect->sh_name); - - /* We'll tack temporary mod_kallsyms on the end. */ - mod->init_layout.size =3D ALIGN(mod->init_layout.size, - __alignof__(struct mod_kallsyms)); - info->mod_kallsyms_init_off =3D mod->init_layout.size; - mod->init_layout.size +=3D sizeof(struct mod_kallsyms); - info->init_typeoffs =3D mod->init_layout.size; - mod->init_layout.size +=3D nsrc * sizeof(char); - mod->init_layout.size =3D debug_align(mod->init_layout.size); -} - -/* - * We use the full symtab and strtab which layout_symtab arranged to - * be appended to the init section. Later we switch to the cut-down - * core-only ones. - */ -static void add_kallsyms(struct module *mod, const struct load_info *info) -{ - unsigned int i, ndst; - const Elf_Sym *src; - Elf_Sym *dst; - char *s; - Elf_Shdr *symsec =3D &info->sechdrs[info->index.sym]; - - /* Set up to point into init section. */ - mod->kallsyms =3D mod->init_layout.base + info->mod_kallsyms_init_off; - - mod->kallsyms->symtab =3D (void *)symsec->sh_addr; - mod->kallsyms->num_symtab =3D symsec->sh_size / sizeof(Elf_Sym); - /* Make sure we get permanent strtab: don't use info->strtab. */ - mod->kallsyms->strtab =3D (void *)info->sechdrs[info->index.str].sh_addr; - mod->kallsyms->typetab =3D mod->init_layout.base + info->init_typeoffs; - - /* - * Now populate the cut down core kallsyms for after init - * and set types up while we still have access to sections. - */ - mod->core_kallsyms.symtab =3D dst =3D mod->core_layout.base + info->symof= fs; - mod->core_kallsyms.strtab =3D s =3D mod->core_layout.base + info->stroffs; - mod->core_kallsyms.typetab =3D mod->core_layout.base + info->core_typeoff= s; - src =3D mod->kallsyms->symtab; - for (ndst =3D i =3D 0; i < mod->kallsyms->num_symtab; i++) { - mod->kallsyms->typetab[i] =3D elf_type(src + i, info); - if (i =3D=3D 0 || is_livepatch_module(mod) || - is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum, - info->index.pcpu)) { - mod->core_kallsyms.typetab[ndst] =3D - mod->kallsyms->typetab[i]; - dst[ndst] =3D src[i]; - dst[ndst++].st_name =3D s - mod->core_kallsyms.strtab; - s +=3D strlcpy(s, &mod->kallsyms->strtab[src[i].st_name], - KSYM_NAME_LEN) + 1; - } - } - mod->core_kallsyms.num_symtab =3D ndst; -} -#else -static inline void layout_symtab(struct module *mod, struct load_info *inf= o) -{ -} - -static void add_kallsyms(struct module *mod, const struct load_info *info) -{ -} -#endif /* CONFIG_KALLSYMS */ - -#if IS_ENABLED(CONFIG_KALLSYMS) && IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) -static void init_build_id(struct module *mod, const struct load_info *info) -{ - const Elf_Shdr *sechdr; - unsigned int i; - - for (i =3D 0; i < info->hdr->e_shnum; i++) { - sechdr =3D &info->sechdrs[i]; - if (!sect_empty(sechdr) && sechdr->sh_type =3D=3D SHT_NOTE && - !build_id_parse_buf((void *)sechdr->sh_addr, mod->build_id, - sechdr->sh_size)) - break; - } -} -#else -static void init_build_id(struct module *mod, const struct load_info *info) -{ -} -#endif - static void dynamic_debug_setup(struct module *mod, struct _ddebug *debug,= unsigned int num) { if (!debug) @@ -3702,285 +3473,6 @@ static inline int within(unsigned long addr, void *= start, unsigned long size) return ((void *)addr >=3D start && (void *)addr < start + size); } =20 -#ifdef CONFIG_KALLSYMS -/* - * This ignores the intensely annoying "mapping symbols" found - * in ARM ELF files: $a, $t and $d. - */ -static inline int is_arm_mapping_symbol(const char *str) -{ - if (str[0] =3D=3D '.' && str[1] =3D=3D 'L') - return true; - return str[0] =3D=3D '$' && strchr("axtd", str[1]) - && (str[2] =3D=3D '\0' || str[2] =3D=3D '.'); -} - -static const char *kallsyms_symbol_name(struct mod_kallsyms *kallsyms, uns= igned int symnum) -{ - return kallsyms->strtab + kallsyms->symtab[symnum].st_name; -} - -/* - * Given a module and address, find the corresponding symbol and return it= s name - * while providing its size and offset if needed. - */ -static const char *find_kallsyms_symbol(struct module *mod, - unsigned long addr, - unsigned long *size, - unsigned long *offset) -{ - unsigned int i, best =3D 0; - unsigned long nextval, bestval; - struct mod_kallsyms *kallsyms =3D rcu_dereference_sched(mod->kallsyms); - - /* At worse, next value is at end of module */ - if (within_module_init(addr, mod)) - nextval =3D (unsigned long)mod->init_layout.base+mod->init_layout.text_s= ize; - else - nextval =3D (unsigned long)mod->core_layout.base+mod->core_layout.text_s= ize; - - bestval =3D kallsyms_symbol_value(&kallsyms->symtab[best]); - - /* - * Scan for closest preceding symbol, and next symbol. (ELF - * starts real symbols at 1). - */ - for (i =3D 1; i < kallsyms->num_symtab; i++) { - const Elf_Sym *sym =3D &kallsyms->symtab[i]; - unsigned long thisval =3D kallsyms_symbol_value(sym); - - if (sym->st_shndx =3D=3D SHN_UNDEF) - continue; - - /* - * We ignore unnamed symbols: they're uninformative - * and inserted at a whim. - */ - if (*kallsyms_symbol_name(kallsyms, i) =3D=3D '\0' - || is_arm_mapping_symbol(kallsyms_symbol_name(kallsyms, i))) - continue; - - if (thisval <=3D addr && thisval > bestval) { - best =3D i; - bestval =3D thisval; - } - if (thisval > addr && thisval < nextval) - nextval =3D thisval; - } - - if (!best) - return NULL; - - if (size) - *size =3D nextval - bestval; - if (offset) - *offset =3D addr - bestval; - - return kallsyms_symbol_name(kallsyms, best); -} - -void * __weak dereference_module_function_descriptor(struct module *mod, - void *ptr) -{ - return ptr; -} - -/* - * For kallsyms to ask for address resolution. NULL means not found. Car= eful - * not to lock to avoid deadlock on oopses, simply disable preemption. - */ -const char *module_address_lookup(unsigned long addr, - unsigned long *size, - unsigned long *offset, - char **modname, - const unsigned char **modbuildid, - char *namebuf) -{ - const char *ret =3D NULL; - struct module *mod; - - preempt_disable(); - mod =3D __module_address(addr); - if (mod) { - if (modname) - *modname =3D mod->name; - if (modbuildid) { -#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) - *modbuildid =3D mod->build_id; -#else - *modbuildid =3D NULL; -#endif - } - - ret =3D find_kallsyms_symbol(mod, addr, size, offset); - } - /* Make a copy in here where it's safe */ - if (ret) { - strncpy(namebuf, ret, KSYM_NAME_LEN - 1); - ret =3D namebuf; - } - preempt_enable(); - - return ret; -} - -int lookup_module_symbol_name(unsigned long addr, char *symname) -{ - struct module *mod; - - preempt_disable(); - list_for_each_entry_rcu(mod, &modules, list) { - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - continue; - if (within_module(addr, mod)) { - const char *sym; - - sym =3D find_kallsyms_symbol(mod, addr, NULL, NULL); - if (!sym) - goto out; - - strlcpy(symname, sym, KSYM_NAME_LEN); - preempt_enable(); - return 0; - } - } -out: - preempt_enable(); - return -ERANGE; -} - -int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size, - unsigned long *offset, char *modname, char *name) -{ - struct module *mod; - - preempt_disable(); - list_for_each_entry_rcu(mod, &modules, list) { - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - continue; - if (within_module(addr, mod)) { - const char *sym; - - sym =3D find_kallsyms_symbol(mod, addr, size, offset); - if (!sym) - goto out; - if (modname) - strlcpy(modname, mod->name, MODULE_NAME_LEN); - if (name) - strlcpy(name, sym, KSYM_NAME_LEN); - preempt_enable(); - return 0; - } - } -out: - preempt_enable(); - return -ERANGE; -} - -int module_get_kallsym(unsigned int symnum, unsigned long *value, char *ty= pe, - char *name, char *module_name, int *exported) -{ - struct module *mod; - - preempt_disable(); - list_for_each_entry_rcu(mod, &modules, list) { - struct mod_kallsyms *kallsyms; - - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - continue; - kallsyms =3D rcu_dereference_sched(mod->kallsyms); - if (symnum < kallsyms->num_symtab) { - const Elf_Sym *sym =3D &kallsyms->symtab[symnum]; - - *value =3D kallsyms_symbol_value(sym); - *type =3D kallsyms->typetab[symnum]; - strlcpy(name, kallsyms_symbol_name(kallsyms, symnum), KSYM_NAME_LEN); - strlcpy(module_name, mod->name, MODULE_NAME_LEN); - *exported =3D is_exported(name, *value, mod); - preempt_enable(); - return 0; - } - symnum -=3D kallsyms->num_symtab; - } - preempt_enable(); - return -ERANGE; -} - -/* Given a module and name of symbol, find and return the symbol's value */ -static unsigned long find_kallsyms_symbol_value(struct module *mod, const = char *name) -{ - unsigned int i; - struct mod_kallsyms *kallsyms =3D rcu_dereference_sched(mod->kallsyms); - - for (i =3D 0; i < kallsyms->num_symtab; i++) { - const Elf_Sym *sym =3D &kallsyms->symtab[i]; - - if (strcmp(name, kallsyms_symbol_name(kallsyms, i)) =3D=3D 0 && - sym->st_shndx !=3D SHN_UNDEF) - return kallsyms_symbol_value(sym); - } - return 0; -} - -/* Look for this name: can be of form module:name. */ -unsigned long module_kallsyms_lookup_name(const char *name) -{ - struct module *mod; - char *colon; - unsigned long ret =3D 0; - - /* Don't lock: we're in enough trouble already. */ - preempt_disable(); - if ((colon =3D strnchr(name, MODULE_NAME_LEN, ':')) !=3D NULL) { - if ((mod =3D find_module_all(name, colon - name, false)) !=3D NULL) - ret =3D find_kallsyms_symbol_value(mod, colon+1); - } else { - list_for_each_entry_rcu(mod, &modules, list) { - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - continue; - if ((ret =3D find_kallsyms_symbol_value(mod, name)) !=3D 0) - break; - } - } - preempt_enable(); - return ret; -} - -#ifdef CONFIG_LIVEPATCH -int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *, - struct module *, unsigned long), - void *data) -{ - struct module *mod; - unsigned int i; - int ret =3D 0; - - mutex_lock(&module_mutex); - list_for_each_entry(mod, &modules, list) { - /* We hold module_mutex: no need for rcu_dereference_sched */ - struct mod_kallsyms *kallsyms =3D mod->kallsyms; - - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - continue; - for (i =3D 0; i < kallsyms->num_symtab; i++) { - const Elf_Sym *sym =3D &kallsyms->symtab[i]; - - if (sym->st_shndx =3D=3D SHN_UNDEF) - continue; - - ret =3D fn(data, kallsyms_symbol_name(kallsyms, i), - mod, kallsyms_symbol_value(sym)); - if (ret !=3D 0) - goto out; - } - } -out: - mutex_unlock(&module_mutex); - return ret; -} -#endif /* CONFIG_LIVEPATCH */ -#endif /* CONFIG_KALLSYMS */ - static void cfi_init(struct module *mod) { #ifdef CONFIG_CFI_CLANG --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 5ABD6C433EF for ; Tue, 28 Dec 2021 21:31:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237619AbhL1VbF (ORCPT ); Tue, 28 Dec 2021 16:31:05 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:38624 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237488AbhL1Vaz (ORCPT ); Tue, 28 Dec 2021 16:30:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727055; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VxUWH6ivJOFpbXbRPW5hN0FCZVwBuQeN4pyxAhArSmU=; b=Eunm4fzEfA05LCKvI4WPlbg9YzO982uZ2vNSyM04r/NTNLBazhdaRawWsZN+I1lLDDQKUS dAbr0mArAYifOsZlywbCGCeO6yWJhQ8kSIrPJYs06uEV2DLnfqhfImdBW4JKQ5phczXfeL MKsqXXs86AW9vY+gokGLFXR8mciLrXo= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-672-V9n4iVyKMs6eI9MV8rfE7w-1; Tue, 28 Dec 2021 16:30:53 -0500 X-MC-Unique: V9n4iVyKMs6eI9MV8rfE7w-1 Received: by mail-wr1-f69.google.com with SMTP id a11-20020adffb8b000000b001a0b0f4afe9so4304178wrr.13 for ; Tue, 28 Dec 2021 13:30:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VxUWH6ivJOFpbXbRPW5hN0FCZVwBuQeN4pyxAhArSmU=; b=Y0o29dHwQ7PHaoNR7odHVfNvruze8WfKWlfKGMzHgbGeD5Zcmlf/nlEX8FzSwPq38w xdAmUNj40DTaW+3P2C9/1lV6yrGljevaLAsSYBqTlpcwxHT8EtinnqXn/ImCpuktq5fR Ktw++b7va4FatwfEd5MJEUdX7G49HGm2E6ZKHtUCwA+0h5SsDCFigFUi9r6LrZCcVnei jgBbAmMwzKt6OrkEWkaW0kWqZiS6YDDtUNu1Syl/hEfkarQQBuVunKLCqpITg9rJyFC8 Fbw5gqasuTA8Gnm8BwSlZiAfv8bAsmOPB3g8mT07RsFHV8/2nnvHaeNUWUn2VMOOXcpt YAnQ== X-Gm-Message-State: AOAM531zhU6Pp29QordIASfNBIv8j/tavzD0AXRG9QOKS5NpMeDxb+tm QebLyxO1GcOnEvkfrrrjH2HKbNddqlayRtwJB1Ud++WAkkZSBLvMv7rSyLVPxz4L6jZjtWJG9IW p1D2QrHJksZcoF/80rM+do2s= X-Received: by 2002:adf:e8d2:: with SMTP id k18mr18380369wrn.187.1640727052372; Tue, 28 Dec 2021 13:30:52 -0800 (PST) X-Google-Smtp-Source: ABdhPJx4lnaBslQfygUi2472o/r+KKnzwYQz+fbWy70cSMdNOs9GmXSxbGajrT7AXC8VOnkwen0NtQ== X-Received: by 2002:adf:e8d2:: with SMTP id k18mr18380348wrn.187.1640727052121; Tue, 28 Dec 2021 13:30:52 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id e12sm20481584wrg.110.2021.12.28.13.30.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:51 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 10/12] module: Move procfs support into a separate file Date: Tue, 28 Dec 2021 21:30:39 +0000 Message-Id: <20211228213041.1356334-11-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates code that allows one to generate a list of loaded/or linked modules via /proc when procfs support is enabled into kernel/module/procfs.c. Signed-off-by: Aaron Tomlin --- kernel/module/Makefile | 1 + kernel/module/main.c | 98 ------------------------------------- kernel/module/procfs.c | 108 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 98 deletions(-) create mode 100644 kernel/module/procfs.c diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 23582011ab08..cba3e608b4ca 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_ARCH_HAS_STRICT_MODULE_RWX) +=3D arch_strict= _rwx.o obj-$(CONFIG_STRICT_MODULE_RWX) +=3D strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) +=3D debug_kmemleak.o obj-$(CONFIG_KALLSYMS) +=3D kallsyms.o +obj-$(CONFIG_PROC_FS) +=3D procfs.o diff --git a/kernel/module/main.c b/kernel/module/main.c index 9813e1672d8c..2da580c7b069 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -3529,103 +3528,6 @@ static char *module_flags(struct module *mod, char = *buf) return buf; } =20 -#ifdef CONFIG_PROC_FS -/* Called by the /proc file system to return a list of modules. */ -static void *m_start(struct seq_file *m, loff_t *pos) -{ - mutex_lock(&module_mutex); - return seq_list_start(&modules, *pos); -} - -static void *m_next(struct seq_file *m, void *p, loff_t *pos) -{ - return seq_list_next(p, &modules, pos); -} - -static void m_stop(struct seq_file *m, void *p) -{ - mutex_unlock(&module_mutex); -} - -static int m_show(struct seq_file *m, void *p) -{ - struct module *mod =3D list_entry(p, struct module, list); - char buf[MODULE_FLAGS_BUF_SIZE]; - void *value; - - /* We always ignore unformed modules. */ - if (mod->state =3D=3D MODULE_STATE_UNFORMED) - return 0; - - seq_printf(m, "%s %u", - mod->name, mod->init_layout.size + mod->core_layout.size); - print_unload_info(m, mod); - - /* Informative for users. */ - seq_printf(m, " %s", - mod->state =3D=3D MODULE_STATE_GOING ? "Unloading" : - mod->state =3D=3D MODULE_STATE_COMING ? "Loading" : - "Live"); - /* Used by oprofile and other similar tools. */ - value =3D m->private ? NULL : mod->core_layout.base; - seq_printf(m, " 0x%px", value); - - /* Taints info */ - if (mod->taints) - seq_printf(m, " %s", module_flags(mod, buf)); - - seq_puts(m, "\n"); - return 0; -} - -/* - * Format: modulename size refcount deps address - * - * Where refcount is a number or -, and deps is a comma-separated list - * of depends or -. - */ -static const struct seq_operations modules_op =3D { - .start =3D m_start, - .next =3D m_next, - .stop =3D m_stop, - .show =3D m_show -}; - -/* - * This also sets the "private" pointer to non-NULL if the - * kernel pointers should be hidden (so you can just test - * "m->private" to see if you should keep the values private). - * - * We use the same logic as for /proc/kallsyms. - */ -static int modules_open(struct inode *inode, struct file *file) -{ - int err =3D seq_open(file, &modules_op); - - if (!err) { - struct seq_file *m =3D file->private_data; - m->private =3D kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul; - } - - return err; -} - -static const struct proc_ops modules_proc_ops =3D { - .proc_flags =3D PROC_ENTRY_PERMANENT, - .proc_open =3D modules_open, - .proc_read =3D seq_read, - .proc_lseek =3D seq_lseek, - .proc_release =3D seq_release, -}; - -static int __init proc_modules_init(void) -{ - proc_create("modules", 0, NULL, &modules_proc_ops); - return 0; -} -module_init(proc_modules_init); -#endif - /* Given an address, look for it in the module exception tables. */ const struct exception_table_entry *search_module_extables(unsigned long a= ddr) { diff --git a/kernel/module/procfs.c b/kernel/module/procfs.c new file mode 100644 index 000000000000..98d898250475 --- /dev/null +++ b/kernel/module/procfs.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/proc.c - module proc support + * + * Copyright (C) 2008 Alexey Dobriyan + */ + +#include +#include +#include +#include +#include +#include "internal.h" + +/* Called by the /proc file system to return a list of modules. */ +static void *m_start(struct seq_file *m, loff_t *pos) +{ + mutex_lock(&module_mutex); + return seq_list_start(&modules, *pos); +} + +static void *m_next(struct seq_file *m, void *p, loff_t *pos) +{ + return seq_list_next(p, &modules, pos); +} + +static void m_stop(struct seq_file *m, void *p) +{ + mutex_unlock(&module_mutex); +} + +static int m_show(struct seq_file *m, void *p) +{ + struct module *mod =3D list_entry(p, struct module, list); + char buf[MODULE_FLAGS_BUF_SIZE]; + void *value; + + /* We always ignore unformed modules. */ + if (mod->state =3D=3D MODULE_STATE_UNFORMED) + return 0; + + seq_printf(m, "%s %u", + mod->name, mod->init_layout.size + mod->core_layout.size); + print_unload_info(m, mod); + + /* Informative for users. */ + seq_printf(m, " %s", + mod->state =3D=3D MODULE_STATE_GOING ? "Unloading" : + mod->state =3D=3D MODULE_STATE_COMING ? "Loading" : + "Live"); + /* Used by oprofile and other similar tools. */ + value =3D m->private ? NULL : mod->core_layout.base; + seq_printf(m, " 0x%px", value); + + /* Taints info */ + if (mod->taints) + seq_printf(m, " %s", module_flags(mod, buf)); + + seq_puts(m, "\n"); + return 0; +} + +/* + * Format: modulename size refcount deps address + * + * Where refcount is a number or -, and deps is a comma-separated list + * of depends or -. + */ +static const struct seq_operations modules_op =3D { + .start =3D m_start, + .next =3D m_next, + .stop =3D m_stop, + .show =3D m_show +}; + +/* + * This also sets the "private" pointer to non-NULL if the + * kernel pointers should be hidden (so you can just test + * "m->private" to see if you should keep the values private). + * + * We use the same logic as for /proc/kallsyms. + */ +static int modules_open(struct inode *inode, struct file *file) +{ + int err =3D seq_open(file, &modules_op); + + if (!err) { + struct seq_file *m =3D file->private_data; + m->private =3D kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul; + } + + return err; +} + +static const struct proc_ops modules_proc_ops =3D { + .proc_flags =3D PROC_ENTRY_PERMANENT, + .proc_open =3D modules_open, + .proc_read =3D seq_read, + .proc_lseek =3D seq_lseek, + .proc_release =3D seq_release, +}; + +static int __init proc_modules_init(void) +{ + proc_create("modules", 0, NULL, &modules_proc_ops); + return 0; +} +module_init(proc_modules_init); --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 55DCFC433FE for ; Tue, 28 Dec 2021 21:31:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237643AbhL1VbK (ORCPT ); Tue, 28 Dec 2021 16:31:10 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:42659 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237587AbhL1Va5 (ORCPT ); Tue, 28 Dec 2021 16:30:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727056; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Xa7dxlntY/DpkYx7DfautLpI2nhSdeShR7fEHZvJHJg=; b=hdMv+Ud/YKaq10Na5mnRNGKL0p//s/Kp6OxEBUegFoTzKtEZ/gLFY06C2sPKUpRKwnj5Ei kBYAe6rRgBvZlT3Hg8Zur+sOU5Wf5uoS9dRKAM2H1cM4025WTnV0HlWE62YEyWhrYVopWK 2IZgDLl+UR7E4CRbfL7HD0p3c7Swrqk= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-292-pZmfCTWMMWeF_yRKg6kZDQ-1; Tue, 28 Dec 2021 16:30:55 -0500 X-MC-Unique: pZmfCTWMMWeF_yRKg6kZDQ-1 Received: by mail-wr1-f71.google.com with SMTP id d6-20020adfa346000000b001a262748c6fso4288222wrb.12 for ; Tue, 28 Dec 2021 13:30:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Xa7dxlntY/DpkYx7DfautLpI2nhSdeShR7fEHZvJHJg=; b=4MZBigncIwiNUD0Xl1TzKWqP7T1gsnAj7WZKDdqvYRwEkwjrYMpk1yaFimPqQxSRhJ N/4ULRUCGtaKfRXf1TNgJb0sDP3ry1i8+R1JJLS2kxjd4yRifCa7asa0hjXPQC0MjIgt hLa4zS2R91u+DOAAgFeG02SETNmoSh7tMjIwxeueoDLnJH8vTX75SY8O66q0U0gCnXwQ FEd6Q8vL7nh9TyoFs5pwJkMTUoQz6qWeFbBX24dkQzv4ekMQAiEpQj7vBZMKG/57wLIU lIGxYwJrJP1pvBY/jYgizNsS3lctOrO52F2rOp38P88oul44S78MMVoK/nGZhuMNlCxW 617A== X-Gm-Message-State: AOAM530ngub9gx5Qb5V7HYIkR6tASjieG3/UdtxbnqGjoHTuWzlRFjKe Odd3Rc4nKbJaks1bpTx1mco++KYuBYsje+Mx7HkiCwJP/mUrVHlNCIqlZe9Akvs41iV14mZokmb 53wBN0DNR/jkMkuiMY6/WwZQ= X-Received: by 2002:a1c:494:: with SMTP id 142mr19456419wme.191.1640727053836; Tue, 28 Dec 2021 13:30:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJwRr16cZDRN4qIsVfdtpfPWok+Nvwpi5LJtl2+6YvMIyuyZGUCRolJWNwBrYBP91MDRVqWpPg== X-Received: by 2002:a1c:494:: with SMTP id 142mr19456395wme.191.1640727053498; Tue, 28 Dec 2021 13:30:53 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id s207sm19375411wme.2.2021.12.28.13.30.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:52 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 11/12] module: Move sysfs support into a separate file Date: Tue, 28 Dec 2021 21:30:40 +0000 Message-Id: <20211228213041.1356334-12-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates module sysfs support out of core code into kernel/module/sysfs.c. In addition simple code refactoring to make this possible. Signed-off-by: Aaron Tomlin --- kernel/module/Makefile | 1 + kernel/module/internal.h | 20 ++ kernel/module/main.c | 462 +-------------------------------------- kernel/module/procfs.c | 3 + kernel/module/sysfs.c | 426 ++++++++++++++++++++++++++++++++++++ 5 files changed, 455 insertions(+), 457 deletions(-) create mode 100644 kernel/module/sysfs.c diff --git a/kernel/module/Makefile b/kernel/module/Makefile index cba3e608b4ca..917910302ac0 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_STRICT_MODULE_RWX) +=3D strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) +=3D debug_kmemleak.o obj-$(CONFIG_KALLSYMS) +=3D kallsyms.o obj-$(CONFIG_PROC_FS) +=3D procfs.o +obj-$(CONFIG_SYSFS) +=3D sysfs.o diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 119d42c304a1..4d81eb1f58ef 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -99,3 +99,23 @@ static inline char *find_kallsyms_symbol(struct module *= mod, unsigned long addr, return NULL; } #endif /* CONFIG_KALLSYMS */ + +#ifdef CONFIG_SYSFS +extern int mod_sysfs_setup(struct module *mod, const struct load_info *inf= o, struct kernel_param *kparam, unsigned int num_params); +extern void mod_sysfs_fini(struct module *mod); +extern void module_remove_modinfo_attrs(struct module *mod, int end); +extern void del_usage_links(struct module *mod); +extern void init_param_lock(struct module *mod); +#else /* !CONFIG_SYSFS */ +static int mod_sysfs_setup(struct module *mod, + const struct load_info *info, + struct kernel_param *kparam, + unsigned int num_params) +{ + return 0; +} +static inline void mod_sysfs_fini(struct module *mod) { } +static inline void module_remove_modinfo_attrs(struct module *mod, int end= ) { } +static inline void del_usage_links(struct module *mod) { } +static inline void init_param_lock(struct module *mod) { } +#endif /* CONFIG_SYSFS */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 2da580c7b069..354fb2697188 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -13,9 +13,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -801,7 +799,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, nam= e_user, return ret; } =20 -static inline void print_unload_info(struct seq_file *m, struct module *mo= d) +inline void print_unload_info(struct seq_file *m, struct module *mod) { struct module_use *use; int printed_something =3D 0; @@ -1017,7 +1015,7 @@ static ssize_t show_taint(struct module_attribute *ma= ttr, static struct module_attribute modinfo_taint =3D __ATTR(taint, 0444, show_taint, NULL); =20 -static struct module_attribute *modinfo_attrs[] =3D { +struct module_attribute *modinfo_attrs[] =3D { &module_uevent, &modinfo_version, &modinfo_srcversion, @@ -1031,6 +1029,8 @@ static struct module_attribute *modinfo_attrs[] =3D { NULL, }; =20 +size_t modinfo_attrs_count =3D ARRAY_SIZE(modinfo_attrs); + static const char vermagic[] =3D VERMAGIC_STRING; =20 static int try_to_force_load(struct module *mod, const char *reason) @@ -1281,458 +1281,6 @@ resolve_symbol_wait(struct module *mod, return ksym; } =20 -/* - * /sys/module/foo/sections stuff - * J. Corbet - */ -#ifdef CONFIG_SYSFS - -#ifdef CONFIG_KALLSYMS -struct module_sect_attr { - struct bin_attribute battr; - unsigned long address; -}; - -struct module_sect_attrs { - struct attribute_group grp; - unsigned int nsections; - struct module_sect_attr attrs[]; -}; - -static ssize_t module_sect_read(struct file *file, struct kobject *kobj, - struct bin_attribute *battr, - char *buf, loff_t pos, size_t count) -{ - struct module_sect_attr *sattr =3D - container_of(battr, struct module_sect_attr, battr); - char bounce[MODULE_SECT_READ_SIZE + 1]; - size_t wrote; - - if (pos !=3D 0) - return -EINVAL; - - /* - * Since we're a binary read handler, we must account for the - * trailing NUL byte that sprintf will write: if "buf" is - * too small to hold the NUL, or the NUL is exactly the last - * byte, the read will look like it got truncated by one byte. - * Since there is no way to ask sprintf nicely to not write - * the NUL, we have to use a bounce buffer. - */ - wrote =3D scnprintf(bounce, sizeof(bounce), "0x%px\n", - kallsyms_show_value(file->f_cred) - ? (void *)sattr->address : NULL); - count =3D min(count, wrote); - memcpy(buf, bounce, count); - - return count; -} - -static void free_sect_attrs(struct module_sect_attrs *sect_attrs) -{ - unsigned int section; - - for (section =3D 0; section < sect_attrs->nsections; section++) - kfree(sect_attrs->attrs[section].battr.attr.name); - kfree(sect_attrs); -} - -static void add_sect_attrs(struct module *mod, const struct load_info *inf= o) -{ - unsigned int nloaded =3D 0, i, size[2]; - struct module_sect_attrs *sect_attrs; - struct module_sect_attr *sattr; - struct bin_attribute **gattr; - - /* Count loaded sections and allocate structures */ - for (i =3D 0; i < info->hdr->e_shnum; i++) - if (!sect_empty(&info->sechdrs[i])) - nloaded++; - size[0] =3D ALIGN(struct_size(sect_attrs, attrs, nloaded), - sizeof(sect_attrs->grp.bin_attrs[0])); - size[1] =3D (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]); - sect_attrs =3D kzalloc(size[0] + size[1], GFP_KERNEL); - if (sect_attrs =3D=3D NULL) - return; - - /* Setup section attributes. */ - sect_attrs->grp.name =3D "sections"; - sect_attrs->grp.bin_attrs =3D (void *)sect_attrs + size[0]; - - sect_attrs->nsections =3D 0; - sattr =3D §_attrs->attrs[0]; - gattr =3D §_attrs->grp.bin_attrs[0]; - for (i =3D 0; i < info->hdr->e_shnum; i++) { - Elf_Shdr *sec =3D &info->sechdrs[i]; - if (sect_empty(sec)) - continue; - sysfs_bin_attr_init(&sattr->battr); - sattr->address =3D sec->sh_addr; - sattr->battr.attr.name =3D - kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); - if (sattr->battr.attr.name =3D=3D NULL) - goto out; - sect_attrs->nsections++; - sattr->battr.read =3D module_sect_read; - sattr->battr.size =3D MODULE_SECT_READ_SIZE; - sattr->battr.attr.mode =3D 0400; - *(gattr++) =3D &(sattr++)->battr; - } - *gattr =3D NULL; - - if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp)) - goto out; - - mod->sect_attrs =3D sect_attrs; - return; - out: - free_sect_attrs(sect_attrs); -} - -static void remove_sect_attrs(struct module *mod) -{ - if (mod->sect_attrs) { - sysfs_remove_group(&mod->mkobj.kobj, - &mod->sect_attrs->grp); - /* - * We are positive that no one is using any sect attrs - * at this point. Deallocate immediately. - */ - free_sect_attrs(mod->sect_attrs); - mod->sect_attrs =3D NULL; - } -} - -/* - * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections. - */ - -struct module_notes_attrs { - struct kobject *dir; - unsigned int notes; - struct bin_attribute attrs[]; -}; - -static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t count) -{ - /* - * The caller checked the pos and count against our size. - */ - memcpy(buf, bin_attr->private + pos, count); - return count; -} - -static void free_notes_attrs(struct module_notes_attrs *notes_attrs, - unsigned int i) -{ - if (notes_attrs->dir) { - while (i-- > 0) - sysfs_remove_bin_file(notes_attrs->dir, - ¬es_attrs->attrs[i]); - kobject_put(notes_attrs->dir); - } - kfree(notes_attrs); -} - -static void add_notes_attrs(struct module *mod, const struct load_info *in= fo) -{ - unsigned int notes, loaded, i; - struct module_notes_attrs *notes_attrs; - struct bin_attribute *nattr; - - /* failed to create section attributes, so can't create notes */ - if (!mod->sect_attrs) - return; - - /* Count notes sections and allocate structures. */ - notes =3D 0; - for (i =3D 0; i < info->hdr->e_shnum; i++) - if (!sect_empty(&info->sechdrs[i]) && - (info->sechdrs[i].sh_type =3D=3D SHT_NOTE)) - ++notes; - - if (notes =3D=3D 0) - return; - - notes_attrs =3D kzalloc(struct_size(notes_attrs, attrs, notes), - GFP_KERNEL); - if (notes_attrs =3D=3D NULL) - return; - - notes_attrs->notes =3D notes; - nattr =3D ¬es_attrs->attrs[0]; - for (loaded =3D i =3D 0; i < info->hdr->e_shnum; ++i) { - if (sect_empty(&info->sechdrs[i])) - continue; - if (info->sechdrs[i].sh_type =3D=3D SHT_NOTE) { - sysfs_bin_attr_init(nattr); - nattr->attr.name =3D mod->sect_attrs->attrs[loaded].battr.attr.name; - nattr->attr.mode =3D S_IRUGO; - nattr->size =3D info->sechdrs[i].sh_size; - nattr->private =3D (void *) info->sechdrs[i].sh_addr; - nattr->read =3D module_notes_read; - ++nattr; - } - ++loaded; - } - - notes_attrs->dir =3D kobject_create_and_add("notes", &mod->mkobj.kobj); - if (!notes_attrs->dir) - goto out; - - for (i =3D 0; i < notes; ++i) - if (sysfs_create_bin_file(notes_attrs->dir, - ¬es_attrs->attrs[i])) - goto out; - - mod->notes_attrs =3D notes_attrs; - return; - - out: - free_notes_attrs(notes_attrs, i); -} - -static void remove_notes_attrs(struct module *mod) -{ - if (mod->notes_attrs) - free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes); -} - -#else - -static inline void add_sect_attrs(struct module *mod, - const struct load_info *info) -{ -} - -static inline void remove_sect_attrs(struct module *mod) -{ -} - -static inline void add_notes_attrs(struct module *mod, - const struct load_info *info) -{ -} - -static inline void remove_notes_attrs(struct module *mod) -{ -} -#endif /* CONFIG_KALLSYMS */ - -static void del_usage_links(struct module *mod) -{ -#ifdef CONFIG_MODULE_UNLOAD - struct module_use *use; - - mutex_lock(&module_mutex); - list_for_each_entry(use, &mod->target_list, target_list) - sysfs_remove_link(use->target->holders_dir, mod->name); - mutex_unlock(&module_mutex); -#endif -} - -static int add_usage_links(struct module *mod) -{ - int ret =3D 0; -#ifdef CONFIG_MODULE_UNLOAD - struct module_use *use; - - mutex_lock(&module_mutex); - list_for_each_entry(use, &mod->target_list, target_list) { - ret =3D sysfs_create_link(use->target->holders_dir, - &mod->mkobj.kobj, mod->name); - if (ret) - break; - } - mutex_unlock(&module_mutex); - if (ret) - del_usage_links(mod); -#endif - return ret; -} - -static void module_remove_modinfo_attrs(struct module *mod, int end); - -static int module_add_modinfo_attrs(struct module *mod) -{ - struct module_attribute *attr; - struct module_attribute *temp_attr; - int error =3D 0; - int i; - - mod->modinfo_attrs =3D kzalloc((sizeof(struct module_attribute) * - (ARRAY_SIZE(modinfo_attrs) + 1)), - GFP_KERNEL); - if (!mod->modinfo_attrs) - return -ENOMEM; - - temp_attr =3D mod->modinfo_attrs; - for (i =3D 0; (attr =3D modinfo_attrs[i]); i++) { - if (!attr->test || attr->test(mod)) { - memcpy(temp_attr, attr, sizeof(*temp_attr)); - sysfs_attr_init(&temp_attr->attr); - error =3D sysfs_create_file(&mod->mkobj.kobj, - &temp_attr->attr); - if (error) - goto error_out; - ++temp_attr; - } - } - - return 0; - -error_out: - if (i > 0) - module_remove_modinfo_attrs(mod, --i); - else - kfree(mod->modinfo_attrs); - return error; -} - -static void module_remove_modinfo_attrs(struct module *mod, int end) -{ - struct module_attribute *attr; - int i; - - for (i =3D 0; (attr =3D &mod->modinfo_attrs[i]); i++) { - if (end >=3D 0 && i > end) - break; - /* pick a field to test for end of list */ - if (!attr->attr.name) - break; - sysfs_remove_file(&mod->mkobj.kobj, &attr->attr); - if (attr->free) - attr->free(mod); - } - kfree(mod->modinfo_attrs); -} - -static void mod_kobject_put(struct module *mod) -{ - DECLARE_COMPLETION_ONSTACK(c); - mod->mkobj.kobj_completion =3D &c; - kobject_put(&mod->mkobj.kobj); - wait_for_completion(&c); -} - -static int mod_sysfs_init(struct module *mod) -{ - int err; - struct kobject *kobj; - - if (!module_sysfs_initialized) { - pr_err("%s: module sysfs not initialized\n", mod->name); - err =3D -EINVAL; - goto out; - } - - kobj =3D kset_find_obj(module_kset, mod->name); - if (kobj) { - pr_err("%s: module is already loaded\n", mod->name); - kobject_put(kobj); - err =3D -EINVAL; - goto out; - } - - mod->mkobj.mod =3D mod; - - memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); - mod->mkobj.kobj.kset =3D module_kset; - err =3D kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, - "%s", mod->name); - if (err) - mod_kobject_put(mod); - -out: - return err; -} - -static int mod_sysfs_setup(struct module *mod, - const struct load_info *info, - struct kernel_param *kparam, - unsigned int num_params) -{ - int err; - - err =3D mod_sysfs_init(mod); - if (err) - goto out; - - mod->holders_dir =3D kobject_create_and_add("holders", &mod->mkobj.kobj); - if (!mod->holders_dir) { - err =3D -ENOMEM; - goto out_unreg; - } - - err =3D module_param_sysfs_setup(mod, kparam, num_params); - if (err) - goto out_unreg_holders; - - err =3D module_add_modinfo_attrs(mod); - if (err) - goto out_unreg_param; - - err =3D add_usage_links(mod); - if (err) - goto out_unreg_modinfo_attrs; - - add_sect_attrs(mod, info); - add_notes_attrs(mod, info); - - return 0; - -out_unreg_modinfo_attrs: - module_remove_modinfo_attrs(mod, -1); -out_unreg_param: - module_param_sysfs_remove(mod); -out_unreg_holders: - kobject_put(mod->holders_dir); -out_unreg: - mod_kobject_put(mod); -out: - return err; -} - -static void mod_sysfs_fini(struct module *mod) -{ - remove_notes_attrs(mod); - remove_sect_attrs(mod); - mod_kobject_put(mod); -} - -static void init_param_lock(struct module *mod) -{ - mutex_init(&mod->param_lock); -} -#else /* !CONFIG_SYSFS */ - -static int mod_sysfs_setup(struct module *mod, - const struct load_info *info, - struct kernel_param *kparam, - unsigned int num_params) -{ - return 0; -} - -static void mod_sysfs_fini(struct module *mod) -{ -} - -static void module_remove_modinfo_attrs(struct module *mod, int end) -{ -} - -static void del_usage_links(struct module *mod) -{ -} - -static void init_param_lock(struct module *mod) -{ -} -#endif /* CONFIG_SYSFS */ - static void mod_sysfs_teardown(struct module *mod) { del_usage_links(mod); @@ -3505,7 +3053,7 @@ static void cfi_cleanup(struct module *mod) } =20 /* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */ -static char *module_flags(struct module *mod, char *buf) +char *module_flags(struct module *mod, char *buf) { int bx =3D 0; =20 diff --git a/kernel/module/procfs.c b/kernel/module/procfs.c index 98d898250475..365d5e52ac23 100644 --- a/kernel/module/procfs.c +++ b/kernel/module/procfs.c @@ -12,6 +12,9 @@ #include #include "internal.h" =20 +extern void print_unload_info(struct seq_file *m, struct module *mod); +extern char *module_flags(struct module *mod, char *buf); + /* Called by the /proc file system to return a list of modules. */ static void *m_start(struct seq_file *m, loff_t *pos) { diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c new file mode 100644 index 000000000000..1cd91c214b72 --- /dev/null +++ b/kernel/module/sysfs.c @@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * kernel/module/sysfs.c - module sysfs support + * + * Copyright (C) 2008 Rusty Russell + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal.h" + +/* + * /sys/module/foo/sections stuff + * J. Corbet + */ +#ifdef CONFIG_KALLSYMS +struct module_sect_attr { + struct bin_attribute battr; + unsigned long address; +}; + +struct module_sect_attrs { + struct attribute_group grp; + unsigned int nsections; + struct module_sect_attr attrs[]; +}; + +static ssize_t module_sect_read(struct file *file, struct kobject *kobj, + struct bin_attribute *battr, + char *buf, loff_t pos, size_t count) +{ + struct module_sect_attr *sattr =3D + container_of(battr, struct module_sect_attr, battr); + char bounce[MODULE_SECT_READ_SIZE + 1]; + size_t wrote; + + if (pos !=3D 0) + return -EINVAL; + + /* + * Since we're a binary read handler, we must account for the + * trailing NUL byte that sprintf will write: if "buf" is + * too small to hold the NUL, or the NUL is exactly the last + * byte, the read will look like it got truncated by one byte. + * Since there is no way to ask sprintf nicely to not write + * the NUL, we have to use a bounce buffer. + */ + wrote =3D scnprintf(bounce, sizeof(bounce), "0x%px\n", + kallsyms_show_value(file->f_cred) + ? (void *)sattr->address : NULL); + count =3D min(count, wrote); + memcpy(buf, bounce, count); + + return count; +} + +static void free_sect_attrs(struct module_sect_attrs *sect_attrs) +{ + unsigned int section; + + for (section =3D 0; section < sect_attrs->nsections; section++) + kfree(sect_attrs->attrs[section].battr.attr.name); + kfree(sect_attrs); +} + +static void add_sect_attrs(struct module *mod, const struct load_info *inf= o) +{ + unsigned int nloaded =3D 0, i, size[2]; + struct module_sect_attrs *sect_attrs; + struct module_sect_attr *sattr; + struct bin_attribute **gattr; + + /* Count loaded sections and allocate structures */ + for (i =3D 0; i < info->hdr->e_shnum; i++) + if (!sect_empty(&info->sechdrs[i])) + nloaded++; + size[0] =3D ALIGN(struct_size(sect_attrs, attrs, nloaded), + sizeof(sect_attrs->grp.bin_attrs[0])); + size[1] =3D (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]); + sect_attrs =3D kzalloc(size[0] + size[1], GFP_KERNEL); + if (sect_attrs =3D=3D NULL) + return; + + /* Setup section attributes. */ + sect_attrs->grp.name =3D "sections"; + sect_attrs->grp.bin_attrs =3D (void *)sect_attrs + size[0]; + + sect_attrs->nsections =3D 0; + sattr =3D §_attrs->attrs[0]; + gattr =3D §_attrs->grp.bin_attrs[0]; + for (i =3D 0; i < info->hdr->e_shnum; i++) { + Elf_Shdr *sec =3D &info->sechdrs[i]; + if (sect_empty(sec)) + continue; + sysfs_bin_attr_init(&sattr->battr); + sattr->address =3D sec->sh_addr; + sattr->battr.attr.name =3D + kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL); + if (sattr->battr.attr.name =3D=3D NULL) + goto out; + sect_attrs->nsections++; + sattr->battr.read =3D module_sect_read; + sattr->battr.size =3D MODULE_SECT_READ_SIZE; + sattr->battr.attr.mode =3D 0400; + *(gattr++) =3D &(sattr++)->battr; + } + *gattr =3D NULL; + + if (sysfs_create_group(&mod->mkobj.kobj, §_attrs->grp)) + goto out; + + mod->sect_attrs =3D sect_attrs; + return; + out: + free_sect_attrs(sect_attrs); +} + +static void remove_sect_attrs(struct module *mod) +{ + if (mod->sect_attrs) { + sysfs_remove_group(&mod->mkobj.kobj, + &mod->sect_attrs->grp); + /* + * We are positive that no one is using any sect attrs + * at this point. Deallocate immediately. + */ + free_sect_attrs(mod->sect_attrs); + mod->sect_attrs =3D NULL; + } +} + +/* + * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections. + */ + +struct module_notes_attrs { + struct kobject *dir; + unsigned int notes; + struct bin_attribute attrs[]; +}; + +static ssize_t module_notes_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t pos, size_t count) +{ + /* + * The caller checked the pos and count against our size. + */ + memcpy(buf, bin_attr->private + pos, count); + return count; +} + +static void free_notes_attrs(struct module_notes_attrs *notes_attrs, + unsigned int i) +{ + if (notes_attrs->dir) { + while (i-- > 0) + sysfs_remove_bin_file(notes_attrs->dir, + ¬es_attrs->attrs[i]); + kobject_put(notes_attrs->dir); + } + kfree(notes_attrs); +} + +static void add_notes_attrs(struct module *mod, const struct load_info *in= fo) +{ + unsigned int notes, loaded, i; + struct module_notes_attrs *notes_attrs; + struct bin_attribute *nattr; + + /* failed to create section attributes, so can't create notes */ + if (!mod->sect_attrs) + return; + + /* Count notes sections and allocate structures. */ + notes =3D 0; + for (i =3D 0; i < info->hdr->e_shnum; i++) + if (!sect_empty(&info->sechdrs[i]) && + (info->sechdrs[i].sh_type =3D=3D SHT_NOTE)) + ++notes; + + if (notes =3D=3D 0) + return; + + notes_attrs =3D kzalloc(struct_size(notes_attrs, attrs, notes), + GFP_KERNEL); + if (notes_attrs =3D=3D NULL) + return; + + notes_attrs->notes =3D notes; + nattr =3D ¬es_attrs->attrs[0]; + for (loaded =3D i =3D 0; i < info->hdr->e_shnum; ++i) { + if (sect_empty(&info->sechdrs[i])) + continue; + if (info->sechdrs[i].sh_type =3D=3D SHT_NOTE) { + sysfs_bin_attr_init(nattr); + nattr->attr.name =3D mod->sect_attrs->attrs[loaded].battr.attr.name; + nattr->attr.mode =3D S_IRUGO; + nattr->size =3D info->sechdrs[i].sh_size; + nattr->private =3D (void *) info->sechdrs[i].sh_addr; + nattr->read =3D module_notes_read; + ++nattr; + } + ++loaded; + } + + notes_attrs->dir =3D kobject_create_and_add("notes", &mod->mkobj.kobj); + if (!notes_attrs->dir) + goto out; + + for (i =3D 0; i < notes; ++i) + if (sysfs_create_bin_file(notes_attrs->dir, + ¬es_attrs->attrs[i])) + goto out; + + mod->notes_attrs =3D notes_attrs; + return; + + out: + free_notes_attrs(notes_attrs, i); +} + +static void remove_notes_attrs(struct module *mod) +{ + if (mod->notes_attrs) + free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes); +} + +#else /* !CONFIG_KALLSYMS */ +static inline void add_sect_attrs(struct module *mod, const struct load_in= fo *info) { } +static inline void remove_sect_attrs(struct module *mod) { } +static inline void add_notes_attrs(struct module *mod, const struct load_i= nfo *info) { } +static inline void remove_notes_attrs(struct module *mod) { } +#endif /* CONFIG_KALLSYMS */ + +void del_usage_links(struct module *mod) +{ +#ifdef CONFIG_MODULE_UNLOAD + struct module_use *use; + + mutex_lock(&module_mutex); + list_for_each_entry(use, &mod->target_list, target_list) + sysfs_remove_link(use->target->holders_dir, mod->name); + mutex_unlock(&module_mutex); +#endif +} + +static int add_usage_links(struct module *mod) +{ + int ret =3D 0; +#ifdef CONFIG_MODULE_UNLOAD + struct module_use *use; + + mutex_lock(&module_mutex); + list_for_each_entry(use, &mod->target_list, target_list) { + ret =3D sysfs_create_link(use->target->holders_dir, + &mod->mkobj.kobj, mod->name); + if (ret) + break; + } + mutex_unlock(&module_mutex); + if (ret) + del_usage_links(mod); +#endif + return ret; +} + +extern struct module_attribute *modinfo_attrs[]; +extern size_t modinfo_attrs_count; + +static int module_add_modinfo_attrs(struct module *mod) +{ + struct module_attribute *attr; + struct module_attribute *temp_attr; + int error =3D 0; + int i; + + mod->modinfo_attrs =3D kzalloc((sizeof(struct module_attribute) * + (modinfo_attrs_count + 1)), + GFP_KERNEL); + if (!mod->modinfo_attrs) + return -ENOMEM; + + temp_attr =3D mod->modinfo_attrs; + for (i =3D 0; (attr =3D modinfo_attrs[i]); i++) { + if (!attr->test || attr->test(mod)) { + memcpy(temp_attr, attr, sizeof(*temp_attr)); + sysfs_attr_init(&temp_attr->attr); + error =3D sysfs_create_file(&mod->mkobj.kobj, + &temp_attr->attr); + if (error) + goto error_out; + ++temp_attr; + } + } + + return 0; + +error_out: + if (i > 0) + module_remove_modinfo_attrs(mod, --i); + else + kfree(mod->modinfo_attrs); + return error; +} + +void module_remove_modinfo_attrs(struct module *mod, int end) +{ + struct module_attribute *attr; + int i; + + for (i =3D 0; (attr =3D &mod->modinfo_attrs[i]); i++) { + if (end >=3D 0 && i > end) + break; + /* pick a field to test for end of list */ + if (!attr->attr.name) + break; + sysfs_remove_file(&mod->mkobj.kobj, &attr->attr); + if (attr->free) + attr->free(mod); + } + kfree(mod->modinfo_attrs); +} + +static void mod_kobject_put(struct module *mod) +{ + DECLARE_COMPLETION_ONSTACK(c); + mod->mkobj.kobj_completion =3D &c; + kobject_put(&mod->mkobj.kobj); + wait_for_completion(&c); +} + +static int mod_sysfs_init(struct module *mod) +{ + int err; + struct kobject *kobj; + + if (!module_sysfs_initialized) { + pr_err("%s: module sysfs not initialized\n", mod->name); + err =3D -EINVAL; + goto out; + } + + kobj =3D kset_find_obj(module_kset, mod->name); + if (kobj) { + pr_err("%s: module is already loaded\n", mod->name); + kobject_put(kobj); + err =3D -EINVAL; + goto out; + } + + mod->mkobj.mod =3D mod; + + memset(&mod->mkobj.kobj, 0, sizeof(mod->mkobj.kobj)); + mod->mkobj.kobj.kset =3D module_kset; + err =3D kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL, + "%s", mod->name); + if (err) + mod_kobject_put(mod); + +out: + return err; +} + +int mod_sysfs_setup(struct module *mod, + const struct load_info *info, + struct kernel_param *kparam, + unsigned int num_params) +{ + int err; + + err =3D mod_sysfs_init(mod); + if (err) + goto out; + + mod->holders_dir =3D kobject_create_and_add("holders", &mod->mkobj.kobj); + if (!mod->holders_dir) { + err =3D -ENOMEM; + goto out_unreg; + } + + err =3D module_param_sysfs_setup(mod, kparam, num_params); + if (err) + goto out_unreg_holders; + + err =3D module_add_modinfo_attrs(mod); + if (err) + goto out_unreg_param; + + err =3D add_usage_links(mod); + if (err) + goto out_unreg_modinfo_attrs; + + add_sect_attrs(mod, info); + add_notes_attrs(mod, info); + + return 0; + +out_unreg_modinfo_attrs: + module_remove_modinfo_attrs(mod, -1); +out_unreg_param: + module_param_sysfs_remove(mod); +out_unreg_holders: + kobject_put(mod->holders_dir); +out_unreg: + mod_kobject_put(mod); +out: + return err; +} + +void mod_sysfs_fini(struct module *mod) +{ + remove_notes_attrs(mod); + remove_sect_attrs(mod); + mod_kobject_put(mod); +} + +void init_param_lock(struct module *mod) +{ + mutex_init(&mod->param_lock); +} --=20 2.31.1 From nobody Wed Jul 1 06:47:50 2026 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 080EEC433F5 for ; Tue, 28 Dec 2021 21:31:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237617AbhL1VbL (ORCPT ); Tue, 28 Dec 2021 16:31:11 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:52289 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237513AbhL1Va7 (ORCPT ); Tue, 28 Dec 2021 16:30:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1640727057; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F1lOBRpMAGkWz55gR1tG3JnxjneKMph16mPglikuVp0=; b=YDqmAwU5z/9lgU27tGjWHNNNDJBuZcPzZlpy9w74y2l1gZXlAWjQFkS3eamxUCvcTMkiUk QHliu97bzrFGTtMgjo2NjfuXVySCv6hiOwjf68RcTLrP+uK64Nn0ZRaD0u2AyAGhStcQjd hq+Bl6qriR6vJDF1zPMPf4ljRv3gESw= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-217-RBsiBtFBOReSIZNgWW6q_Q-1; Tue, 28 Dec 2021 16:30:56 -0500 X-MC-Unique: RBsiBtFBOReSIZNgWW6q_Q-1 Received: by mail-wm1-f72.google.com with SMTP id b20-20020a05600c4e1400b003457da1c91eso6555664wmq.4 for ; Tue, 28 Dec 2021 13:30:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=F1lOBRpMAGkWz55gR1tG3JnxjneKMph16mPglikuVp0=; b=4oIIYfXpG6sgc4IWbv3X7F6HobNIXFeKUOBBrqhSefVGN2v4f5aBGb8UTum5LSA4/M T9iHmEVlKe+LHuKgYv29jUb1zcrPP7vJkVjrEiyQra/xhWZwwCdkshgeyAug9xj64QVs CkVFtdFu8xWwaPFAlzhp4OqFdj7TjK30qYgvic465HiE0+eCMdUgZ5jl52o+Mcz/L9X1 gnxf40uNY9I7i0ZTXVS3ShqmOyPC6hoKawbJe13jdoA7i5tiuJ7pNW2zz8tUymF3M7/l 3lDE6k6dSFswMTlFd3s2XLYnYCN1G3BmSXddPzrRMgtW+wquAneZW4lHVb9sYT7jt2ZQ yMqA== X-Gm-Message-State: AOAM5307JMQT3ZvEN5Qlf8VJlxbiyRhliOm4DgTHKRi9PwfjSRHgm6QA xj0FWV2u0/oS/6iVPUdVOXqZy9LMNNlXBHhsRelyuKyQom9xePfaiEWqQs02Ejyx5FAAM+eyc7V +lQ+Tv7ZPGCYNW1BEfn9ALT0= X-Received: by 2002:a5d:6702:: with SMTP id o2mr17958885wru.292.1640727054498; Tue, 28 Dec 2021 13:30:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJwWLuWvxuln1/E5kemLw46EPZ4rHzmIPkxuxDJpLp6+pGF82G0D/3i7IICNC7t5ofzUBwTU2A== X-Received: by 2002:a5d:6702:: with SMTP id o2mr17958880wru.292.1640727054375; Tue, 28 Dec 2021 13:30:54 -0800 (PST) Received: from localhost (cpc111743-lutn13-2-0-cust979.9-3.cable.virginm.net. [82.17.115.212]) by smtp.gmail.com with ESMTPSA id k9sm18612597wro.80.2021.12.28.13.30.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Dec 2021 13:30:54 -0800 (PST) From: Aaron Tomlin To: mcgrof@kernel.org Cc: cl@linux.com, pmladek@suse.com, mbenes@suse.cz, akpm@linux-foundation.org, jeyu@kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, atomlin@atomlin.com, ghalat@redhat.com Subject: [RFC PATCH 12/12] module: Move kdb_modules list out of core code Date: Tue, 28 Dec 2021 21:30:41 +0000 Message-Id: <20211228213041.1356334-13-atomlin@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211228213041.1356334-1-atomlin@redhat.com> References: <20211228213041.1356334-1-atomlin@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No functional change. This patch migrates kdb_modules list to core kdb code since the list of added/or loaded modules is no longer private. Signed-off-by: Aaron Tomlin --- kernel/debug/kdb/kdb_main.c | 5 +++++ kernel/module/main.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index d8ee5647b732..ef61fb65671a 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -60,6 +60,11 @@ EXPORT_SYMBOL(kdb_grepping_flag); int kdb_grep_leading; int kdb_grep_trailing; =20 +#ifdef CONFIG_MODULES +extern struct list_head modules; +struct list_head *kdb_modules =3D &modules; /* kdb needs the list of modul= es */ +#endif /* CONFIG_MODULES */ + /* * Kernel debugger state flags */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 354fb2697188..09012246907a 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -95,10 +95,6 @@ static void mod_update_bounds(struct module *mod) __mod_update_bounds(mod->init_layout.base, mod->init_layout.size); } =20 -#ifdef CONFIG_KGDB_KDB -struct list_head *kdb_modules =3D &modules; /* kdb needs the list of modul= es */ -#endif /* CONFIG_KGDB_KDB */ - static void module_assert_mutex_or_preempt(void) { #ifdef CONFIG_LOCKDEP --=20 2.31.1