linux-s390.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v2 00/13] sysctl: add module aliases
@ 2026-08-19  2:27 Mauricio Faria de Oliveira
  2026-08-19  2:28 ` [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>' Mauricio Faria de Oliveira
                   ` (12 more replies)
  0 siblings, 13 replies; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:27 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

This series adds 'sysctl:' aliases to modules that register sysctl tables; e.g.:

        $ modinfo ./mpls_router.ko  | grep sysctl:
        alias:          sysctl:*/net/mpls/conf/*/input
        alias:          sysctl:*/net/mpls/default_ttl
        alias:          sysctl:*/net/mpls/ip_ttl_propagate
        alias:          sysctl:*/net/mpls/platform_labels

It provides a trivial way to map /proc/sys files to modules (not trivial today),
and for userspace to handle nonexistent /proc/sys files (e.g., procps's sysctl
and systemd-sysctl applying tunables) with "modprobe sysctl:<...>" and a retry.

This is done almost automatically with register_sysctl(), register_net_sysctl()
and friends as wrappers of MODULE_SYSCTL_TABLE (similar to MODULE_DEVICE_TABLE),
which emits symbols for file2alias/modpost to find and parse the sysctl tables.

The big exception to 'almost' are sysctl tables and paths allocated or defined
at runtime (e.g., per-namespace or per-device), as all information is required
at build-time. Fortunately, such tables and paths are often based on 'templates'
which are static and can be used.

This is done by plumbing the template table/path as optional arguments (macros
with default values as default_gfp()), so not to create functions for all cases:

        register_sysctl(path, table [, table_tmpl [, path_tmpl]]);
        register_net_sysctl(net, path, table [, table_tmpl[, path_tmpl]]);
        register_net_sysctl_sz(net, path, table, size [, table_tmpl[, path_tmpl]]);

In this series:
- Patch 1 prevents a build error later.
- Patch 2 adds CONFIG_SYSCTL_MODULE_ALIASES.
- Patch 3 adds MODULE_SYSCTL_TABLE().
- Patches 4-5 add register_sysctl() wrapper and update some callers.
- Patches 6-10 add register_net_sysctl[_sz]() wrappers and update some callers.
- Patches 11-13 add file2alias support.

Not all maintainers/reviewers (specially for the many changes in net/) are
in To/Cc in respect of their time, as this RFC probably needs more general
and earlier feedback before settling on specific changes for their review.
All lists are included for visibility, though.

Example
=======

To put it all together, 'mpls_router.ko' (used above) from 'net/mpls/af_mpls.c':
        
- Tables:

        static const struct ctl_table mpls_table[] = {
                {
                        .procname       = "platform_labels",
                ...
                        .procname       = "ip_ttl_propagate",
                ...
                        .procname       = "default_ttl",
                },
        };
        
        static const struct ctl_table mpls_dev_table[] = {
                {
                        .procname       = "input",
                ...
                },
        };

- Registration:

        net->mpls.ctl = register_net_sysctl_sz(net, "net/mpls", table,
                                               table_size, mpls_table);

        #define path_template "net/mpls/conf/%s"
        ...
        mdev->sysctl = register_net_sysctl_sz(net, path, table, table_size,
                                              mpls_dev_table, path_template);

- Symbols:

        $ objdump -t net/mpls/mpls_router.ko \
          | grep '__mod_device_table__.*__sysctl__'
        0000000000000900 l     O .data  0000000000000018
                __mod_device_table__kmod_mpls_router__sysctl__mpls_table.177
        0000000000000940 l     O .data  0000000000000018
                __mod_device_table__kmod_mpls_router__sysctl__mpls_dev_table.174

- file2alias:

        $ grep '^MODULE_ALIAS("sysctl:' net/mpls/mpls_router.mod.c
        MODULE_ALIAS("sysctl:*/net/mpls/platform_labels");
        MODULE_ALIAS("sysctl:*/net/mpls/ip_ttl_propagate");
        MODULE_ALIAS("sysctl:*/net/mpls/default_ttl");
        MODULE_ALIAS("sysctl:*/net/mpls/conf/*/input");

- modinfo:

        $ modinfo ./mpls_router.ko  | grep sysctl:
        alias:          sysctl:*/net/mpls/conf/*/input
        alias:          sysctl:*/net/mpls/default_ttl
        alias:          sysctl:*/net/mpls/ip_ttl_propagate
        alias:          sysctl:*/net/mpls/platform_labels

Testing
=======

Configurations:
- allmodconfig with the option enabled (check for 'MODULE_ALIAS("sysctl:' lines)
- allmodconfig with the option disabled (check for code errors)
- allyesconfig with the option enabled (check for include errors)

Architectures (test different bitness, endianness, and ELF handling)
- x86_64, i386
- arm, arm64
- arc
- alpha
- loongarch
- m68k
- mips(64)(el)
- parisc(64)
- powerpc(64(le))
- riscv
- sparc64
- s390

The resulting '.mod.c' files of allmodconfig with the option enabled was checked
for consistency across all architectures, and that the new aliases lines are the
difference to allmodconfig with the option disabled.

Disabling
=========

- Per-call:

  Use 'register_sysctl_sz()' or '__register_net_sysctl_sz()' directly.

- Per-file:

  Use '#define SYSCTL_MODULE_ALIASES_DISABLE'.

- System-wide:

  Maybe something along these lines:

        # cat /etc/modprobe.d/no-sysctl.conf
        alias sysctl:* no-sysctl
        install no-sysctl /bin/false

        # modinfo -F name sysctl:/proc/net/mpls/default_ttl
        mpls_router

        # modprobe sysctl:/proc/net/mpls/default_ttl
        modprobe: ERROR: Error running install command '/bin/false' for module no_sysctl: retcode 1
        modprobe: ERROR: could not insert 'no_sysctl': Invalid argument

P.S.
====

I wrote proof-of-concept patches for procps sysctl and systemd-sysctl some time
ago, which worked as expected, i.e., successfully set sysctl tunables which did
not exist in /proc/sys, by running 'modprobe sysctl:/proc/sys/...' and retrying.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Changes in v2:
- This is based on the series submitted 4 years ago,
  with Originally-by: tags added in related patches.
- Link to v1: https://lore.kernel.org/linux-fsdevel/20220722022416.137548-1-mfo@canonical.com/

---
Mauricio Faria de Oliveira (13):
      keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>'
      proc: add config option SYSCTL_MODULE_ALIASES
      sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE
      sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE
      sysctl, parport: update register_sysctl() callers with template arguments
      sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
      sysctl, net: update register_net_sysctl{_sz}() callers with template arguments
      sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) with template arguments
      sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
      sysctl, net: update register_net_sysctl_sz() edge case
      sysctl: unrandomize struct ctl_table.procname
      modpost: move addend_*_rel() calls into addend_rel()
      modpost: handle MODULE_SYSCTL_TABLE symbols

 arch/riscv/kernel/vector.c              |   1 +
 drivers/net/vrf.c                       |   3 +-
 drivers/parport/procfs.c                |  26 +++-
 fs/proc/Kconfig                         |  13 ++
 fs/verity/init.c                        |   1 +
 include/linux/key.h                     |   1 -
 include/linux/mod_devicetable.h         |   7 +
 include/linux/pid_namespace.h           |   1 +
 include/linux/sysctl.h                  | 110 ++++++++++++++-
 include/net/ipv6.h                      |   6 +-
 include/net/net_namespace.h             |  45 ++++++-
 net/bridge/br_netfilter_hooks.c         |   3 +-
 net/core/neighbour.c                    |  11 +-
 net/core/sysctl_net_core.c              |   3 +-
 net/ieee802154/6lowpan/reassembly.c     |   2 +-
 net/ipv4/devinet.c                      |  12 +-
 net/ipv4/ip_fragment.c                  |   3 +-
 net/ipv4/route.c                        |   3 +-
 net/ipv4/sysctl_net_ipv4.c              |   2 +-
 net/ipv4/xfrm4_policy.c                 |   3 +-
 net/ipv6/addrconf.c                     |   7 +-
 net/ipv6/icmp.c                         |   6 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c |   4 +-
 net/ipv6/reassembly.c                   |   3 +-
 net/ipv6/route.c                        |  10 +-
 net/ipv6/sysctl_net_ipv6.c              |  13 +-
 net/ipv6/xfrm6_policy.c                 |   3 +-
 net/mpls/af_mpls.c                      |   9 +-
 net/mptcp/ctrl.c                        |   3 +-
 net/netfilter/ipvs/ip_vs_ctl.c          |   4 +-
 net/netfilter/ipvs/ip_vs_lblc.c         |   3 +-
 net/netfilter/ipvs/ip_vs_lblcr.c        |   3 +-
 net/netfilter/nf_conntrack_standalone.c |   5 +-
 net/netfilter/nf_log.c                  |   9 +-
 net/rds/tcp.c                           |   4 +-
 net/sctp/sysctl.c                       |   3 +-
 net/smc/smc_sysctl.c                    |   2 +-
 net/sysctl_net.c                        |  10 +-
 net/unix/sysctl_net_unix.c              |   3 +-
 net/vmw_vsock/af_vsock.c                |   4 +-
 net/xfrm/xfrm_sysctl.c                  |   2 +-
 scripts/mod/devicetable-offsets.c       |   6 +
 scripts/mod/file2alias.c                | 230 ++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c                   |  46 ++++---
 scripts/mod/modpost.h                   |  25 ++++
 45 files changed, 567 insertions(+), 106 deletions(-)
---
base-commit: 2697ef8943c9985c14708a6429e21812693857b2
change-id: 20260818-sysctl-module-aliases-2f5801b1eb71

Best regards,
-- 
Mauricio Faria de Oliveira <mfo@igalia.com>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>'
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:33   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES Mauricio Faria de Oliveira
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Fix an include loop error in preparation for sysctl.h to include module.h:

    CC [M]  arch/x86/events/amd/uncore.o
  In file included from .../include/linux/fs.h:44,         <<<
                   from .../include/linux/compat.h:17,
                   from .../arch/x86/include/asm/ia32.h:7,
                   from .../arch/x86/include/asm/elf.h:10,
                   from .../include/linux/elf.h:6,
                   from .../include/linux/module.h:20,     <<<
                   from .../include/linux/sysctl.h:245,    <<<
                   from .../include/linux/key.h:17,        <<<
                   from .../include/linux/cred.h:13,       <<<
                   from .../include/linux/sched/signal.h:10,
                   from .../include/linux/ptrace.h:7,
                   from .../include/uapi/asm-generic/bpf_perf_event.h:4,
                   from ./arch/x86/include/generated/uapi/asm/
                        bpf_perf_event.h:1,
                   from .../include/uapi/linux/bpf_perf_event.h:11,
                   from .../include/linux/perf_event.h:18,
                   from .../arch/x86/events/amd/uncore.c:8:
  .../include/linux/mnt_idmapping.h: In function ‘mapped_fsuid’:
  .../include/linux/mnt_idmapping.h:231:59: error: implicit declaration
    of function ‘current_fsuid’ [-Wimplicit-function-declaration]

Reason:
 - cred.h includes key.h *before* defining current_fsuid();
 - key.h includes sysctl.h;
 - sysctl.h includes module.h;
 - module.h includes fs.h via elf.h > asm/elf.h > asm/ia32.h > compat.h;
 - fs.h includes mnt_idmapping.h, which uses *undefined* current_fsuid().

Note that fs.h does include cred.h (which defines current_fsuid()) right
before mnt_idmapping.h (which uses it), but it is not parsed because the
include guard of cred.h is defined earlier.

Address this by removing sysctl.h from key.h, which does not need it,
and adding it to files that actually need it.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 arch/riscv/kernel/vector.c    | 1 +
 fs/verity/init.c              | 1 +
 include/linux/key.h           | 1 -
 include/linux/pid_namespace.h | 1 +
 4 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index b112166d51e9f584f84c52d0f84feb92ccd60df1..9eac47c99f114304521fdc539018f3f84507e75f 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/uaccess.h>
 #include <linux/prctl.h>
+#include <linux/sysctl.h>
 
 #include <asm/thread_info.h>
 #include <asm/processor.h>
diff --git a/fs/verity/init.c b/fs/verity/init.c
index 3aa55dec88fc919792a2cb4be476f8481ef78a9e..d460eef74fcfe49f6cf69974a8194a65de486819 100644
--- a/fs/verity/init.c
+++ b/fs/verity/init.c
@@ -9,6 +9,7 @@
 #include "fsverity_private.h"
 
 #include <linux/ratelimit.h>
+#include <linux/sysctl.h>
 
 #ifdef CONFIG_SYSCTL
 static const struct ctl_table fsverity_sysctl_table[] = {
diff --git a/include/linux/key.h b/include/linux/key.h
index 81b8f05c68985c6f0a5c5bbe0f1fd6661912c618..a74f8f1b7936d6ede584c0a8cd520f858f6a9758 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -14,7 +14,6 @@
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include <linux/rcupdate.h>
-#include <linux/sysctl.h>
 #include <linux/rwsem.h>
 #include <linux/atomic.h>
 #include <linux/assoc_array.h>
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b20baaa7e62b755e7e561fcd8018e2b61213503e..94b23471c7dec135e24c4c0c1fdbf841cea2e5de 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -10,6 +10,7 @@
 #include <linux/nsproxy.h>
 #include <linux/ns_common.h>
 #include <linux/idr.h>
+#include <linux/sysctl.h>
 
 /* MAX_PID_NS_LEVEL is needed for limiting size of 'struct pid' */
 #define MAX_PID_NS_LEVEL 32

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
  2026-08-19  2:28 ` [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>' Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:37   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Add a config option for the 'sysctl:' module aliases feature.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 fs/proc/Kconfig | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 24f5a36f45df8b1d6831a0f4011c1f6b1987cb52..e6591ec4bcf0ab2ad96ca7dc90b831b2f9873ac2 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -98,6 +98,19 @@ config SYSCTL
 	  building a kernel for install/rescue disks or your system is very
 	  limited in memory.
 
+config SYSCTL_MODULE_ALIASES
+	bool "'sysctl:' module aliases (EXPERIMENTAL)"
+	depends on SYSCTL && MODULES
+	default n
+	help
+	  The /proc/sys files registered by a module do not exist until the
+	  module is loaded; meanwhile, userspace cannot find or access them.
+
+	  This options adds 'sysctl:*/<path>/<file>' module aliases for the
+	  /proc/sys files registered by modules, so modules for nonexistent
+	  files can be loaded with 'modprobe sysctl:/proc/sys/<path>/<file>'
+	  by userspace when needed.
+
 config PROC_PAGE_MONITOR
  	default y
 	depends on PROC_FS && MMU

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
  2026-08-19  2:28 ` [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>' Mauricio Faria de Oliveira
  2026-08-19  2:28 ` [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:40   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

The MODULE_SYSCTL_TABLE macro emits a struct module_sysctl_table variable
with pointers to a sysctl table's path and entries, and table/entry sizes.

That symbol will be handled by file2alias.c (modpost) with the changes in
mod_devicetable.h and devicetable-offsets.c.

The option macros MODULE_SYSCTL_TABLE_{DISABLE,UNIQUE_ID} can be used on
a per-file basis to disable the macro and change the symbol name pattern.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 include/linux/mod_devicetable.h   |  7 +++++++
 include/linux/sysctl.h            | 42 +++++++++++++++++++++++++++++++++++++++
 scripts/mod/devicetable-offsets.c |  6 ++++++
 3 files changed, 55 insertions(+)

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index a397213bedace6e81ac600691b3b50ae0f88356b..818a4a53448dba2088e3dbd1ef2c2d4dbb190fcc 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -78,4 +78,11 @@ struct cpu_feature {
 	__u16	feature;
 };
 
+struct module_sysctl_table {
+	kernel_ulong_t path;
+	kernel_ulong_t table;
+	__u16 table_size;
+	__u16 entry_size;
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e5d7226ab6f5af34a33829883ad5d1b405e19c86..6960fe22c50bfd8a9acc79870e494c2775fa040a 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -293,6 +293,48 @@ struct ctl_table_root {
 	int (*permissions)(struct ctl_table_header *head, const struct ctl_table *table);
 };
 
+/*
+ * Creates a symbol so file2alias.c can find the sysctl table.
+ *
+ * MODULE_SYSCTL_TABLE() is the sysctl equivalent of MODULE_DEVICE_TABLE(),
+ * with pointers to a sysctl table's path and entries, and table/entry sizes.
+ *
+ * The parameters 'path' and 'table' must be static (e.g., string literal or
+ * static char[]; static struct ctl_table[]) as both are used as initializer
+ * elements for a static struct variable.
+ *
+ * The generated symbol name contains 'table' by default. However, if 'table'
+ * is a struct field (contains '.' or '->'), in order to avoid syntax errors,
+ * define the macro SYSCTL_MODULE_ALIASES_UNIQUE_ID.
+ *
+ * Define the macro SYSCTL_MODULE_ALIASES_DISABLE to disable this.
+ */
+#if defined(CONFIG_SYSCTL_MODULE_ALIASES) && defined(MODULE) &&			\
+    !defined(SYSCTL_MODULE_ALIASES_DISABLE)
+
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+
+#if defined(SYSCTL_MODULE_ALIASES_UNIQUE_ID)
+#define __MODULE_SYSCTL_TABLE_NAME(table)					\
+	__mod_device_table(sysctl, __UNIQUE_ID)
+#else
+#define __MODULE_SYSCTL_TABLE_NAME(table)					\
+	__mod_device_table(sysctl, table)
+#endif
+
+#define MODULE_SYSCTL_TABLE(path, table)					\
+	static struct module_sysctl_table __used				\
+		__MODULE_SYSCTL_TABLE_NAME(table) = {				\
+			(kernel_ulong_t) path,					\
+			(kernel_ulong_t) table,					\
+			(u16) sizeof(table),					\
+			(u16) sizeof(const struct ctl_table)			\
+		}
+#else
+#define MODULE_SYSCTL_TABLE(path, table)
+#endif
+
 #define register_sysctl(path, table)	\
 	register_sysctl_sz(path, table, ARRAY_SIZE(table))
 
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
index b4178c42d08f50dfaba4d50d5c1d48b8aff88db4..e3b8855e6ebcf8d16f486f71d62900584ee884b1 100644
--- a/scripts/mod/devicetable-offsets.c
+++ b/scripts/mod/devicetable-offsets.c
@@ -284,5 +284,11 @@ int main(void)
 	DEVID(coreboot_device_id);
 	DEVID_FIELD(coreboot_device_id, tag);
 
+	DEVID(module_sysctl_table);
+	DEVID_FIELD(module_sysctl_table, path);
+	DEVID_FIELD(module_sysctl_table, table);
+	DEVID_FIELD(module_sysctl_table, table_size);
+	DEVID_FIELD(module_sysctl_table, entry_size);
+
 	return 0;
 }

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (2 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:44   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments Mauricio Faria de Oliveira
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Add a MODULE_SYSCTL_TABLE call into register_sysctl() for existing callers
to automatically use it.

Add optional 'template arguments' to support a dynamic table/path defined
at run-time based on a 'template' table/path available at build-time.

Split the update of callers with template arguments into another commit for
clarity, disabling them for now.

Note: there is no register_sysctl_sz() wrapper, as it is used in even more
dynamic cases (e.g., table generated at run-time not based on a template).

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 drivers/parport/procfs.c |  2 ++
 include/linux/sysctl.h   | 54 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index 3880460e67f25a7d8708a734c6f4d9e6c363c726..cda3221e386ed7a4afc898b3d0313081dee5b49b 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -13,6 +13,8 @@
  * Cleaned up include files - Russell King <linux@arm.uk.linux.org>
  */
 
+#define SYSCTL_MODULE_ALIASES_DISABLE
+
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/module.h>
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 6960fe22c50bfd8a9acc79870e494c2775fa040a..7e05fafd5544e1c4a3283dc13b0692f39515d01e 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -335,8 +335,58 @@ struct ctl_table_root {
 #define MODULE_SYSCTL_TABLE(path, table)
 #endif
 
-#define register_sysctl(path, table)	\
-	register_sysctl_sz(path, table, ARRAY_SIZE(table))
+/*
+ * The register_sysctl() wrapper for the MODULE_SYSCTL_TABLE macro
+ * automatically creates symbols in sysctl table registration sites.
+ *
+ * Usage:
+ * - register_sysctl(path, table);
+ * - register_sysctl(path, table, table_tmpl);
+ * - register_sysctl(path, table, table_tmpl, path_tmpl);
+ *
+ * The optional 'template arguments' ('table_tmpl' and 'path_tmpl')
+ * can support callers with non-static variables: dynamic table/path
+ * defined at run-time based on a 'template' available at build-time.
+ *
+ * For example, a sysctl table, or table and path, which is/are:
+ *
+ * - per-namespace: different tables based on a template table
+ *   (i.e., same files in each namespace) with identical path
+ *   (i.e., same path in each namespace).
+ *
+ * - per-device: different tables based on a template table
+ *   (i.e., same files for each device) with different paths
+ *   (i.e., diff paths for each device) based on a template path.
+ *
+ * The wrapper passes the build-time parameters (templates) to the macro
+ * and the dynamic/run-time parameters (instances) to the wrapped function.
+ *
+ * The wrapper reduces to the wrapped function when either the macro or the
+ * config option is disabled.
+ */
+#define _register_sysctl(path, table, table_tmpl, path_tmpl)			\
+({										\
+	MODULE_SYSCTL_TABLE(path_tmpl, table_tmpl);				\
+	register_sysctl_sz(path, table, ARRAY_SIZE(table));			\
+})
+
+#define register_sysctl(path, table, tmpl_args...)				\
+	_register_sysctl(path, table,						\
+			 __sysctl_table_tmpl_or_default(table, ## tmpl_args),	\
+			 __sysctl_path_tmpl_or_default(path, ## tmpl_args))	\
+
+/* Helper macros for optional template arguments */
+#define __sysctl_table_tmpl(skip, table_tmpl, ...)				\
+	table_tmpl
+
+#define __sysctl_path_tmpl(skip, table_tmpl, path_tmpl, ...)			\
+	path_tmpl
+
+#define __sysctl_table_tmpl_or_default(default, tmpl_args...)			\
+	__sysctl_table_tmpl(, ## tmpl_args, default)
+
+#define __sysctl_path_tmpl_or_default(default, tmpl_args...)			\
+	__sysctl_path_tmpl(, ## tmpl_args, default, default)
 
 #ifdef CONFIG_SYSCTL
 

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (3 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:44   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Update callers with dynamic table/path to use template arguments.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 drivers/parport/procfs.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
index cda3221e386ed7a4afc898b3d0313081dee5b49b..7c048e9a973aa96251930e21581aed045c41cc35 100644
--- a/drivers/parport/procfs.c
+++ b/drivers/parport/procfs.c
@@ -13,7 +13,7 @@
  * Cleaned up include files - Russell King <linux@arm.uk.linux.org>
  */
 
-#define SYSCTL_MODULE_ALIASES_DISABLE
+#define SYSCTL_MODULE_ALIASES_UNIQUE_ID
 
 #include <linux/string.h>
 #include <linux/init.h>
@@ -434,13 +434,17 @@ int parport_proc_register(struct parport *port)
 #endif /* IEEE 1284 support */
 	}
 
-	tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s/devices", port->name);
+#define tmp_dir_tmpl "dev/parport/%s/devices"
+	tmp_dir_path = kasprintf(GFP_KERNEL, tmp_dir_tmpl, port->name);
 	if (!tmp_dir_path) {
 		err = -ENOMEM;
 		goto exit_free_t;
 	}
 
-	t->devices_header = register_sysctl(tmp_dir_path, t->device_dir);
+	t->devices_header = register_sysctl(tmp_dir_path, t->device_dir,
+					    parport_sysctl_template.device_dir,
+					    tmp_dir_tmpl);
+#undef tmp_dir_tmpl
 	if (t->devices_header == NULL) {
 		err = -ENOENT;
 		goto  exit_free_tmp_dir_path;
@@ -448,13 +452,17 @@ int parport_proc_register(struct parport *port)
 
 	kfree(tmp_dir_path);
 
-	tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s", port->name);
+#define tmp_dir_tmpl "dev/parport/%s"
+	tmp_dir_path = kasprintf(GFP_KERNEL, tmp_dir_tmpl,  port->name);
 	if (!tmp_dir_path) {
 		err = -ENOMEM;
 		goto unregister_devices_h;
 	}
 
-	t->port_header = register_sysctl(tmp_dir_path, t->vars);
+	t->port_header = register_sysctl(tmp_dir_path, t->vars,
+					 parport_sysctl_template.vars,
+					 tmp_dir_tmpl);
+#undef tmp_dir_tmpl
 	if (t->port_header == NULL) {
 		err = -ENOENT;
 		goto unregister_devices_h;
@@ -500,7 +508,8 @@ int parport_device_proc_register(struct pardevice *device)
 		return -ENOMEM;
 
 	/* Allocate a buffer for two paths: dev/parport/PORT/devices/DEVICE. */
-	tmp_dir_path = kasprintf(GFP_KERNEL, "dev/parport/%s/devices/%s", port->name, device->name);
+#define tmp_dir_tmpl "dev/parport/%s/devices/%s"
+	tmp_dir_path = kasprintf(GFP_KERNEL, tmp_dir_tmpl, port->name, device->name);
 	if (!tmp_dir_path) {
 		err = -ENOMEM;
 		goto exit_free_t;
@@ -508,7 +517,10 @@ int parport_device_proc_register(struct pardevice *device)
 
 	t->vars[0].data = &device->timeslice;
 
-	t->sysctl_header = register_sysctl(tmp_dir_path, t->vars);
+	t->sysctl_header = register_sysctl(tmp_dir_path, t->vars,
+					   parport_device_sysctl_template.vars,
+					   tmp_dir_tmpl);
+#undef tmp_dir_tmpl
 	if (t->sysctl_header == NULL) {
 		kfree(t);
 		t = NULL;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (4 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:40   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments Mauricio Faria de Oliveira
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Add a MODULE_SYSCTL_TABLE call into register_net_sysctl{_sz}() for existing
callers to automatically use it.

Add optional 'template arguments' to support a dynamic table/path defined
at run-time based on a 'template' available at build-time.

Split the update of callers with template arguments into separate commits,
disabling the macro for now.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 include/linux/sysctl.h      |  3 +++
 include/net/net_namespace.h | 45 ++++++++++++++++++++++++++++++++++++++++-----
 net/sysctl_net.c            | 10 +++++-----
 3 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 7e05fafd5544e1c4a3283dc13b0692f39515d01e..9e00a086ff1d47ab18021b3d79b0e8a93037cb2d 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -309,6 +309,9 @@ struct ctl_table_root {
  *
  * Define the macro SYSCTL_MODULE_ALIASES_DISABLE to disable this.
  */
+
+#define SYSCTL_MODULE_ALIASES_DISABLE
+
 #if defined(CONFIG_SYSCTL_MODULE_ALIASES) && defined(MODULE) &&			\
     !defined(SYSCTL_MODULE_ALIASES_DISABLE)
 
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index e5ee673b9fcf846aefcc309d4cca1a8fc870aae2..2127049c71cedade45922d7f0d3b7a3ce0af67e0 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -520,13 +520,48 @@ void unregister_pernet_device(struct pernet_operations *);
 
 struct ctl_table;
 
-#define register_net_sysctl(net, path, table)	\
-	register_net_sysctl_sz(net, path, table, ARRAY_SIZE(table))
+/*
+ * The register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
+ * automatically create symbols in sysctl registration sites.
+ *
+ * See register_sysctl() and MODULE_SYSCTL_TABLE() in <linux/sysctl.h>
+ * for information about template arguments and options for the macro.
+ *
+ * Usage:
+ * - register_net_sysctl(net, path, table);
+ * - register_net_sysctl(net, path, table, table_tmpl);
+ * - register_net_sysctl(net, path, table, table_tmpl, path_tmpl);
+ * - register_net_sysctl_sz(net, path, table, size);
+ * - register_net_sysctl_sz(net, path, table, size, table_tmpl);
+ * - register_net_sysctl_sz(net, path, table, size, table_tmpl, path_tmpl);
+ */
+#define _register_net_sysctl_sz(net, path, table, size, table_tmpl, path_tmpl)	\
+({										\
+	MODULE_SYSCTL_TABLE(path_tmpl, table_tmpl);				\
+	__register_net_sysctl_sz(net, path, table, size);			\
+})
+
+#define register_net_sysctl_sz(net, path, table, size, tmpl_args...)		\
+	_register_net_sysctl_sz(net, path, table, size,				\
+				__sysctl_table_tmpl_or_default(table,		\
+							       ## tmpl_args),	\
+				__sysctl_path_tmpl_or_default(path,		\
+							      ## tmpl_args))
+#define register_net_sysctl(net, path, table, tmpl_args...)			\
+	register_net_sysctl_sz(net, path, table,				\
+			       __sysctl_table_array_size(table, ## tmpl_args),	\
+			       ## tmpl_args)
+
+/* Helper macro for optional template arguments */
+#define __sysctl_table_array_size(table, tmpl_args...)	\
+	ARRAY_SIZE(__sysctl_table_tmpl_or_default(table, ## tmpl_args))
+
 #ifdef CONFIG_SYSCTL
 int net_sysctl_init(void);
-struct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path,
-						const struct ctl_table *table,
-						size_t table_size);
+struct ctl_table_header *__register_net_sysctl_sz(struct net *net,
+						  const char *path,
+						  const struct ctl_table *table,
+						  size_t table_size);
 void unregister_net_sysctl_table(struct ctl_table_header *header);
 #else
 static inline int net_sysctl_init(void) { return 0; }
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index e190a639eef2f6929c4aed85ad625aaf8a6ebd6a..e003210e0917760b707dae1e738c50d7c3969deb 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -160,10 +160,10 @@ static int ensure_safe_net_sysctl(struct net *net, const char *path,
 	return 0;
 }
 
-struct ctl_table_header *register_net_sysctl_sz(struct net *net,
-						const char *path,
-						const struct ctl_table *table,
-						size_t table_size)
+struct ctl_table_header *__register_net_sysctl_sz(struct net *net,
+						  const char *path,
+						  const struct ctl_table *table,
+						  size_t table_size)
 {
 	if (!net_eq(net, &init_net))
 		if (ensure_safe_net_sysctl(net, path, table, table_size))
@@ -171,7 +171,7 @@ struct ctl_table_header *register_net_sysctl_sz(struct net *net,
 
 	return __register_sysctl_table(&net->sysctls, path, table, table_size);
 }
-EXPORT_SYMBOL_GPL(register_net_sysctl_sz);
+EXPORT_SYMBOL_GPL(__register_net_sysctl_sz);
 
 void unregister_net_sysctl_table(struct ctl_table_header *header)
 {

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (5 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:48   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) " Mauricio Faria de Oliveira
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Update most callers with dynamic table/path to use template arguments.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 net/core/neighbour.c                | 11 ++++++++---
 net/core/sysctl_net_core.c          |  3 ++-
 net/ieee802154/6lowpan/reassembly.c |  2 +-
 net/ipv4/devinet.c                  |  9 +++++++--
 net/ipv4/route.c                    |  3 ++-
 net/ipv4/sysctl_net_ipv4.c          |  2 +-
 net/ipv6/addrconf.c                 |  7 +++++--
 net/ipv6/sysctl_net_ipv6.c          |  3 ++-
 net/mpls/af_mpls.c                  |  9 ++++++---
 net/netfilter/ipvs/ip_vs_lblc.c     |  3 ++-
 net/netfilter/ipvs/ip_vs_lblcr.c    |  3 ++-
 net/sctp/sysctl.c                   |  3 ++-
 net/smc/smc_sysctl.c                |  2 +-
 net/xfrm/xfrm_sysctl.c              |  2 +-
 14 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1349c0eedb642539b28391390fd82f543e004353..bdd67dd879d24f41c95c454ca26d63fd6d8e112b 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -12,6 +12,7 @@
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#define SYSCTL_MODULE_ALIASES_UNIQUE_ID
 
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -3910,11 +3911,15 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
 	      BUG();
 	}
 
-	snprintf(neigh_path, sizeof(neigh_path), "net/%s/neigh/%s",
-		p_name, dev_name_source);
+#define path_template "net/%s/neigh/%s"
+	snprintf(neigh_path, sizeof(neigh_path), path_template,
+		 p_name, dev_name_source);
 	t->sysctl_header = register_net_sysctl_sz(neigh_parms_net(p),
 						  neigh_path, t->neigh_vars,
-						  neigh_vars_size);
+						  neigh_vars_size,
+						  neigh_sysctl_template.neigh_vars,
+						  path_template);
+#undef path_template
 	if (!t->sysctl_header)
 		goto free;
 
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index eb35da3556f4aa00cecd4582ab94e339d2518506..d8dfce6babc337749cde653fb1308f977ba28ef5 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -821,7 +821,8 @@ static __net_init int sysctl_core_net_init(struct net *net)
 			goto err_dup;
 	}
 
-	net->core.sysctl_hdr = register_net_sysctl_sz(net, "net/core", tbl, table_size);
+	net->core.sysctl_hdr = register_net_sysctl_sz(net, "net/core", tbl, table_size,
+						      netns_core_table);
 	if (net->core.sysctl_hdr == NULL)
 		goto err_reg;
 
diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c
index ddb6a5817d098eda6b22d802b5f59604b2145ff2..28914524bd0c389877533ed689eaf5af58c46bdd 100644
--- a/net/ieee802154/6lowpan/reassembly.c
+++ b/net/ieee802154/6lowpan/reassembly.c
@@ -386,7 +386,7 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
 	table[2].data	= &ieee802154_lowpan->fqdir->timeout;
 
 	hdr = register_net_sysctl_sz(net, "net/ieee802154/6lowpan", table,
-				     table_size);
+				     table_size, lowpan_frags_ns_ctl_table);
 	if (hdr == NULL)
 		goto err_reg;
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a90be57c63be1565b2dff51e8264668fd71b9e58..a466163dad7fe7f8b5b1c2897dd5fe548c288442 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -21,6 +21,7 @@
  *					if no match found.
  */
 
+#define SYSCTL_MODULE_ALIASES_UNIQUE_ID
 
 #include <linux/uaccess.h>
 #include <linux/bitops.h>
@@ -2739,9 +2740,13 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name,
 		t->devinet_vars[i].extra2 = net;
 	}
 
-	snprintf(path, sizeof(path), "net/ipv4/conf/%s", dev_name);
+#define path_template "net/ipv4/conf/%s"
+	snprintf(path, sizeof(path), path_template, dev_name);
 
-	t->sysctl_header = register_net_sysctl(net, path, t->devinet_vars);
+	t->sysctl_header = register_net_sysctl(net, path, t->devinet_vars,
+					       devinet_sysctl.devinet_vars,
+					       path_template);
+#undef path_template
 	if (!t->sysctl_header)
 		goto free;
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 604cc51dfd9bc5e7351a93140a9e0699a71e6a4e..d5464c7ef7dacdd47c5cb59ca14f605004c43b49 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -3661,7 +3661,8 @@ static __net_init int sysctl_route_net_init(struct net *net)
 	tbl[0].extra1 = net;
 
 	net->ipv4.route_hdr = register_net_sysctl_sz(net, "net/ipv4/route",
-						     tbl, table_size);
+						     tbl, table_size,
+						     ipv4_route_netns_table);
 	if (!net->ipv4.route_hdr)
 		goto err_reg;
 	return 0;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 2f0363bca2a88d68276670cfce6fb04398f82bc5..879651f4a57bc1206494a9eb1dd6a3fb752169c9 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1696,7 +1696,7 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
 	}
 
 	net->ipv4.ipv4_hdr = register_net_sysctl_sz(net, "net/ipv4", table,
-						    table_size);
+						    table_size, ipv4_net_table);
 	if (!net->ipv4.ipv4_hdr)
 		goto err_reg;
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9d89be7e0544befb979526fa4f0c4f0ab90582f0..e87c5d2e6e2f49ef4041faa4d8df85f69cabad36 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -7347,10 +7347,13 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
 		}
 	}
 
-	snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
+#define path_template "net/ipv6/conf/%s"
+	snprintf(path, sizeof(path), path_template, dev_name);
 
 	p->sysctl_header = register_net_sysctl_sz(net, path, table,
-						  table_size);
+						  table_size, addrconf_sysctl,
+						  path_template);
+#undef path_template
 	if (!p->sysctl_header)
 		goto free;
 
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 1a0a36dcdabc1be961d0ab69e5c93b05c53f46a8..75ba17cb7c0ccb4769d61e74220c75d0b3e2bcd9 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -275,7 +275,8 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
 		goto out_ipv6_route_table;
 
 	net->ipv6.sysctl.hdr = register_net_sysctl_sz(net, "net/ipv6",
-						      ipv6_table, table_size);
+						      ipv6_table, table_size,
+						      ipv6_table_template);
 	if (!net->ipv6.sysctl.hdr)
 		goto out_ipv6_icmp_table;
 
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 961be5054a039b3d8bcfd22851beb69c21954bc3..f2025bedc543b5b50eb3c7275e26e6adcdf27ae5 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1446,9 +1446,12 @@ static int mpls_dev_sysctl_register(struct net_device *dev,
 		table[i].extra2 = net;
 	}
 
-	snprintf(path, sizeof(path), "net/mpls/conf/%s", dev->name);
+#define path_template "net/mpls/conf/%s"
+	snprintf(path, sizeof(path), path_template, dev->name);
 
-	mdev->sysctl = register_net_sysctl_sz(net, path, table, table_size);
+	mdev->sysctl = register_net_sysctl_sz(net, path, table, table_size,
+					      mpls_dev_table, path_template);
+#undef path_template
 	if (!mdev->sysctl)
 		goto free;
 
@@ -2765,7 +2768,7 @@ static __net_init int mpls_net_init(struct net *net)
 		table[i].data = (char *)net + (uintptr_t)table[i].data;
 
 	net->mpls.ctl = register_net_sysctl_sz(net, "net/mpls", table,
-					       table_size);
+					       table_size, mpls_table);
 	if (net->mpls.ctl == NULL) {
 		kfree(table);
 		return -ENOMEM;
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 693bcc82ccb77b49bfa28a7facac946f0223aba2..efad701b096341dfe44e621ed647e21fd3bfa486 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -572,7 +572,8 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
 
 	ipvs->lblc_ctl_header = register_net_sysctl_sz(net, "net/ipv4/vs",
 						       ipvs->lblc_ctl_table,
-						       vars_table_size);
+						       vars_table_size,
+						       vs_vars_table);
 	if (!ipvs->lblc_ctl_header) {
 		if (!net_eq(net, &init_net))
 			kfree(ipvs->lblc_ctl_table);
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index f53f05ceea36f02d6d1d435882484005829fe6de..3498e6db6f0d7e9af29a95f1f8ccecd7c8d45cfd 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -757,7 +757,8 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
 
 	ipvs->lblcr_ctl_header = register_net_sysctl_sz(net, "net/ipv4/vs",
 							ipvs->lblcr_ctl_table,
-							vars_table_size);
+							vars_table_size,
+							vs_vars_table);
 	if (!ipvs->lblcr_ctl_header) {
 		if (!net_eq(net, &init_net))
 			kfree(ipvs->lblcr_ctl_table);
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 2b94c211427de7b2e9aa374033eac26ddd874e14..891fb447ea480ec95fb66a02bf8e086b3efa58c7 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -605,7 +605,8 @@ int sctp_sysctl_net_register(struct net *net)
 	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
 
 	net->sctp.sysctl_header = register_net_sysctl_sz(net, "net/sctp",
-							 table, table_size);
+							 table, table_size,
+							 sctp_net_table);
 	if (net->sctp.sysctl_header == NULL) {
 		kfree(table);
 		return -ENOMEM;
diff --git a/net/smc/smc_sysctl.c b/net/smc/smc_sysctl.c
index 09dad48337f6164f5765fa793412bdebf47e61ca..4b1dc109afa6c62b4640513336d0862bdcd00f8c 100644
--- a/net/smc/smc_sysctl.c
+++ b/net/smc/smc_sysctl.c
@@ -235,7 +235,7 @@ int __net_init smc_sysctl_net_init(struct net *net)
 	}
 
 	net->smc.smc_hdr = register_net_sysctl_sz(net, "net/smc", table,
-						  table_size);
+						  table_size, smc_table);
 	if (!net->smc.smc_hdr)
 		goto err_reg;
 
diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c
index 357152a50faf10e5c33468c034dd1777e0bed079..34bb2097930b61f711a2cafd614e63b5caac0013 100644
--- a/net/xfrm/xfrm_sysctl.c
+++ b/net/xfrm/xfrm_sysctl.c
@@ -60,7 +60,7 @@ int __net_init xfrm_sysctl_init(struct net *net)
 		table_size = 0;
 
 	net->xfrm.sysctl_hdr = register_net_sysctl_sz(net, "net/core", table,
-						      table_size);
+						      table_size, xfrm_table);
 	if (!net->xfrm.sysctl_hdr)
 		goto out_register;
 	return 0;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) with template arguments
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (6 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:36   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers " Mauricio Faria de Oliveira
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Reduce register_net_sysctl_sz(net, path, table, ARRAY_SIZE(table_tmpl)) to
register_net_sysctl(net, path, table, table_tmpl) which does it internally.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 drivers/net/vrf.c                       | 3 +--
 net/bridge/br_netfilter_hooks.c         | 3 +--
 net/ipv4/devinet.c                      | 3 +--
 net/ipv4/ip_fragment.c                  | 3 +--
 net/ipv4/xfrm4_policy.c                 | 3 +--
 net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++--
 net/ipv6/reassembly.c                   | 3 +--
 net/ipv6/xfrm6_policy.c                 | 3 +--
 net/mptcp/ctrl.c                        | 3 +--
 net/netfilter/ipvs/ip_vs_ctl.c          | 4 +---
 net/netfilter/nf_conntrack_standalone.c | 5 ++---
 net/rds/tcp.c                           | 4 ++--
 net/unix/sysctl_net_unix.c              | 3 +--
 net/vmw_vsock/af_vsock.c                | 4 ++--
 14 files changed, 18 insertions(+), 30 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index a0557a3a70260a404b2c2c6262e8466aec5be391..19dacbe69d6de81e2cf5cd2b6e750a25f9cef092 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1875,8 +1875,7 @@ static int vrf_netns_init_sysctl(struct net *net, struct netns_vrf *nn_vrf)
 	/* init the extra1 parameter with the reference to current netns */
 	table[0].extra1 = net;
 
-	nn_vrf->ctl_hdr = register_net_sysctl_sz(net, "net/vrf", table,
-						 ARRAY_SIZE(vrf_table));
+	nn_vrf->ctl_hdr = register_net_sysctl(net, "net/vrf", table, vrf_table);
 	if (!nn_vrf->ctl_hdr) {
 		kfree(table);
 		return -ENOMEM;
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index 0a394e5f439168fc32f3beb08721bee063ca5f17..ce5deb724608cf01103581f7f3e57210ffb85657 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -1251,8 +1251,7 @@ static int br_netfilter_sysctl_init_net(struct net *net)
 
 	br_netfilter_sysctl_default(brnet);
 
-	brnet->ctl_hdr = register_net_sysctl_sz(net, "net/bridge", table,
-						ARRAY_SIZE(brnf_table));
+	brnet->ctl_hdr = register_net_sysctl(net, "net/bridge", table, brnf_table);
 	if (!brnet->ctl_hdr) {
 		if (!net_eq(net, &init_net))
 			kfree(table);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a466163dad7fe7f8b5b1c2897dd5fe548c288442..fad5483287c29f75a0c09aa833af389e51f36cfb 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2884,8 +2884,7 @@ static __net_init int devinet_init_net(struct net *net)
 		goto err_reg_dflt;
 
 	err = -ENOMEM;
-	forw_hdr = register_net_sysctl_sz(net, "net/ipv4", tbl,
-					  ARRAY_SIZE(ctl_forward_entry));
+	forw_hdr = register_net_sysctl(net, "net/ipv4", tbl, ctl_forward_entry);
 	if (!forw_hdr)
 		goto err_reg_ctl;
 	net->ipv4.forw_hdr = forw_hdr;
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index c790d2f494870e1debd7e73b2d67df017a29f8a8..122aae5b4a384c12db5786bc34314107b4794b63 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -604,8 +604,7 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net)
 	table[2].data	= &net->ipv4.fqdir->timeout;
 	table[3].data	= &net->ipv4.fqdir->max_dist;
 
-	hdr = register_net_sysctl_sz(net, "net/ipv4", table,
-				     ARRAY_SIZE(ip4_frags_ns_ctl_table));
+	hdr = register_net_sysctl(net, "net/ipv4", table, ip4_frags_ns_ctl_table);
 	if (!hdr)
 		goto err_reg;
 
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index ab7a01029d490416d36482f7a3189f83d6670f42..cdd69d31a2757b0a23d65fb4b7d6d7de97c08706 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -177,8 +177,7 @@ static __net_init int xfrm4_net_sysctl_init(struct net *net)
 			goto err_alloc;
 	}
 
-	hdr = register_net_sysctl_sz(net, "net/ipv4", table,
-				     ARRAY_SIZE(xfrm4_policy_table));
+	hdr = register_net_sysctl(net, "net/ipv4", table, xfrm4_policy_table);
 	if (!hdr)
 		goto err_reg;
 
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 599c49bf0a0afd5054e926a5f2b1f0677bcd8b4d..09c98f2b9c3a04f622b232987dbc6a72f41238b4 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -86,8 +86,8 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
 	table[2].data	= &nf_frag->fqdir->high_thresh;
 	table[2].extra1	= &nf_frag->fqdir->low_thresh;
 
-	hdr = register_net_sysctl_sz(net, "net/netfilter", table,
-				     ARRAY_SIZE(nf_ct_frag6_sysctl_table));
+	hdr = register_net_sysctl(net, "net/netfilter", table,
+				  nf_ct_frag6_sysctl_table);
 	if (hdr == NULL)
 		goto err_reg;
 
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 05c51f669754a1a10e944bb7c4433565bcaacb40..372c85b253fa1c2fe1f54765e2dea02f8ba047f9 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -471,8 +471,7 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net)
 	table[1].extra2	= &net->ipv6.fqdir->high_thresh;
 	table[2].data	= &net->ipv6.fqdir->timeout;
 
-	hdr = register_net_sysctl_sz(net, "net/ipv6", table,
-				     ARRAY_SIZE(ip6_frags_ns_ctl_table));
+	hdr = register_net_sysctl(net, "net/ipv6", table, ip6_frags_ns_ctl_table);
 	if (!hdr)
 		goto err_reg;
 
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 5ec063cb4aa4378e70fff002dd03abf2029b247f..1c5a0ba14a7d03542d0691ea4c0f6a60443c20f6 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -223,8 +223,7 @@ static int __net_init xfrm6_net_sysctl_init(struct net *net)
 			goto err_alloc;
 	}
 
-	hdr = register_net_sysctl_sz(net, "net/ipv6", table,
-				     ARRAY_SIZE(xfrm6_policy_table));
+	hdr = register_net_sysctl(net, "net/ipv6", table, xfrm6_policy_table);
 	if (!hdr)
 		goto err_reg;
 
diff --git a/net/mptcp/ctrl.c b/net/mptcp/ctrl.c
index 63c5747f0f63cf75e516f68ac6cdde5ba5522278..df87f20f72ab86506b69ea40b403002ebf828348 100644
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -406,8 +406,7 @@ static int mptcp_pernet_new_table(struct net *net, struct mptcp_pernet *pernet)
 	/* table[12] is for available_path_managers which is read-only info */
 	table[13].data = &pernet->add_addr_v6_port_drop_ts;
 
-	hdr = register_net_sysctl_sz(net, MPTCP_SYSCTL_PATH, table,
-				     ARRAY_SIZE(mptcp_sysctl_table));
+	hdr = register_net_sysctl(net, MPTCP_SYSCTL_PATH, table, mptcp_sysctl_table);
 	if (!hdr)
 		goto err_reg;
 
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 4c1c739446b76ea455dab2958a844d05e31a46a7..c65ccdebc285926ed993aeddc21d17b0e2cbef40 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -5048,7 +5048,6 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
 	struct net *net = ipvs->net;
 	struct ctl_table *tbl;
 	int idx, ret;
-	size_t ctl_table_size = ARRAY_SIZE(vs_vars);
 	bool unpriv = net->user_ns != &init_user_ns;
 
 	atomic_set(&ipvs->dropentry, 0);
@@ -5166,8 +5165,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct netns_ipvs *ipvs)
 #endif
 
 	ret = -ENOMEM;
-	ipvs->sysctl_hdr = register_net_sysctl_sz(net, "net/ipv4/vs", tbl,
-						  ctl_table_size);
+	ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl, vs_vars);
 	if (!ipvs->sysctl_hdr)
 		goto err;
 	ipvs->sysctl_tbl = tbl;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index f4f2d82192d54ed9831b9677743f1139820e5a2e..a2f70cf4cd665e55f8e182bdf45da89b39434e11 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -1043,9 +1043,8 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
 		table[NF_SYSCTL_CT_BUCKETS].mode = 0444;
 	}
 
-	cnet->sysctl_header = register_net_sysctl_sz(net, "net/netfilter",
-						     table,
-						     ARRAY_SIZE(nf_ct_sysctl_table));
+	cnet->sysctl_header = register_net_sysctl(net, "net/netfilter", table,
+						  nf_ct_sysctl_table);
 	if (!cnet->sysctl_header)
 		goto out_unregister_netfilter;
 
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index b263634ac750d204a0d5726db6abe04023aa9c17..37fadb675faddf8e21f0aac04b96985ce3709bff 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -588,8 +588,8 @@ static __net_init int rds_tcp_init_net(struct net *net)
 	}
 	tbl[RDS_TCP_SNDBUF].data = &rtn->sndbuf_size;
 	tbl[RDS_TCP_RCVBUF].data = &rtn->rcvbuf_size;
-	rtn->rds_tcp_sysctl = register_net_sysctl_sz(net, "net/rds/tcp", tbl,
-						     ARRAY_SIZE(rds_tcp_sysctl_table));
+	rtn->rds_tcp_sysctl = register_net_sysctl(net, "net/rds/tcp", tbl,
+						  rds_tcp_sysctl_table);
 	if (!rtn->rds_tcp_sysctl) {
 		pr_warn("could not register sysctl\n");
 		err = -ENOMEM;
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index 47660d5726bbd7d812762f4feffa9a0a42499d7d..6d3d8d6905ace1c1b022951fab9b3f26c4a87c0a 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -48,8 +48,7 @@ int __net_init unix_sysctl_register(struct net *net)
 			goto err_alloc;
 	}
 
-	net->unx.ctl = register_net_sysctl_sz(net, "net/unix", table,
-					      ARRAY_SIZE(unix_table));
+	net->unx.ctl = register_net_sysctl(net, "net/unix", table, unix_table);
 	if (net->unx.ctl == NULL)
 		goto err_reg;
 
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index caebef73ea58d2b6043ca3fe3b6872f92fbe9fa6..b1fe08249050e95d4c945a8b670f21d5c444ebf4 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -2952,8 +2952,8 @@ static int __net_init vsock_sysctl_register(struct net *net)
 			goto err_alloc;
 	}
 
-	net->vsock.sysctl_hdr = register_net_sysctl_sz(net, "net/vsock", table,
-						       ARRAY_SIZE(vsock_table));
+	net->vsock.sysctl_hdr = register_net_sysctl(net, "net/vsock", table,
+						    vsock_table);
 	if (!net->vsock.sysctl_hdr)
 		goto err_reg;
 

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (7 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) " Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:36   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case Mauricio Faria de Oliveira
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

The sysctl table definition and registration must be in the same file,
in order for the macro to work.

Add plumbing to register ipv6_{route,icmp}_table in their own files.
With this, ipv6_{route,icmp}_sysctl_table_size() can be removed.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 include/net/ipv6.h         |  6 ++++--
 net/ipv6/icmp.c            |  6 ++++--
 net/ipv6/route.c           | 10 +++++++---
 net/ipv6/sysctl_net_ipv6.c | 10 ++--------
 4 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 3de07e738538f783e0fb4628c92ce50a7e36f9f5..29a095798abe8f5730ab0a046931ebf78f481bdf 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -1220,9 +1220,11 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev) { return 0; }
 
 #ifdef CONFIG_SYSCTL
 struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
-size_t ipv6_icmp_sysctl_table_size(void);
+struct ctl_table_header *ipv6_icmp_sysctl_register(struct net *net,
+						   const struct ctl_table *table);
 struct ctl_table *ipv6_route_sysctl_init(struct net *net);
-size_t ipv6_route_sysctl_table_size(struct net *net);
+struct ctl_table_header *ipv6_route_sysctl_register(struct net *net,
+						    const struct ctl_table *table);
 int ipv6_sysctl_register(void);
 void ipv6_sysctl_unregister(void);
 #endif
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index a95b0351824f3237815e43bf8448110070955884..bb170b8c867c3c6eaccc41aab8ab1c65eb0aa24b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -1450,8 +1450,10 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
 	return table;
 }
 
-size_t ipv6_icmp_sysctl_table_size(void)
+struct ctl_table_header *ipv6_icmp_sysctl_register(struct net *net,
+						   const struct ctl_table *table)
 {
-	return ARRAY_SIZE(ipv6_icmp_table_template);
+	return register_net_sysctl(net, "net/ipv6/icmp", table,
+				   ipv6_icmp_table_template);
 }
 #endif
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 16dfac54a259a11410ba736535f0462070979276..9e3f849d3564f4312d7b64157471f50c8168aafd 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -6698,13 +6698,17 @@ struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net)
 	return table;
 }
 
-size_t ipv6_route_sysctl_table_size(struct net *net)
+struct ctl_table_header *ipv6_route_sysctl_register(struct net *net,
+						    const struct ctl_table *table)
 {
+	size_t table_size = ARRAY_SIZE(ipv6_route_table_template);
+
 	/* Don't export sysctls to unprivileged users */
 	if (net->user_ns != &init_user_ns)
-		return 1;
+		table_size = 1;
 
-	return ARRAY_SIZE(ipv6_route_table_template);
+	return register_net_sysctl_sz(net, "net/ipv6/route", table,
+				      table_size, ipv6_route_table_template);
 }
 #endif
 
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index 75ba17cb7c0ccb4769d61e74220c75d0b3e2bcd9..88138fbd42b85d54d00cd15dfd7d6848ebabd607 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -280,17 +280,11 @@ static int __net_init ipv6_sysctl_net_init(struct net *net)
 	if (!net->ipv6.sysctl.hdr)
 		goto out_ipv6_icmp_table;
 
-	net->ipv6.sysctl.route_hdr = register_net_sysctl_sz(net,
-							    "net/ipv6/route",
-							    ipv6_route_table,
-							    ipv6_route_sysctl_table_size(net));
+	net->ipv6.sysctl.route_hdr = ipv6_route_sysctl_register(net, ipv6_route_table);
 	if (!net->ipv6.sysctl.route_hdr)
 		goto out_unregister_ipv6_table;
 
-	net->ipv6.sysctl.icmp_hdr = register_net_sysctl_sz(net,
-							   "net/ipv6/icmp",
-							   ipv6_icmp_table,
-							   ipv6_icmp_sysctl_table_size());
+	net->ipv6.sysctl.icmp_hdr = ipv6_icmp_sysctl_register(net, ipv6_icmp_table);
 	if (!net->ipv6.sysctl.icmp_hdr)
 		goto out_unregister_route_table;
 

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (8 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers " Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:39   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname Mauricio Faria de Oliveira
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Handle the last (edge) case:
- nf_log.c: ignore sysctl table with template set at run-time.

And re-enable the macro.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 include/linux/sysctl.h | 3 ---
 net/netfilter/nf_log.c | 9 +++++----
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 9e00a086ff1d47ab18021b3d79b0e8a93037cb2d..7e05fafd5544e1c4a3283dc13b0692f39515d01e 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -309,9 +309,6 @@ struct ctl_table_root {
  *
  * Define the macro SYSCTL_MODULE_ALIASES_DISABLE to disable this.
  */
-
-#define SYSCTL_MODULE_ALIASES_DISABLE
-
 #if defined(CONFIG_SYSCTL_MODULE_ALIASES) && defined(MODULE) &&			\
     !defined(SYSCTL_MODULE_ALIASES_DISABLE)
 
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index f4d80654dfe6ab6abd886e224f400e4444bcd29b..ed4a5a6b8d95b82676397f6747ef5d988c9060ea 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -518,10 +518,11 @@ static int netfilter_log_sysctl_init(struct net *net)
 	for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
 		table[i].extra2 = net;
 
-	net->nf.nf_log_dir_header = register_net_sysctl_sz(net,
-							   "net/netfilter/nf_log",
-							   table,
-							   ARRAY_SIZE(nf_log_sysctl_table));
+	/* MODULE_SYSCTL_TABLE(): template table's .procname set at run-time. */
+	net->nf.nf_log_dir_header = __register_net_sysctl_sz(net,
+							     "net/netfilter/nf_log",
+							     table,
+							     ARRAY_SIZE(nf_log_sysctl_table));
 	if (!net->nf.nf_log_dir_header)
 		goto err_reg;
 

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (9 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:38   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel() Mauricio Faria de Oliveira
  2026-08-19  2:28 ` [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols Mauricio Faria de Oliveira
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

The 'struct ctl_table.procname' field (sysctl filename) cannot be accessed
by scripts since it is defined in kernel headers (see "don't include kernel
headers into userspace" in file2alias.c) and its offset may be randomized.

Unrandomize '.procname' as the first field so its offset is always zero and
match the 'struct ctl_table' symbol address, which can be found by scripts.

Originally-by: Mauricio Faria de Oliveira <mfo@canonical.com>
Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 include/linux/sysctl.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 7e05fafd5544e1c4a3283dc13b0692f39515d01e..120c0f05bd083e08d8104ff05136138f2e8cdb07 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -220,7 +220,14 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
 
 /* A sysctl table is an array of struct ctl_table: */
 struct ctl_table {
+
+	/* This must be the first field for module aliases (file2alias.c) */
 	const char *procname;		/* Text ID for /proc/sys */
+
+#ifdef CONFIG_SYSCTL_MODULE_ALIASES
+	/* This begins the randomizable portion of the struct. */
+	randomized_struct_fields_start
+#endif
 	void *data;
 	int maxlen;
 	umode_t mode;
@@ -228,7 +235,14 @@ struct ctl_table {
 	struct ctl_table_poll *poll;
 	void *extra1;
 	void *extra2;
+#ifdef CONFIG_SYSCTL_MODULE_ALIASES
+	/* New fields go above here, so they are in the randomized portion. */
+	randomized_struct_fields_end
+};
+static_assert(offsetof(const struct ctl_table, procname) == 0);
+#else
 } __randomize_layout;
+#endif
 
 struct ctl_node {
 	struct rb_node node;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel()
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (10 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:39   ` sashiko-bot
  2026-08-19  2:28 ` [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols Mauricio Faria de Oliveira
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Move the arch-based addend_*_rel() calls into addend_rel() to be reused.

Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 scripts/mod/modpost.c | 35 +++++++++++++++++++----------------
 scripts/mod/modpost.h |  2 ++
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 75374c64b8cc78bb4d01fa4c64254c7d7cd80e8f..d18a87b882a67f06d5f75ee92f4c26dc713d83b8 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1296,6 +1296,24 @@ static Elf_Addr addend_mips_rel(uint32_t *location, unsigned int r_type)
 	return (Elf_Addr)(-1);
 }
 
+Elf_Addr addend_rel(struct elf_info *elf, unsigned int secndx,
+		    unsigned int r_type, Elf_Addr r_offset, Elf_Sym *tsym)
+{
+	void *loc = sym_get_data_by_offset(elf, secndx, r_offset);
+
+	switch (elf->hdr->e_machine) {
+	case EM_386:
+		return addend_386_rel(loc, r_type);
+	case EM_ARM:
+		return addend_arm_rel(loc, tsym, r_type);
+	case EM_MIPS:
+		return addend_mips_rel(loc, r_type);
+	}
+
+	fatal("Please add code to calculate addend for this architecture\n");
+	return (Elf_Addr)(-1);
+}
+
 #ifndef EM_RISCV
 #define EM_RISCV		243
 #endif
@@ -1402,27 +1420,12 @@ static void section_rel(struct module *mod, struct elf_info *elf,
 		Elf_Sym *tsym;
 		Elf_Addr taddr, r_offset;
 		unsigned int r_type, r_sym;
-		void *loc;
 
 		r_offset = TO_NATIVE(rel->r_offset);
 		get_rel_type_and_sym(elf, rel->r_info, &r_type, &r_sym);
 
-		loc = sym_get_data_by_offset(elf, fsecndx, r_offset);
 		tsym = elf->symtab_start + r_sym;
-
-		switch (elf->hdr->e_machine) {
-		case EM_386:
-			taddr = addend_386_rel(loc, r_type);
-			break;
-		case EM_ARM:
-			taddr = addend_arm_rel(loc, tsym, r_type);
-			break;
-		case EM_MIPS:
-			taddr = addend_mips_rel(loc, r_type);
-			break;
-		default:
-			fatal("Please add code to calculate addend for this architecture\n");
-		}
+		taddr = addend_rel(elf, fsecndx, r_type, r_offset, tsym);
 
 		check_section_mismatch(mod, elf, tsym,
 				       fsecndx, fromsec, r_offset, taddr);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index d5f6d82837d5b4fbd671ff9dab9bbe353442f6cf..a98811552bd2996c31cf73fd3619e6c58bac8a6d 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -222,6 +222,8 @@ const char *get_basename(const char *path);
 char *read_text_file(const char *filename);
 char *get_line(char **stringp);
 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
+Elf_Addr addend_rel(struct elf_info *elf, unsigned int secndx,
+		    unsigned int r_type, Elf_Addr r_offset, Elf_Sym *tsym);
 
 void __attribute__((format(printf, 3, 4)))
 modpost_log(bool is_error, struct module *mod, const char *fmt, ...);

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols
  2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
                   ` (11 preceding siblings ...)
  2026-08-19  2:28 ` [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel() Mauricio Faria de Oliveira
@ 2026-08-19  2:28 ` Mauricio Faria de Oliveira
  2026-08-19  2:48   ` sashiko-bot
  12 siblings, 1 reply; 27+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19  2:28 UTC (permalink / raw)
  To: Kees Cook, Joel Granados, Nathan Chancellor, Nicolas Schier,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman
  Cc: kernel-dev, linux-riscv, linux-kernel, fsverity, keyrings, bpf,
	linux-fsdevel, linux-kbuild, netdev, linux-wpan, lvs-devel,
	netfilter-devel, coreteam, linux-sctp, linux-rdma, linux-s390,
	bridge, mptcp, rds-devel, virtualization,
	Mauricio Faria de Oliveira

Update file2alias.c to handle 'mod_devicetable' symbols with type 'sysctl'.

The key operation is to iterate over relocation entries, so add the helper
for_each_reloc() with a function callback, and the functions to:

1) Find the sysctl path and table in the 'sysctl' module symbol.

2) Find the sysctl table's entries and their '.procname' field,
   adding a module alias 'sysctl:*/<path>/<procname>' for each.

Originally-by: Mauricio Faria de Oliveira <mfo@canonical.com>
Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
---
 scripts/mod/file2alias.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c    |  11 ++-
 scripts/mod/modpost.h    |  23 +++++
 3 files changed, 262 insertions(+), 2 deletions(-)

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d55840de60b3f8ec22b646d16ff8b..797cfc2f478e25dd2ba5f9a5a063a2919fe58cc5 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1531,6 +1531,231 @@ static const struct devtable devtable[] = {
 	{"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry},
 };
 
+// Looks like: sysctl:*/path/procname
+static void do_sysctl_entry(const char *procname, const char *path,
+			    struct module *mod)
+{
+	const char *src;
+	char *dst, buf[256], *end = buf + sizeof(buf) - 1; /* -1 for NUL byte */
+
+	/* Replace '%s' from path template with '*' for wildcard in modprobe. */
+	for (src = path, dst = buf; *src && dst < end; src++, dst++)
+		*dst = (*src == '%') ? (src++, '*') : *src;
+	*dst = '\0';
+
+	module_alias_printf(mod, false, "sysctl:*/%s/%s", buf, procname);
+}
+
+/*
+ * Execute a callback function for each relocation entry in relocation section.
+ * The caller must ensure sechdr->sh_type is SHT_RELA or SHT_REL.
+ */
+static void for_each_reloc(struct elf_info *elf, unsigned int shndx,
+			   bool (*fn)(struct elf_info *elf, Elf_Shdr *sechdr,
+				      Elf_Sym *sym, Elf_Addr r_offset,
+				      Elf_Addr r_addend, void *data),
+			   void *data)
+{
+	Elf_Shdr *sechdr = &elf->sechdrs[shndx];
+	const Elf_Rela *rela; /* used as Elf_Rel[a] on SHT_REL[A] */
+	const Elf_Rela *start = (void *) elf->hdr + sechdr->sh_offset;
+	const Elf_Rela *stop = (void *) start + sechdr->sh_size;
+	size_t size = (sechdr->sh_type == SHT_RELA) ? sizeof(Elf_Rela)
+						    : sizeof(Elf_Rel);
+
+	for (rela = start; rela < stop; rela = (Elf_Rela *)((void *) rela + size)) {
+		Elf_Sym *sym;
+		Elf_Addr r_offset, r_addend;
+		unsigned int r_type, r_sym;
+
+		r_offset = TO_NATIVE(rela->r_offset);
+		get_rel_type_and_sym(elf, rela->r_info, &r_type, &r_sym);
+
+		sym = elf->symtab_start + r_sym;
+		r_addend = (sechdr->sh_type == SHT_RELA)
+					? TO_NATIVE(rela->r_addend)
+					: addend_rel(elf, sechdr->sh_info,
+						     r_type, r_offset, sym);
+
+		if (fn(elf, sechdr, sym, r_offset, r_addend, data))
+			break;
+	}
+}
+
+/*
+ * Callback parameters and function to loop over the sysctl entries in struct
+ * module_sysctl_table's .table symbol (found below) in its reloction section.
+ */
+struct sysctl_entries {
+	Elf_Addr table_offset;
+	ssize_t table_size;
+	ssize_t entry_size;
+	const char *path;
+	const char *modsymname;
+	struct module *mod;
+};
+
+static bool do_sysctl_entries(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Sym *sym,
+			      Elf_Addr r_offset, Elf_Addr r_addend, void *data)
+{
+	struct sysctl_entries *sysctl_entries = (struct sysctl_entries *) data;
+
+	/* Skip until .table starts */
+	if (r_offset < sysctl_entries->table_offset)
+		return false;
+
+	/* Stop after .table ends */
+	if (r_offset >= sysctl_entries->table_offset + sysctl_entries->table_size)
+		return true;
+
+	/* Check for alignment with an array entry (.procname at offset zero) */
+	if ((r_offset - sysctl_entries->table_offset) % sysctl_entries->entry_size == 0) {
+
+		/* The symbol for .procname points to a string */
+		const char *procname = (const char *)
+				       sym_get_data_addend(elf, sym, r_addend);
+
+		if (!procname) {
+			warn("%s [%s] found entry with NULL .procname (skip)\n",
+			     sysctl_entries->modsymname, sysctl_entries->mod->name);
+			return false;
+		}
+
+		do_sysctl_entry(procname, sysctl_entries->path, sysctl_entries->mod);
+	}
+
+	/* Continue at next entry */
+	return false;
+}
+
+/*
+ * Callback parameters and function to search for struct module_sysctl_table's
+ * pointers (.path and .table) in relocation entries of a relocation section.
+ */
+struct sysctl_pointers {
+	/* Input: offsets */
+	Elf_Addr path_offset;
+	Elf_Addr table_offset;
+
+	/* Output: symbols and relocation addends */
+	Elf_Sym *path_sym;
+	Elf_Sym *table_sym;
+	Elf_Addr path_r_addend;
+	Elf_Addr table_r_addend;
+};
+
+static bool do_sysctl_pointers(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Sym *sym,
+			       Elf_Addr r_offset, Elf_Addr r_addend, void *data)
+{
+	struct sysctl_pointers *sysctl_pointers = (struct sysctl_pointers *) data;
+
+	/* Check for relocation entry's offset matching .path or .table */
+	if (!sysctl_pointers->path_sym &&
+	     sysctl_pointers->path_offset == r_offset) {
+		sysctl_pointers->path_sym = sym;
+		sysctl_pointers->path_r_addend = r_addend;
+	} else if (!sysctl_pointers->table_sym &&
+		    sysctl_pointers->table_offset == r_offset) {
+		sysctl_pointers->table_sym = sym;
+		sysctl_pointers->table_r_addend = r_addend;
+	}
+
+	/* Stop once both .path and .table are found */
+	return (sysctl_pointers->path_sym && sysctl_pointers->table_sym);
+}
+
+static void do_sysctl_table(const char *modsymname, void *modsymval,
+			    Elf_Sym *modsym, struct module *mod,
+			    struct elf_info *info)
+{
+	/*
+	 * The struct module_sysctl_table symbol contains 4 fields:
+	 *  .path: pointer to string with the dirname in /proc/sys
+	 *  .table: pointer to struct ctl_table array with filenames (.procname)
+	 *  .table_size: size of struct ctl_table array
+	 *  .entry_size: size of struct ctl_table entry in the array
+	 */
+
+	/* The size values can be read directly. */
+	DEF_FIELD(modsymval, module_sysctl_table, table_size);
+	DEF_FIELD(modsymval, module_sysctl_table, entry_size);
+
+	struct sysctl_entries sysctl_entries = {
+		.table_size = table_size,
+		.entry_size = entry_size,
+		.modsymname = modsymname,
+		.mod = mod,
+	};
+
+	/*
+	 * Step 1:
+	 *
+	 * Each pointer has a relocation entry in a relocation section,
+	 * that links the pointer with the symbol it points to.
+	 *
+	 * In order to access the symbols pointed to by .path and .table pointers:
+	 * 1) find the relocation section of the struct module_sysctl_table symbol;
+	 * 2) find the relocation entries for these pointers by their field offset;
+	 * 3) then use the symbols found in these relocation entries.
+	 */
+
+	struct sysctl_pointers sysctl_pointers = {
+		.path_offset = modsym->st_value + OFF_module_sysctl_table_path,
+		.path_sym = NULL,
+		.table_offset = modsym->st_value + OFF_module_sysctl_table_table,
+		.table_sym = NULL,
+	};
+
+	unsigned int shndx;
+
+	/* Find the relocation section for struct module_sysctl_table symbol. */
+	shndx = get_reloc_secindex(info, modsym);
+	if (shndx == SHN_UNDEF) {
+		error("%s [%s.ko] cannot find relocation section for symbol\n",
+		      modsymname, mod->name);
+		return;
+	}
+
+	/* Find the relocation entries for the .path and .table pointers. */
+	for_each_reloc(info, shndx, do_sysctl_pointers, &sysctl_pointers);
+	if (!sysctl_pointers.path_sym || !sysctl_pointers.table_sym) {
+		error("%s [%s.ko] cannot find relocation entry for path/table\n",
+		      modsymname, mod->name);
+		return;
+	}
+
+	/*
+	 * Step 2:
+	 *
+	 * The .table symbol is the struct ctl_table array where each entry has
+	 * a .procname pointer with a relocation entry for the filename string.
+	 *
+	 * In order to access the strings pointed to by .procname pointers:
+	 * 1) Find the relocation section of the struct ctl_table array symbol;
+	 * 2) Find the relocation entries for these pointers by their field offset;
+	 * 3) Then use the symbols found in these relocation entries.
+	 */
+
+	/* Find the relocation section for the struct ctl_table array. */
+	shndx = get_reloc_secindex(info, sysctl_pointers.table_sym);
+	if (shndx == SHN_UNDEF) {
+		/* Edge case: empty .table: no relocation section. */
+		return;
+	}
+
+	/* The .path symbol can be read directly. */
+	sysctl_entries.path = (const char *)
+			   sym_get_data_addend(info, sysctl_pointers.path_sym,
+						sysctl_pointers.path_r_addend);
+
+	/* The .table symbol is the struct ctl_table array. */
+	sysctl_entries.table_offset = sysctl_pointers.table_sym->st_value +
+				   sysctl_pointers.table_r_addend;
+
+	/* Add module aliases for entries in the struct ctl_table array. */
+	for_each_reloc(info, shndx, do_sysctl_entries, &sysctl_entries);
+}
+
 /* Create MODULE_ALIAS() statements.
  * At this time, we cannot write the actual output C source yet,
  * so we write into the mod->dev_table_buf buffer. */
@@ -1542,6 +1767,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 	const char *type, *name, *modname;
 	size_t typelen, modnamelen;
 	static const char *prefix = "__mod_device_table__";
+	bool sym_is_devtable = false;
 
 	/* We're looking for a section relative symbol */
 	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
@@ -1586,10 +1812,14 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 		if (sym_is(type, typelen, p->device_id)) {
 			do_table(name, symval, sym->st_size, p->id_size,
 				 p->device_id, p->do_entry, mod);
+			sym_is_devtable = true;
 			break;
 		}
 	}
 
+	if (!sym_is_devtable && sym_is(type, typelen, "sysctl"))
+		do_sysctl_table(name, symval, sym, mod, info);
+
 	if (mod->is_vmlinux) {
 		struct module_alias *alias;
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d18a87b882a67f06d5f75ee92f4c26dc713d83b8..10eb7273cdd817da788fa3bce87d695661dd1b93 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -340,6 +340,13 @@ void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
 				      sym->st_value);
 }
 
+void *sym_get_data_addend(const struct elf_info *info, const Elf_Sym *sym,
+			  Elf_Addr r_addend)
+{
+	return sym_get_data_by_offset(info, get_secindex(info, sym),
+				      sym->st_value + r_addend);
+}
+
 static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
 {
 	return sym_get_data_by_offset(info, info->secindex_strings,
@@ -1338,8 +1345,8 @@ Elf_Addr addend_rel(struct elf_info *elf, unsigned int secndx,
 #define R_LARCH_ALIGN		102
 #endif
 
-static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
-				 unsigned int *r_type, unsigned int *r_sym)
+void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
+			  unsigned int *r_type, unsigned int *r_sym)
 {
 	typedef struct {
 		Elf64_Word    r_sym;	/* Symbol index */
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index a98811552bd2996c31cf73fd3619e6c58bac8a6d..409fdfc844c4bfcea30fd6ae758f4042384e3e56 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -186,6 +186,25 @@ static inline unsigned int get_secindex(const struct elf_info *info,
 	return index;
 }
 
+/* Find the relocation section for the section of a symbol */
+static inline unsigned int get_reloc_secindex(const struct elf_info *info,
+					      const Elf_Sym *sym)
+{
+	unsigned int sym_secindex = get_secindex(info, sym);
+	unsigned int secindex;
+
+	for (secindex = 0; secindex < info->num_sections; secindex++) {
+		Elf_Shdr *shdr = &info->sechdrs[secindex];
+
+		if ((shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
+		    (shdr->sh_flags & SHF_INFO_LINK) &&
+		    shdr->sh_info == sym_secindex)
+			return secindex;
+	}
+
+	return SHN_UNDEF;
+}
+
 /*
  * If there's no name there, ignore it; likewise, ignore it if it's
  * one of the magic symbols emitted used by current tools.
@@ -222,8 +241,12 @@ const char *get_basename(const char *path);
 char *read_text_file(const char *filename);
 char *get_line(char **stringp);
 void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
+void *sym_get_data_addend(const struct elf_info *info, const Elf_Sym *sym,
+			  Elf_Addr r_addend);
 Elf_Addr addend_rel(struct elf_info *elf, unsigned int secndx,
 		    unsigned int r_type, Elf_Addr r_offset, Elf_Sym *tsym);
+void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
+			  unsigned int *r_type, unsigned int *r_sym);
 
 void __attribute__((format(printf, 3, 4)))
 modpost_log(bool is_error, struct module *mod, const char *fmt, ...);

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>'
  2026-08-19  2:28 ` [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>' Mauricio Faria de Oliveira
@ 2026-08-19  2:33   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:33 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Christian Borntraeger, Vasily Gorbik, Heiko Carstens, bpf, mptcp,
	Alexander Gordeev, linux-s390

> Fix an include loop error in preparation for sysctl.h to include module.h:
> 
>     CC [M]  arch/x86/events/amd/uncore.o
>   In file included from .../include/linux/fs.h:44,         <<<
>                    from .../include/linux/compat.h:17,
>                    from .../arch/x86/include/asm/ia32.h:7,
>                    from .../arch/x86/include/asm/elf.h:10,
>                    from .../include/linux/elf.h:6,
>                    from .../include/linux/module.h:20,     <<<
>                    from .../include/linux/sysctl.h:245,    <<<
>                    from .../include/linux/key.h:17,        <<<
>                    from .../include/linux/cred.h:13,       <<<
>                    from .../include/linux/sched/signal.h:10,
>                    from .../include/linux/ptrace.h:7,
>                    from .../include/uapi/asm-generic/bpf_perf_event.h:4,
> [ ... ]
> 
> Address this by removing sysctl.h from key.h, which does not need it,
> and adding it to files that actually need it.
> 
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=1


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) with template arguments
  2026-08-19  2:28 ` [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) " Mauricio Faria de Oliveira
@ 2026-08-19  2:36   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:36 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Alexander Gordeev, Heiko Carstens, Christian Borntraeger, mptcp,
	bpf, linux-s390, Vasily Gorbik

> Reduce register_net_sysctl_sz(net, path, table, ARRAY_SIZE(table_tmpl)) to
> register_net_sysctl(net, path, table, table_tmpl) which does it internally.
> 
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=8


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19  2:28 ` [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers " Mauricio Faria de Oliveira
@ 2026-08-19  2:36   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:36 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Christian Borntraeger, bpf, Heiko Carstens, mptcp, Vasily Gorbik,
	linux-s390, Alexander Gordeev

> The sysctl table definition and registration must be in the same file,
> in order for the macro to work.
> 
> Add plumbing to register ipv6_{route,icmp}_table in their own files.
> With this, ipv6_{route,icmp}_sysctl_table_size() can be removed.
> 
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=9


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES
  2026-08-19  2:28 ` [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES Mauricio Faria de Oliveira
@ 2026-08-19  2:37   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:37 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Christian Borntraeger, linux-s390, Heiko Carstens,
	Alexander Gordeev, mptcp, Vasily Gorbik, bpf

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] The Kconfig option `SYSCTL_MODULE_ALIASES` is introduced but never used in the codebase.
- [Low] Grammatical error in the Kconfig help text: 'This options adds' should be 'This option adds'.
--

--- Patch [2]: [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES ---
commit 931fa1a5261f1467829ad7b64b387a4e318eb177
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

proc: add config option SYSCTL_MODULE_ALIASES

Add a config option for the 'sysctl:' module aliases feature.

> diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> index 24f5a36f45df8..e6591ec4bcf0a 100644
> --- a/fs/proc/Kconfig
> +++ b/fs/proc/Kconfig
> @@ -98,6 +98,19 @@ config SYSCTL
>  	  building a kernel for install/rescue disks or your system is very
>  	  limited in memory.
>  
> +config SYSCTL_MODULE_ALIASES
> +	bool "'sysctl:' module aliases (EXPERIMENTAL)"

[Severity: Low]
Is this config option fully implemented in this commit? The
SYSCTL_MODULE_ALIASES option is being introduced here, but it doesn't look
like CONFIG_SYSCTL_MODULE_ALIASES is referenced anywhere else in the C code,
Makefiles, or scripts.

> +	depends on SYSCTL && MODULES
> +	default n
> +	help
> +	  The /proc/sys files registered by a module do not exist until the
> +	  module is loaded; meanwhile, userspace cannot find or access them.
> +
> +	  This options adds 'sysctl:*/<path>/<file>' module aliases for the

[Severity: Low]
This isn't a bug, but there is a typo in the help text: "This options adds"
should likely be "This option adds".

> +	  /proc/sys files registered by modules, so modules for nonexistent
> +	  files can be loaded with 'modprobe sysctl:/proc/sys/<path>/<file>'
> +	  by userspace when needed.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=2

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname
  2026-08-19  2:28 ` [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname Mauricio Faria de Oliveira
@ 2026-08-19  2:38   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:38 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Vasily Gorbik, Alexander Gordeev, Christian Borntraeger, bpf,
	mptcp, linux-s390, Heiko Carstens

> The 'struct ctl_table.procname' field (sysctl filename) cannot be accessed
> by scripts since it is defined in kernel headers (see "don't include kernel
> headers into userspace" in file2alias.c) and its offset may be randomized.
> 
> Unrandomize '.procname' as the first field so its offset is always zero and
> match the 'struct ctl_table' symbol address, which can be found by scripts.
> 
> Originally-by: Mauricio Faria de Oliveira <mfo@canonical.com>
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=11


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case
  2026-08-19  2:28 ` [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case Mauricio Faria de Oliveira
@ 2026-08-19  2:39   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:39 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: linux-s390, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, mptcp, bpf, Heiko Carstens

> Handle the last (edge) case:
> - nf_log.c: ignore sysctl table with template set at run-time.
> 
> And re-enable the macro.
> 
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=10


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel()
  2026-08-19  2:28 ` [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel() Mauricio Faria de Oliveira
@ 2026-08-19  2:39   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:39 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: linux-s390, Heiko Carstens, Alexander Gordeev,
	Christian Borntraeger, mptcp, bpf, Vasily Gorbik

> Move the arch-based addend_*_rel() calls into addend_rel() to be reused.
> 
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=12


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
  2026-08-19  2:28 ` [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:40   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:40 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: linux-s390, Alexander Gordeev, mptcp, Heiko Carstens,
	Vasily Gorbik, bpf, Christian Borntraeger

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] When `CONFIG_SYSCTL` is disabled, the build fails due to a preprocessor conflict where the newly introduced `register_net_sysctl_sz` macro expands inside its own fallback static inline function definition.
--

--- Patch [6]: [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE ---
commit fad97277609904f7e692d6e11a61fdff7e4ff635
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE

This commit replaces register_net_sysctl() and register_net_sysctl_sz() with
macros that automatically use MODULE_SYSCTL_TABLE for existing callers. It
renames the actual sysctl registration function to __register_net_sysctl_sz()
and adds optional template arguments to support dynamically defined paths and
tables.

> diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
> index e5ee673b9fcf8..2127049c71ced 100644
> --- a/include/net/net_namespace.h
> +++ b/include/net/net_namespace.h
[ ... ]
> @@ -520,13 +520,48 @@ void unregister_pernet_device(struct pernet_operations *);
>  
>  struct ctl_table;
>  
> -#define register_net_sysctl(net, path, table)	\
> -	register_net_sysctl_sz(net, path, table, ARRAY_SIZE(table))
> +/*
> + * The register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
> + * automatically create symbols in sysctl registration sites.
[ ... ]
> + */
> +#define _register_net_sysctl_sz(net, path, table, size, table_tmpl, path_tmpl)	\
> +({										\
> +	MODULE_SYSCTL_TABLE(path_tmpl, table_tmpl);				\
> +	__register_net_sysctl_sz(net, path, table, size);			\
> +})
> +
> +#define register_net_sysctl_sz(net, path, table, size, tmpl_args...)		\
> +	_register_net_sysctl_sz(net, path, table, size,				\
> +				__sysctl_table_tmpl_or_default(table,		\
> +							       ## tmpl_args),	\
> +				__sysctl_path_tmpl_or_default(path,		\
> +							      ## tmpl_args))
> +#define register_net_sysctl(net, path, table, tmpl_args...)			\
> +	register_net_sysctl_sz(net, path, table,				\
> +			       __sysctl_table_array_size(table, ## tmpl_args),	\
> +			       ## tmpl_args)
> +
> +/* Helper macro for optional template arguments */
> +#define __sysctl_table_array_size(table, tmpl_args...)	\
> +	ARRAY_SIZE(__sysctl_table_tmpl_or_default(table, ## tmpl_args))
> +
>  #ifdef CONFIG_SYSCTL
>  int net_sysctl_init(void);
> -struct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path,
> -						const struct ctl_table *table,
> -						size_t table_size);
> +struct ctl_table_header *__register_net_sysctl_sz(struct net *net,
> +						  const char *path,
> +						  const struct ctl_table *table,
> +						  size_t table_size);
>  void unregister_net_sysctl_table(struct ctl_table_header *header);
>  #else
>  static inline int net_sysctl_init(void) { return 0; }

[Severity: Low]
Does this commit break the build when CONFIG_SYSCTL is disabled?

Because register_net_sysctl_sz() is now defined as a macro unconditionally
above, the fallback static inline function in this #else block:

static inline struct ctl_table_header *register_net_sysctl_sz(struct net *net,
	const char *path, const struct ctl_table *table, size_t table_size)
{
	return NULL;
}

will cause a macro expansion conflict.

Should this static inline function be renamed to __register_net_sysctl_sz()
to avoid expanding the macro in its own definition and to provide the fallback
implementation needed by the new macro?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=6

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE
  2026-08-19  2:28 ` [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:40   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:40 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Heiko Carstens, Christian Borntraeger, linux-s390, bpf,
	Vasily Gorbik, mptcp, Alexander Gordeev

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] The file2alias.c handler for sysctl device tables is entirely missing from the patch, resulting in no module aliases being generated.
- [High] `__UNIQUE_ID` is used without arguments, preventing its expansion and causing redefinition compiler errors.
- [High] Pointers in device table structs cannot be dereferenced by modpost without relocation resolution.
- [High] modpost cannot parse `struct ctl_table` due to randomized layout and nested pointers.
- [High] Macro generates a single struct, but modpost expects a NULL-terminated array.
- [Medium] The MODULE_SYSCTL_TABLE macro silently accepts pointers instead of arrays, resulting in an invalid table_size.
--

--- Patch [3]: [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE ---
commit 4b00a2bf658ca058127bbaaa61c3c168a3a4574c
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE

This commit adds the MODULE_SYSCTL_TABLE macro to emit a struct
module_sysctl_table variable containing pointers to a sysctl table's path
and entries. It also adds the necessary struct definitions and field
offsets for modpost integration.

> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index a397213bedace..818a4a53448db 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h

[ ... ]

> @@ -78,4 +78,11 @@ struct cpu_feature {
>  	__u16	feature;
>  };
>  
> +struct module_sysctl_table {
> +	kernel_ulong_t path;
> +	kernel_ulong_t table;

[Severity: High]
Does modpost know how to read these external pointers? 

Modpost's file2alias.c extracts raw bytes from the struct and typically
does not resolve relocations to dereference .rodata or .data pointers. Will
this prevent modpost from actually reading the path or table strings/data
from unlinked ELF object files (.o)?

> +	__u16 table_size;
> +	__u16 entry_size;
> +};
> +
>  #endif /* LINUX_MOD_DEVICETABLE_H */
> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index e5d7226ab6f5a..6960fe22c50bf 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h

[ ... ]

> @@ -293,6 +293,48 @@ struct ctl_table_root {
>  	int (*permissions)(struct ctl_table_header *head, const struct ctl_table *table);
>  };
>  
> +/*
> + * Creates a symbol so file2alias.c can find the sysctl table.
> + *
> + * MODULE_SYSCTL_TABLE() is the sysctl equivalent of MODULE_DEVICE_TABLE(),
> + * with pointers to a sysctl table's path and entries, and table/entry sizes.
> + *
> + * The parameters 'path' and 'table' must be static (e.g., string literal or
> + * static char[]; static struct ctl_table[]) as both are used as initializer
> + * elements for a static struct variable.
> + *
> + * The generated symbol name contains 'table' by default. However, if 'table'
> + * is a struct field (contains '.' or '->'), in order to avoid syntax errors,
> + * define the macro SYSCTL_MODULE_ALIASES_UNIQUE_ID.
> + *
> + * Define the macro SYSCTL_MODULE_ALIASES_DISABLE to disable this.
> + */
> +#if defined(CONFIG_SYSCTL_MODULE_ALIASES) && defined(MODULE) &&			\
> +    !defined(SYSCTL_MODULE_ALIASES_DISABLE)
> +
> +#include <linux/module.h>
> +#include <linux/mod_devicetable.h>
> +
> +#if defined(SYSCTL_MODULE_ALIASES_UNIQUE_ID)
> +#define __MODULE_SYSCTL_TABLE_NAME(table)					\
> +	__mod_device_table(sysctl, __UNIQUE_ID)

[Severity: High]
Does this use of __UNIQUE_ID work correctly without an argument? 

Since __UNIQUE_ID is a function-like macro, using it without parentheses
prevents its expansion. This could result in the preprocessor treating it
as a literal token, generating a variable name like ...__sysctl____UNIQUE_ID
and causing redefinition errors if invoked multiple times in the same file.

> +#else
> +#define __MODULE_SYSCTL_TABLE_NAME(table)					\
> +	__mod_device_table(sysctl, table)
> +#endif
> +
> +#define MODULE_SYSCTL_TABLE(path, table)					\
> +	static struct module_sysctl_table __used				\
> +		__MODULE_SYSCTL_TABLE_NAME(table) = {				\

[Severity: High]
Will this work with modpost's do_table() logic? 

This macro generates a single struct instance, but modpost expects all
__mod_device_table symbols to point to an array terminated by an all-zero
element. Scanning this single struct could cause a build-time
"not terminated with a NULL entry" error when it sees non-zero bytes.

> +			(kernel_ulong_t) path,					\
> +			(kernel_ulong_t) table,					\

[Severity: High]
If modpost attempts to parse struct ctl_table through this pointer, how does
it handle a randomized struct layout? 

Since struct ctl_table can be marked with __randomize_layout when
CONFIG_RANDSTRUCT is enabled, a host tool like modpost cannot reliably extract
information from these entries without having the field offsets explicitly
exported in devicetable-offsets.c.

> +			(u16) sizeof(table),					\

[Severity: Medium]
Can this silently evaluate to a pointer size instead of the array size? 

If a pointer to a ctl_table is passed instead of a static array, sizeof(table)
evaluates to the pointer size, leading to an incorrect table size being
emitted. Could this be protected using __must_be_array(table)?

> +			(u16) sizeof(const struct ctl_table)			\
> +		}
> +#else
> +#define MODULE_SYSCTL_TABLE(path, table)
> +#endif
> +
>  #define register_sysctl(path, table)	\
>  	register_sysctl_sz(path, table, ARRAY_SIZE(table))
>  
> diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c
> index b4178c42d08f5..e3b8855e6ebcf 100644
> --- a/scripts/mod/devicetable-offsets.c
> +++ b/scripts/mod/devicetable-offsets.c

[ ... ]

> @@ -284,5 +284,11 @@ int main(void)
>  	DEVID(coreboot_device_id);
>  	DEVID_FIELD(coreboot_device_id, tag);
>  
> +	DEVID(module_sysctl_table);

[Severity: High]
Where is the file2alias.c handler for sysctl device tables? 

The commit message mentions this symbol will be handled by file2alias.c,
but the patch does not appear to add the corresponding entry in the
devtable[] array to actually parse the new struct. Will this result in
no module aliases being generated at all?

> +	DEVID_FIELD(module_sysctl_table, path);
> +	DEVID_FIELD(module_sysctl_table, table);
> +	DEVID_FIELD(module_sysctl_table, table_size);
> +	DEVID_FIELD(module_sysctl_table, entry_size);
> +
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=3

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments
  2026-08-19  2:28 ` [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments Mauricio Faria de Oliveira
@ 2026-08-19  2:44   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:44 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Christian Borntraeger, Alexander Gordeev, bpf, mptcp,
	Vasily Gorbik, linux-s390, Heiko Carstens

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Lockless traversal of the `port->devices` list can lead to a use-after-free if a device is concurrently unregistered.
--

--- Patch [5]: [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments ---
commit 511c6de215c54187a5a0e65c0208aa20775855cf
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

sysctl, parport: update register_sysctl() callers with template arguments
    
Update callers with dynamic table/path to use template arguments.

> diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c
> index cda3221e386ed..7c048e9a973aa 100644
> --- a/drivers/parport/procfs.c
> +++ b/drivers/parport/procfs.c

[ ... ]

[Severity: High]
This isn't a bug introduced by this patch, but could reading the active
device sysctl lead to a use-after-free if a device is concurrently
unregistered?

In drivers/parport/procfs.c:do_active_device(), the port->devices list is
traversed locklessly:

    for (dev = port->devices; dev ; dev = dev->next) {

Concurrently, parport_unregister_device() in drivers/parport/share.c can
remove a device from this list and free it:

    device_unregister(&dev->dev);

Since there is no synchronization (like taking port->pardevice_lock)
between the sysctl read and device removal, couldn't the lockless traversal
dereference a freed pardevice pointer?

This missing locking is also explicitly annotated in another lockless
traversal in drivers/parport/share.c:parport_release():

    /* !!! LOCKING IS NEEDED HERE */
    for (pd = port->devices; !port->cad && pd; pd = pd->next) {

Could an unprivileged user trigger this by repeatedly reading the sysctl
while a device is unregistered?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=5

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE
  2026-08-19  2:28 ` [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
@ 2026-08-19  2:44   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:44 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: linux-s390, Christian Borntraeger, mptcp, bpf, Alexander Gordeev,
	Vasily Gorbik, Heiko Carstens

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The macro `__UNIQUE_ID` is used without an argument in `__MODULE_SYSCTL_TABLE_NAME`, preventing its expansion.
- [Low] Dangling trailing backslash on the last line of the `register_sysctl` macro definition.
--

--- Patch [4]: [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE ---
commit 5518fc079c95785ae760d86da6be17693ac8aeea
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE

Add a MODULE_SYSCTL_TABLE call into register_sysctl() for existing callers
to automatically use it.

> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index 6960fe22c50bf..7e05fafd5544e 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
> @@ -335,8 +335,58 @@ struct ctl_table_root {
>  #define MODULE_SYSCTL_TABLE(path, table)
>  #endif

[Severity: Medium]
Does this code prevent __UNIQUE_ID from being expanded correctly?

Looking at __MODULE_SYSCTL_TABLE_NAME in include/linux/sysctl.h:

#define __MODULE_SYSCTL_TABLE_NAME(table) \
        __mod_device_table(sysctl, __UNIQUE_ID)

Since __UNIQUE_ID is a function-like macro that requires an argument, using it
without parentheses prevents preprocessor expansion. This results in the
literal string being used to construct the symbol name, which defeats the
purpose of generating a unique identifier and could cause symbol redefinition
errors if MODULE_SYSCTL_TABLE is used multiple times.

> -#define register_sysctl(path, table)	\
> -	register_sysctl_sz(path, table, ARRAY_SIZE(table))
> +/*
> + * The register_sysctl() wrapper for the MODULE_SYSCTL_TABLE macro

[ ... ]

> +#define _register_sysctl(path, table, table_tmpl, path_tmpl)			\
> +({										\
> +	MODULE_SYSCTL_TABLE(path_tmpl, table_tmpl);				\
> +	register_sysctl_sz(path, table, ARRAY_SIZE(table));			\
> +})
> +
> +#define register_sysctl(path, table, tmpl_args...)				\
> +	_register_sysctl(path, table,						\
> +			 __sysctl_table_tmpl_or_default(table, ## tmpl_args),	\
> +			 __sysctl_path_tmpl_or_default(path, ## tmpl_args))	\

[Severity: Low]
Is this trailing backslash intended?

The trailing backslash on the last line of the register_sysctl macro
definition will unnecessarily consume the empty line that follows it.

> +
> +/* Helper macros for optional template arguments */

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=4

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19  2:28 ` [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments Mauricio Faria de Oliveira
@ 2026-08-19  2:48   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:48 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Alexander Gordeev, Heiko Carstens, linux-s390, bpf, Vasily Gorbik,
	Christian Borntraeger, mptcp

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] Syntax error and implicit function declaration when CONFIG_SYSCTL is disabled due to macro collision.
- [Low] The `__UNIQUE_ID` macro is used without arguments in `__MODULE_SYSCTL_TABLE_NAME`, preventing it from generating a unique identifier.
--

--- Patch [7]: [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments ---
commit 35e3405d9382d3cfe84c302ce928023b61da151b
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

sysctl, net: update register_net_sysctl{_sz}() callers with template arguments

Update most callers with dynamic table/path to use template arguments.

> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 1349c0eedb642..bdd67dd879d24 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -12,6 +12,7 @@
>   */
>  
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +#define SYSCTL_MODULE_ALIASES_UNIQUE_ID

[Severity: Low]
When SYSCTL_MODULE_ALIASES_UNIQUE_ID is defined here, the macro
__MODULE_SYSCTL_TABLE_NAME(table) in include/linux/sysctl.h expands to
__mod_device_table(sysctl, __UNIQUE_ID).

Since __UNIQUE_ID is a function-like macro requiring a prefix argument, does
omitting the parentheses prevent it from being expanded by the preprocessor?
Could this create identical literal symbol names for all instances in a module
and defeat the uniqueness mechanism?

>  
>  #include <linux/slab.h>
>  #include <linux/types.h>
[ ... ]
> @@ -3910,11 +3911,15 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
>  	      BUG();
>  	}
>  
> -	snprintf(neigh_path, sizeof(neigh_path), "net/%s/neigh/%s",
> -		p_name, dev_name_source);
> +#define path_template "net/%s/neigh/%s"
> +	snprintf(neigh_path, sizeof(neigh_path), path_template,
> +		 p_name, dev_name_source);
>  	t->sysctl_header = register_net_sysctl_sz(neigh_parms_net(p),
>  						  neigh_path, t->neigh_vars,
> -						  neigh_vars_size);
> +						  neigh_vars_size,
> +						  neigh_sysctl_template.neigh_vars,
> +						  path_template);

[Severity: Low]
Does this call to register_net_sysctl_sz() cause a build failure when
CONFIG_SYSCTL is disabled?

It looks like register_net_sysctl_sz is globally defined as a macro, which
unconditionally expands over the static inline fallback definition in
include/net/net_namespace.h, producing invalid C syntax. Additionally, would
this macro expand to __register_net_sysctl_sz(), which lacks a stub in the
!CONFIG_SYSCTL path, causing implicit function declaration errors?

> +#undef path_template
>  	if (!t->sysctl_header)
>  		goto free;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=7

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols
  2026-08-19  2:28 ` [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols Mauricio Faria de Oliveira
@ 2026-08-19  2:48   ` sashiko-bot
  0 siblings, 0 replies; 27+ messages in thread
From: sashiko-bot @ 2026-08-19  2:48 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: bpf, Vasily Gorbik, Alexander Gordeev, linux-s390, Heiko Carstens,
	Christian Borntraeger, mptcp

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Double addition of `sym->st_value` causes `modpost` to read sysctl table pointers from incorrect offsets on ARM and other architectures utilizing `SHT_REL`.
- [Medium] The sysctl table entries processing aborts iteration upon encountering a relocation offset beyond the table's bounds, invalidly assuming ELF relocations are strictly sorted.
- [Low] The string replacement loop in `do_sysctl_entry()` skips the character immediately following a '%' without bounds checking, leading to an out-of-bounds read.
- [Low] The `entry_size` field parsed from the ELF file is used as a divisor without zero verification, allowing a malformed module to trigger a division-by-zero crash in `modpost`.
--

--- Patch [13]: [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols ---
commit 75e261ee7e3ce69bb021a98d7b4574fdc959ec34
Author: Mauricio Faria de Oliveira <mfo@igalia.com>

modpost: handle MODULE_SYSCTL_TABLE symbols

Update file2alias.c to handle 'mod_devicetable' symbols with type 'sysctl'.
The key operation is to iterate over relocation entries and add module aliases
for each entry.

> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 8d36c74dec2d5..797cfc2f478e2 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
> @@ -1531,6 +1531,231 @@ static const struct devtable devtable[] = {

[ ... ]

> +// Looks like: sysctl:*/path/procname
> +static void do_sysctl_entry(const char *procname, const char *path,
> +			    struct module *mod)
> +{
> +	const char *src;
> +	char *dst, buf[256], *end = buf + sizeof(buf) - 1; /* -1 for NUL byte */
> +
> +	/* Replace '%s' from path template with '*' for wildcard in modprobe. */
> +	for (src = path, dst = buf; *src && dst < end; src++, dst++)
> +		*dst = (*src == '%') ? (src++, '*') : *src;

[Severity: Low]
Does this loop advance past the end of the string if the path ends exactly
with a '%' character?

If *src is '%', the inline ternary operator does a src++. Then the loop's
update step does another src++, which would skip the NUL terminator and lead
to an out-of-bounds read on the next iteration.

> +	*dst = '\0';
> +
> +	module_alias_printf(mod, false, "sysctl:*/%s/%s", buf, procname);
> +}

[ ... ]

> +static bool do_sysctl_entries(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Sym *sym,
> +			      Elf_Addr r_offset, Elf_Addr r_addend, void *data)
> +{
> +	struct sysctl_entries *sysctl_entries = (struct sysctl_entries *) data;
> +
> +	/* Skip until .table starts */
> +	if (r_offset < sysctl_entries->table_offset)
> +		return false;
> +
> +	/* Stop after .table ends */
> +	if (r_offset >= sysctl_entries->table_offset + sysctl_entries->table_size)
> +		return true;

[Severity: Medium]
Is it safe to assume that relocation entries in the ELF section are strictly
sorted by r_offset?

By returning true here, the loop over relocation entries is aborted. The ELF
specification does not guarantee strict sorting by offset. If a linker emits
an out-of-order relocation entry earlier in the section but pointing past the
table, could this prematurely abort the traversal and miss valid entries?

> +
> +	/* Check for alignment with an array entry (.procname at offset zero) */
> +	if ((r_offset - sysctl_entries->table_offset) % sysctl_entries->entry_size == 0) {

[Severity: Low]
Can entry_size be zero here?

Since entry_size is parsed directly from the ELF module, a malformed module
with a size of 0 could trigger a division-by-zero crash in modpost.

> +
> +		/* The symbol for .procname points to a string */
> +		const char *procname = (const char *)
> +				       sym_get_data_addend(elf, sym, r_addend);

[ ... ]

> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index d18a87b882a67..10eb7273cdd81 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -340,6 +340,13 @@ void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
>  				      sym->st_value);
>  }
>  
> +void *sym_get_data_addend(const struct elf_info *info, const Elf_Sym *sym,
> +			  Elf_Addr r_addend)
> +{
> +	return sym_get_data_by_offset(info, get_secindex(info, sym),
> +				      sym->st_value + r_addend);
> +}

[Severity: High]
Does this result in adding sym->st_value twice on architectures like ARM
that use SHT_REL?

In for_each_reloc(), r_addend is calculated using addend_rel(). On ARM,
addend_rel() already returns the instruction value plus sym->st_value.

If sym->st_value is added again here (and in the manual table_offset
calculation in do_sysctl_table()), modpost will read from the wrong
offset, silently failing to extract .procname and missing the module
aliases.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@igalia.com?part=13

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2026-08-19  2:48 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-19  2:27 [PATCH RFC v2 00/13] sysctl: add module aliases Mauricio Faria de Oliveira
2026-08-19  2:28 ` [PATCH RFC v2 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>' Mauricio Faria de Oliveira
2026-08-19  2:33   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 02/13] proc: add config option SYSCTL_MODULE_ALIASES Mauricio Faria de Oliveira
2026-08-19  2:37   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
2026-08-19  2:40   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
2026-08-19  2:44   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 05/13] sysctl, parport: update register_sysctl() callers with template arguments Mauricio Faria de Oliveira
2026-08-19  2:44   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE Mauricio Faria de Oliveira
2026-08-19  2:40   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments Mauricio Faria de Oliveira
2026-08-19  2:48   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) " Mauricio Faria de Oliveira
2026-08-19  2:36   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers " Mauricio Faria de Oliveira
2026-08-19  2:36   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 10/13] sysctl, net: update register_net_sysctl_sz() edge case Mauricio Faria de Oliveira
2026-08-19  2:39   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 11/13] sysctl: unrandomize struct ctl_table.procname Mauricio Faria de Oliveira
2026-08-19  2:38   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 12/13] modpost: move addend_*_rel() calls into addend_rel() Mauricio Faria de Oliveira
2026-08-19  2:39   ` sashiko-bot
2026-08-19  2:28 ` [PATCH RFC v2 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols Mauricio Faria de Oliveira
2026-08-19  2:48   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).