All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v3 00/13] sysctl: add module aliases
@ 2026-08-19 18:16 ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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.

Should this series eventually be merged, the patches will be submitted upstream
as well, for userspace to start consuming it.

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

Changes in v3:
- All issues were reported by sashiko-bot@kernel.org.
- Tested allmodconfig with option enabled on x86_64.
- Patch 2:
  - Fix typo ('s/options/option/').
- Patch 3:
  - Fix usage of __UNIQUE_ID().
  - Add __must_be_array() in MODULE_SYSCTL_TABLE().
- Patch 4:
  - Remove trailing backslash in register_sysctl().
- Patch 6:
  - Fix missing __register_net_sysctl_sz() in !CONFIG_SYSCTL.
- Patch 13:
  - Fix potential out-of-bounds read in do_sysctl_entry().
  - Add check for entry size of zero.
- Link to v2: https://lore.kernel.org/r/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@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             |  47 ++++++-
 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                | 237 ++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c                   |  46 ++++---
 scripts/mod/modpost.h                   |  25 ++++
 45 files changed, 575 insertions(+), 107 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] 41+ messages in thread

* [PATCH RFC v3 00/13] sysctl: add module aliases
@ 2026-08-19 18:16 ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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.

Should this series eventually be merged, the patches will be submitted upstream
as well, for userspace to start consuming it.

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

Changes in v3:
- All issues were reported by sashiko-bot@kernel.org.
- Tested allmodconfig with option enabled on x86_64.
- Patch 2:
  - Fix typo ('s/options/option/').
- Patch 3:
  - Fix usage of __UNIQUE_ID().
  - Add __must_be_array() in MODULE_SYSCTL_TABLE().
- Patch 4:
  - Remove trailing backslash in register_sysctl().
- Patch 6:
  - Fix missing __register_net_sysctl_sz() in !CONFIG_SYSCTL.
- Patch 13:
  - Fix potential out-of-bounds read in do_sysctl_entry().
  - Add check for entry size of zero.
- Link to v2: https://lore.kernel.org/r/20260818-sysctl-module-aliases-v2-0-d5a69dae5798@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             |  47 ++++++-
 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                | 237 ++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c                   |  46 ++++---
 scripts/mod/modpost.h                   |  25 ++++
 45 files changed, 575 insertions(+), 107 deletions(-)
---
base-commit: 2697ef8943c9985c14708a6429e21812693857b2
change-id: 20260818-sysctl-module-aliases-2f5801b1eb71

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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>'
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 01/13] keys, pidns, fs/verity, riscv/vector: reorder '#include <linux/sysctl.h>'
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 02/13] proc: add config option SYSCTL_MODULE_ALIASES
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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..ea77cb2b0b0e3e52ff2d19d9bb16d5a3f5ab8162 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 option 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] 41+ messages in thread

* [PATCH RFC v3 02/13] proc: add config option SYSCTL_MODULE_ALIASES
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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..ea77cb2b0b0e3e52ff2d19d9bb16d5a3f5ab8162 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 option 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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..0adc056ff54d895500c376361fe966bfa5126a3e 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(sysctl))
+#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) + __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 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] 41+ messages in thread

* [PATCH RFC v3 03/13] sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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..0adc056ff54d895500c376361fe966bfa5126a3e 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(sysctl))
+#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) + __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 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 0adc056ff54d895500c376361fe966bfa5126a3e..b808fbc1d964f453db8e354825fd8800db1eecd3 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] 41+ messages in thread

* [PATCH RFC v3 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 0adc056ff54d895500c376361fe966bfa5126a3e..b808fbc1d964f453db8e354825fd8800db1eecd3 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 05/13] sysctl, parport: update register_sysctl() callers with template arguments
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 05/13] sysctl, parport: update register_sysctl() callers with template arguments
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 | 47 +++++++++++++++++++++++++++++++++++++++------
 net/sysctl_net.c            | 10 +++++-----
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index b808fbc1d964f453db8e354825fd8800db1eecd3..7241dbf7eb81ce9f906e33645d03944671c5e6f1 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..c38ea2de35fe85c7ab8f1153a5c5681880b84840 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -520,17 +520,52 @@ 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; }
-static inline struct ctl_table_header *register_net_sysctl_sz(struct net *net,
+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;
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] 41+ messages in thread

* [PATCH RFC v3 06/13] sysctl, net: add register_net_sysctl{_sz}() wrappers for MODULE_SYSCTL_TABLE
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 | 47 +++++++++++++++++++++++++++++++++++++++------
 net/sysctl_net.c            | 10 +++++-----
 3 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index b808fbc1d964f453db8e354825fd8800db1eecd3..7241dbf7eb81ce9f906e33645d03944671c5e6f1 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..c38ea2de35fe85c7ab8f1153a5c5681880b84840 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -520,17 +520,52 @@ 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; }
-static inline struct ctl_table_header *register_net_sysctl_sz(struct net *net,
+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;
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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 07/13] sysctl, net: update register_net_sysctl{_sz}() callers with template arguments
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) with template arguments
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 08/13] sysctl, net: update register_net_sysctl_sz(ARRAY_SIZE(table_tmpl)) with template arguments
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 10/13] sysctl, net: update register_net_sysctl_sz() edge case
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 7241dbf7eb81ce9f906e33645d03944671c5e6f1..b808fbc1d964f453db8e354825fd8800db1eecd3 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] 41+ messages in thread

* [PATCH RFC v3 10/13] sysctl, net: update register_net_sysctl_sz() edge case
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 7241dbf7eb81ce9f906e33645d03944671c5e6f1..b808fbc1d964f453db8e354825fd8800db1eecd3 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 11/13] sysctl: unrandomize struct ctl_table.procname
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 b808fbc1d964f453db8e354825fd8800db1eecd3..ccc77bb918614b1de1e44fbef70471c85fb55c09 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] 41+ messages in thread

* [PATCH RFC v3 11/13] sysctl: unrandomize struct ctl_table.procname
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 b808fbc1d964f453db8e354825fd8800db1eecd3..ccc77bb918614b1de1e44fbef70471c85fb55c09 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 12/13] modpost: move addend_*_rel() calls into addend_rel()
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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] 41+ messages in thread

* [PATCH RFC v3 12/13] modpost: move addend_*_rel() calls into addend_rel()
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* [PATCH RFC v3 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols
  2026-08-19 18:16 ` Mauricio Faria de Oliveira
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  -1 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 | 237 +++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c    |  11 ++-
 scripts/mod/modpost.h    |  23 +++++
 3 files changed, 269 insertions(+), 2 deletions(-)

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d55840de60b3f8ec22b646d16ff8b..abf6ce69831e2ed80a72e38df1353e44d886562c 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1531,6 +1531,238 @@ 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, *end_src = path + strlen(path);
+	char *dst, buf[256], *end_dst = buf + sizeof(buf) - 1; /* -1 for NUL. */
+
+	/* Replace '%s' from path template with '*' for wildcard in modprobe. */
+	for (src = path, dst = buf; src < end_src && *src && dst < end_dst; 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;
+
+	/* The .entry_size value must not be zero. */
+	if (sysctl_entries.entry_size == 0) {
+		error("%s [%s.ko] invalid entry size (zero)\n",
+		      modsymname, mod->name);
+		return;
+	}
+
+	/* 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 +1774,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 +1819,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] 41+ messages in thread

* [PATCH RFC v3 13/13] modpost: handle MODULE_SYSCTL_TABLE symbols
@ 2026-08-19 18:16   ` Mauricio Faria de Oliveira
  0 siblings, 0 replies; 41+ messages in thread
From: Mauricio Faria de Oliveira @ 2026-08-19 18:16 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 | 237 +++++++++++++++++++++++++++++++++++++++++++++++
 scripts/mod/modpost.c    |  11 ++-
 scripts/mod/modpost.h    |  23 +++++
 3 files changed, 269 insertions(+), 2 deletions(-)

diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8d36c74dec2d55840de60b3f8ec22b646d16ff8b..abf6ce69831e2ed80a72e38df1353e44d886562c 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1531,6 +1531,238 @@ 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, *end_src = path + strlen(path);
+	char *dst, buf[256], *end_dst = buf + sizeof(buf) - 1; /* -1 for NUL. */
+
+	/* Replace '%s' from path template with '*' for wildcard in modprobe. */
+	for (src = path, dst = buf; src < end_src && *src && dst < end_dst; 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;
+
+	/* The .entry_size value must not be zero. */
+	if (sysctl_entries.entry_size == 0) {
+		error("%s [%s.ko] invalid entry size (zero)\n",
+		      modsymname, mod->name);
+		return;
+	}
+
+	/* 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 +1774,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 +1819,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


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

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

> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=1


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

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

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit introduces a Kconfig option `SYSCTL_MODULE_ALIASES` but provides no implementation for the feature it claims to add.
--

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

proc: add config option SYSCTL_MODULE_ALIASES

This commit adds a new Kconfig option for the 'sysctl:' module aliases
feature, allowing users to enable or disable it during kernel configuration.

> diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
> index 24f5a36f45df8..ea77cb2b0b0e3 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

[Severity: Medium]
Is the implementation for this feature missing from this patch?

The commit adds the SYSCTL_MODULE_ALIASES configuration option, but there
do not appear to be any references to CONFIG_SYSCTL_MODULE_ALIASES in any
C source files or Makefiles. Could this cause a situation where a user
enables the option expecting the functionality described in the help text,
but the feature remains completely unbacked by code?

> +	default n
> +	help
> +	  The /proc/sys files registered by a module do not exist until the

[ ... ]

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

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

* Re: [PATCH RFC v3 09/13] sysctl, ipv6: update register_net_sysctl{_sz}() callers with template arguments
  2026-08-19 18:16   ` Mauricio Faria de Oliveira
  (?)
@ 2026-08-19 18:24   ` sashiko-bot
  -1 siblings, 0 replies; 41+ messages in thread
From: sashiko-bot @ 2026-08-19 18:24 UTC (permalink / raw)
  To: Mauricio Faria de Oliveira
  Cc: Heiko Carstens, linux-s390, Vasily Gorbik, Christian Borntraeger,
	bpf, mptcp, 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=9


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

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

> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=10


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

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

> Update callers with dynamic table/path to use template arguments.
> 
> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=5


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

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

> 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>

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

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


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

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

> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=8


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

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

> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=12


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

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

> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=11


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

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

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] MODULE_SYSCTL_TABLE exports pointers to modpost, violating the devicetable design pattern and breaking module alias extraction.
- [Medium] Silent truncation of sysctl table size for large arrays.
- [Low] Brittle symbol name generation requires manual user workaround for struct field arguments.
- [Low] The commit message incorrectly documents the names of the control macros.
--

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

sysctl, mod_devicetable: add macro MODULE_SYSCTL_TABLE

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.

> 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.

[Severity: Low]
This isn't a bug, but the commit message documents these macros as
MODULE_SYSCTL_TABLE_DISABLE and MODULE_SYSCTL_TABLE_UNIQUE_ID, while the
code actually implements SYSCTL_MODULE_ALIASES_DISABLE and
SYSCTL_MODULE_ALIASES_UNIQUE_ID. Could the commit message be updated to
match the code?

> 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]
Will modpost be able to resolve these pointers? file2alias.c parses raw
section data from unlinked ELF objects to extract module aliases. Because
path and table are pointers rather than inline string arrays or structures,
modpost will read raw unresolved offsets instead of actual data.

This would break alias extraction on most architectures since file2alias.c
lacks a generalized relocation engine to resolve pointers across ELF sections.

> +	__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..0adc056ff54d8 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h

[ ... ]

> +#if defined(SYSCTL_MODULE_ALIASES_UNIQUE_ID)
> +#define __MODULE_SYSCTL_TABLE_NAME(table)					\
> +	__mod_device_table(sysctl, __UNIQUE_ID(sysctl))
> +#else
> +#define __MODULE_SYSCTL_TABLE_NAME(table)					\
> +	__mod_device_table(sysctl, table)
> +#endif

[Severity: Low]
Does this symbol name generation unnecessarily force manual workarounds? By
default, if table is passed as a struct member (like my_module.table), this
creates an invalid C identifier containing a dot. Would it be simpler to just
use __UNIQUE_ID unconditionally to avoid syntax errors?

> +
> +#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) + __must_be_array(table),		\

[Severity: Medium]
Could casting sizeof(table) to a u16 cause a silent truncation for very large
sysctl tables? 

While no current single static sysctl table in the kernel exceeds 65,535
bytes, casting size_t to a 16-bit integer creates a structural limit that
will silently report the wrong size if a table ever exceeds roughly 1,024
elements.

> +			(u16) sizeof(const struct ctl_table)			\
> +		}

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

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

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

> Update most callers with dynamic table/path to use template arguments.
> 
> 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/20260819-sysctl-module-aliases-v3-0-aab90569365d@igalia.com?part=7


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

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

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The `_register_sysctl` wrapper incorrectly uses `ARRAY_SIZE(table)` instead of `ARRAY_SIZE(table_tmpl)`, breaking the newly introduced template arguments feature for dynamic pointer tables.
- [Low] Fragile symbol name generation in `__MODULE_SYSCTL_TABLE_NAME` causes token-pasting syntax errors for complex arguments.
--

--- Patch [4]: [PATCH RFC v3 04/13] sysctl: add register_sysctl() wrapper for MODULE_SYSCTL_TABLE ---
commit c193948aeca054c46d40a2f5711a72369114c454
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/drivers/parport/procfs.c b/drivers/parport/procfs.c
> index 3880460e67f25..cda3221e386ed 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
> +

[Severity: Low]
Does the need for this disable flag suggest fragile symbol name generation
in __MODULE_SYSCTL_TABLE_NAME?

When register_sysctl() is called with a struct field or pointer dereference
(e.g., dev->table), the generated macro attempts to create a C identifier
containing -> or ., resulting in a compiler syntax error.

Would unconditionally using __UNIQUE_ID(sysctl) prevent this fragility
without requiring callers to use escape hatches like this?

[ ... ]

> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index 0adc056ff54d8..b808fbc1d964f 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
[ ... ]
> +#define _register_sysctl(path, table, table_tmpl, path_tmpl)			\
> +({										\
> +	MODULE_SYSCTL_TABLE(path_tmpl, table_tmpl);				\
> +	register_sysctl_sz(path, table, ARRAY_SIZE(table));			\

[Severity: Medium]
Will this break the template arguments feature for dynamic pointer tables?

If a caller attempts to use the template arguments feature with a dynamically
allocated pointer table, ARRAY_SIZE(table) will cause a compilation failure
because ARRAY_SIZE() cannot be applied to a pointer.

Since MODULE_SYSCTL_TABLE() explicitly enforces that the build-time template
is an array, should this macro use ARRAY_SIZE(table_tmpl) instead? This
would resolve the size correctly and allow the runtime table to be a
dynamically allocated pointer.

> +})

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

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

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

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Double addition of `st_value` when calculating relocation offsets for `SHT_REL` sections.
- [High] `get_reloc_secindex()` overly restricts relocation sections by mandating the `SHF_INFO_LINK` flag, risking build failures on older toolchains.
- [High] Unvalidated symbol indices when resolving `.path` and `.procname` pointers can lead to out-of-bounds reads and garbage alias generation.
- [Medium] `do_sysctl_entries` assumes ELF relocation entries are sorted by `r_offset`, which can prematurely abort the loop and miss sysctl aliases.
--

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

modpost: handle MODULE_SYSCTL_TABLE symbols

This commit updates file2alias.c to handle mod_devicetable symbols with
type sysctl. It introduces helpers to iterate over relocation entries,
extracting the path and procname fields to generate sysctl module aliases.

> diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
> index 8d36c74dec2d5..abf6ce69831e2 100644
> --- a/scripts/mod/file2alias.c
> +++ b/scripts/mod/file2alias.c
[ ... ]
> +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]
Does this code assume relocation entries are strictly sorted by r_offset?
The ELF specification does not guarantee that relocation entries are sorted.
If a compiler emits a relocation for a different variable earlier in the
section, could this prematurely abort the loop and miss valid sysctl aliases?

> +
> +	/* 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);

[Severity: High]
Could this read out-of-bounds memory or garbage data if the procname pointer
references an external string?

If the symbol section index is SHN_UNDEF or SHN_ABS, sym_get_data_by_offset()
might read from offset 0 (the ELF header) or an index far outside the bounds
of the section headers array. Should the symbol's section index be validated
before fetching the data?

> +
> +		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;
> +}
[ ... ]
> +static void do_sysctl_table(const char *modsymname, void *modsymval,
> +			    Elf_Sym *modsym, struct module *mod,
> +			    struct elf_info *info)
> +{
[ ... ]
> +	/* 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);

[Severity: High]
Similarly to the procname symbol above, is it possible for path_sym to be
SHN_UNDEF or SHN_ABS? Reading it without validating the section index could
cause modpost to crash or embed garbage aliases.

> +
> +	/* The .table symbol is the struct ctl_table array. */
> +	sysctl_entries.table_offset = sysctl_pointers.table_sym->st_value +
> +				   sysctl_pointers.table_r_addend;
> +
> +	/* The .entry_size value must not be zero. */
> +	if (sysctl_entries.entry_size == 0) {
> +		error("%s [%s.ko] invalid entry size (zero)\n",
> +		      modsymname, mod->name);
> +		return;
> +	}
> +
> +	/* Add module aliases for entries in the struct ctl_table array. */
> +	for_each_reloc(info, shndx, do_sysctl_entries, &sysctl_entries);
> +}
[ ... ]
> 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]
Will this result in a double-addition of st_value for SHT_REL sections?

In for_each_reloc(), addend_rel() is called for SHT_REL sections, which
already adds sym->st_value to the addend. Adding it again here computes
the offset as 2 * st_value + addend, which could read from the wrong offset
or cause an out-of-bounds access.

> +
>  static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
>  {
>  	return sym_get_data_by_offset(info, info->secindex_strings,
[ ... ]
> diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
> index a98811552bd29..409fdfc844c4b 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;
> +	}

[Severity: High]
Is it safe to mandate the SHF_INFO_LINK flag for relocation sections?

Older toolchains or alternative linkers might omit this flag even when
sh_info is correctly populated. If this returns SHN_UNDEF, the build will
fail unconditionally due to the error() call in do_sysctl_table().

> +
> +	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.
[ ... ]

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

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

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

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.