From nobody Tue Sep 29 08:26:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7ED583C1974; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; cv=none; b=LM2zxugGR2RN4cz2zC4b1Qt7hgZEosOV+aPSe0XxkqUCqy0v3K/hYt2eZ1Gd4tHQbzaOyyxSc5qvsd9MVqN5qjkhz/1mA08KLISo3R7IrXKyzMQ4S0Ir71xVmp7+GfO30MKXvCt46fOWGWu9NqrOHJ5eSneH5v8jYVGZ9mDw0sU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; c=relaxed/simple; bh=fdM8YlvZqAkxic7f4H5puGcsJ5qBOUt62SzUItEjpmc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Pc52yS0QdxShyzhxV4/x1SnkD6vvyRolUn6N0FzfjQUTCF1GDhYhU0PpeeaGZQezGK8SdBdi55KyApL4Axkkt/OXJYiW2PX0di5MTw7k/vjZUIRNAyHSgHYdtalZ6nhlNqtpC94w/H7F59Y/ertJzangDh+vgQqAWkgoyPmSXm4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tA+hh+MT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tA+hh+MT" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3C843C19425; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786366880; bh=fdM8YlvZqAkxic7f4H5puGcsJ5qBOUt62SzUItEjpmc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=tA+hh+MToA99/5xP/NiclCOiEeAAG4jYru0tb3/vnW24A1+06v1b5526CGZwBIciq PORI8Zc+lzWvQx4llGFfde0C1cTaOOLnq48kA2J3XTRCVnnjC34F9slREUNsBrimmW MYzgTrYPSNhw5BTYcISKOwBqB/pdI9n2a3cJy764adx1637q5m4aoZOwHGyCnilemf X3ltFMoedEPXflzllwRkVca8rL7yktPFG9RSImToyXfwPcyjm0pcRxQ9PjFQAT/LGt 3AzlWISndBdNfbEM7gattiBCBGefOjy96S/Mwf2qz32eyceK9oo2nvuJHq4266iW6b bxXU/sLGJBxXQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16F26C5AD55; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) From: Joel Granados Date: Mon, 10 Aug 2026 15:01:02 +0200 Subject: [PATCH v4 1/3] net: enforce net sysctl registration Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260810-jag-net_const_qualify-v4-1-77e888237c69@kernel.org> References: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> In-Reply-To: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , David Ahern , Ido Schimmel , Pablo Neira Ayuso , Florian Westphal , Phil Sutter , Marcelo Ricardo Leitner , Xin Long , Steffen Klassert , Herbert Xu , "D. Wythe" , Dust Li , Sidraya Jayagond , Wenjia Zhang , Mahanta Jambigi , Tony Lu , Wen Gu , Kuniyuki Iwashima , Stefano Garzarella Cc: chia-yu.chang@nokia-bell-labs.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, linux-sctp@vger.kernel.org, linux-rdma@vger.kernel.org, linux-s390@vger.kernel.org, virtualization@lists.linux.dev, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3588; i=joel.granados@kernel.org; h=from:subject:message-id; bh=fdM8YlvZqAkxic7f4H5puGcsJ5qBOUt62SzUItEjpmc=; b=kA0DAAoBupfNUreWQU8ByyZiAGp5y5zIDtqCE0WpbZ/huPU0NcAcyVVhSsTlhDilbHbBijTuP 4kBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqecucAAoJELqXzVK3lkFPhPEL/09O X0yi4CZjcZNE0SwKtiTgqPFkkc7omc52D1l40F5KtGaE3mUjQziRXnT9z40zAfEoYLEVPhGKfPc 7ghTop4RnK3TXnzPRImsSS2hqZ6SwXjWNansCXsLr2J6rDZ7ShnSTd39nik+dslNxnGHuvC4drF 8zh1MndHBRtbMawGyBoDajXKYH/cmLAX99/Z6ekjU9+wMyZ/DHy5D/BU87Bb1gsllcaOIkoQ3qy t8/NjkQNQPA9LFcUmMXpd38MU4vNpqDSEiRJP9Tj/ncGz91gTo3jhDIX0dBmLx7EsVCoci0hbsY cz2eWaSEzA5iE5W6BXlXewexyDSZF27D7r7CtLIAAcqAUKbZTL0v0ReE8tgHli7mw3z5NRKtPXt 2mpQbVsVSMCYl85BqCoJhF4yfr+fqLs04SPnkQvn2o9WZcZi1rEiIY+pImf+HFb/befNMSMIBR/ F4abhqohhKAlaRw4xDhvAXkM1nuXszGiGA9J+L4ZRKhTYJ54qaJXIYtXdzcw== X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Replace the warning and file permission change with an error when an "unsafe" net sysctl registration is detected. One of the barriers preventing the const qualification of the ctl_tables in the net directory is the permission (->mode) change in ensure_safe_net_sysctl. This prep commit removes that barrier and ensures that the received ctl_table pointer to the net ctl_table register function is const. Signed-off-by: Joel Granados Reviewed-by: Simon Horman --- include/net/net_namespace.h | 5 +++-- net/sysctl_net.c | 25 +++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 501af1999fe8393d7c282a87645d1c4ceabadddc..e5ee673b9fcf846aefcc309d4cc= a1a8fc870aae2 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -525,12 +525,13 @@ struct ctl_table; #ifdef CONFIG_SYSCTL int net_sysctl_init(void); struct ctl_table_header *register_net_sysctl_sz(struct net *net, const cha= r *path, - struct ctl_table *table, size_t table_size); + 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, - const char *path, struct ctl_table *table, size_t table_size) + 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 19e8048241bacb18de853d3b904d0f97fd2fe78a..07f8434d4258c615c231ca7e292= 74de44b012665 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -114,16 +114,17 @@ __init int net_sysctl_init(void) goto out; } =20 -/* Verify that sysctls for non-init netns are safe by either: +/* Return error when sysctls for non-init netns are unsafe by verifying: * 1) being read-only, or * 2) having a data pointer which points outside of the global kernel/modu= le * data segment, and rather into the heap where a per-net object was * allocated. */ -static void ensure_safe_net_sysctl(struct net *net, const char *path, - struct ctl_table *table, size_t table_size) +static int ensure_safe_net_sysctl(struct net *net, const char *path, + const struct ctl_table *table, + size_t table_size) { - struct ctl_table *ent; + const struct ctl_table *ent; =20 pr_debug("Registering net sysctl (net %p): %s\n", net, path); ent =3D table; @@ -149,24 +150,24 @@ static void ensure_safe_net_sysctl(struct net *net, c= onst char *path, else continue; =20 - /* If it is writable and points to kernel/module global - * data, then it's probably a netns leak. - */ + /* Warn on netns leak. */ WARN(1, "sysctl %s/%s: data points to %s global data: %ps\n", - path, ent->procname, where, ent->data); + path, ent->procname, where, ent->data); =20 - /* Make it "safe" by dropping writable perms */ - ent->mode &=3D ~0222; + return -EACCES; } + + return 0; } =20 struct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path, - struct ctl_table *table, + const struct ctl_table *table, size_t table_size) { if (!net_eq(net, &init_net)) - ensure_safe_net_sysctl(net, path, table, table_size); + if (ensure_safe_net_sysctl(net, path, table, table_size)) + return NULL; =20 return __register_sysctl_table(&net->sysctls, path, table, table_size); } --=20 2.50.1 From nobody Tue Sep 29 08:26:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94B8A3D902E; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; cv=none; b=u2ajAgo7cVuy4ZelMB5AB68VmGhL5UEjVsEAMV9pXXju+GXSog++p4V8x37h20WGtmUSLkkAeQso1qGMCZMP/EmMi9GFO6H6luvNJzeHmgk9sGvuV54r1MZ8lInAH8wiCdaCYPJjvVtUCwC4ApOGVonkHLlqEaqa9XHK4WcpvAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; c=relaxed/simple; bh=cmAvZ19cBxKvDIXFYQDyg2kQK+OVtNvKHnf3LRawjkw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nUjj3y9OuQHKX/rlsZxxkXO2Yl+MquboN8+BI946r6YDYFYEeLupBiGWjzhf9mX5rxUXFBW5u19SefKFlEO3EnfVdhffLPN0a1KuzyeABWsOxA1DGYwnhZGpxUvzSr8/rCtPfKt5pax0be5rg6wX2T+FQS2HJzCd+lcsHDNpsjI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Tb7xI907; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Tb7xI907" Received: by smtp.kernel.org (Postfix) with ESMTPS id 47ED4C2BCF7; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786366880; bh=cmAvZ19cBxKvDIXFYQDyg2kQK+OVtNvKHnf3LRawjkw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Tb7xI907Og/rWIv9VCdy8kpJnF25F5zvB4qwCuB/iDkxLY7i1hKd7MA29hLIMG8xj 7rvbe+fubFSf1QyRt9PsI8za/Y/4enuxb6x9uoHTk3rujmoEo10HHzkSQ6qTf+u8Tm lmSmHz1zfMu3/LHCrg5hRP0Rr1SnW++ityIgP4G5HcAbc+RuRRZh38DUz5K8AgYej3 RX9AFlOeSHo7fCpdzAQUutL0quRTvEAcd4tMZuHd1ljnZGre6at8+wCgh3hz1wKsTC 0eSr1vOfsrKhHyX6/RiWVmKPntnlGpXrS9VlgYzi6rG9aBtShCcIITZ86mvy6VJEmD RWfEEI3Pg7xuA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FD8EC5AD7B; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) From: Joel Granados Date: Mon, 10 Aug 2026 15:01:03 +0200 Subject: [PATCH v4 2/3] net: Const qualify ctl_tables that kmemdup unconditionally Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260810-jag-net_const_qualify-v4-2-77e888237c69@kernel.org> References: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> In-Reply-To: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , David Ahern , Ido Schimmel , Pablo Neira Ayuso , Florian Westphal , Phil Sutter , Marcelo Ricardo Leitner , Xin Long , Steffen Klassert , Herbert Xu , "D. Wythe" , Dust Li , Sidraya Jayagond , Wenjia Zhang , Mahanta Jambigi , Tony Lu , Wen Gu , Kuniyuki Iwashima , Stefano Garzarella Cc: chia-yu.chang@nokia-bell-labs.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, linux-sctp@vger.kernel.org, linux-rdma@vger.kernel.org, linux-s390@vger.kernel.org, virtualization@lists.linux.dev, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4380; i=joel.granados@kernel.org; h=from:subject:message-id; bh=cmAvZ19cBxKvDIXFYQDyg2kQK+OVtNvKHnf3LRawjkw=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGp5y51liGHWq2D4loETsdzKtPejkgiQOjCxG aB/wwwIKZFLDokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqecudAAoJELqXzVK3 lkFPyegMAIj5M8HS2/tVsKpWcof6V5mm7X7hEMc9qsvcL/r2bRiHAQTEHv2Kz49MiEbqcIlIuyS sQqC3BVGxOpjL6kmp9KUIYPNJwxZaIZNSRaJ8WdRfzLIS0wtCMzqzNmirJuGyEhpXHl3yw+6Gd5 tSaZb2J67uX+Q0giMWG6VQq7E5vsXFHrknwRkA5hp2jzrjBgLsGuYl2L9lsesuKVGdJIWqqFvyp 6OqANRHjrBx2IZn2wuRNrmz/Z8kzlvFSGSN/D5iQ3Zb2xxJqNleuLKQfK7FI/+FYA7D4kgFRUt/ VF4kkqEluH49lpwU+IVBy0bt5NbEwLp1OXCwnONe98BJ3MI+dZPJVwuHK9OQJAmW010uxuwQG5e ZAmRb8fCqo6kGR/Cuvkduo9amnKD2dF/hx440d3OzpoUp+yMKpNG0+OSYv5lfrvzXRRoJxJ2Z4g 12Utv+67BjPZYGbVR8qHh6ZYcDpP9KlP96CBpEDUu3vlKSiW0fv0z9KcK5NsU9eDoUgENupTdj8 Ag= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Const qualify clt_table arrays in the net directory that always pass a memory duplicate to sysctl register. The template would then be in .rodata and the kmemdup'ed array would be outside. Signed-off-by: Joel Granados Reviewed-by: Simon Horman --- net/ipv4/devinet.c | 2 +- net/ipv6/icmp.c | 2 +- net/ipv6/route.c | 2 +- net/ipv6/sysctl_net_ipv6.c | 2 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/sctp/sysctl.c | 2 +- net/xfrm/xfrm_sysctl.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 47ded0f607d4bd502350f678c91b0054e3856427..a90be57c63be1565b2dff51e826= 4668fd71b9e58 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -2796,7 +2796,7 @@ static void devinet_sysctl_unregister(struct in_devic= e *idev) neigh_sysctl_unregister(idev->arp_parms); } =20 -static struct ctl_table ctl_forward_entry[] =3D { +static const struct ctl_table ctl_forward_entry[] =3D { { .procname =3D "ip_forward", .data =3D &ipv4_devconf.data[ diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index efb23807a0262e8d68aa1afc8d96ee94eab89d50..a95b0351824f3237815e43bf844= 8110070955884 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -1374,7 +1374,7 @@ EXPORT_SYMBOL(icmpv6_err_convert); static u32 icmpv6_errors_extension_mask_all =3D GENMASK_U8(ICMP_ERR_EXT_COUNT - 1, 0); =20 -static struct ctl_table ipv6_icmp_table_template[] =3D { +static const struct ctl_table ipv6_icmp_table_template[] =3D { { .procname =3D "ratelimit", .data =3D &init_net.ipv6.sysctl.icmpv6_time, diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5968ce5ad15082949ec4551458a1e2115ae803ac..b833a6400c944da6cdbf2b4cfa8= 7a5730ac2e06b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -6555,7 +6555,7 @@ static int ipv6_sysctl_rtcache_flush(const struct ctl= _table *ctl, int write, return 0; } =20 -static struct ctl_table ipv6_route_table_template[] =3D { +static const struct ctl_table ipv6_route_table_template[] =3D { { .procname =3D "max_size", .data =3D &init_net.ipv6.sysctl.ip6_rt_max_size, diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index d2cd33e2698d5c88df4718c9622dba2d574fa309..1a0a36dcdabc1be961d0ab69e5c= 93b05c53f46a8 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -61,7 +61,7 @@ proc_rt6_multipath_hash_fields(const struct ctl_table *ta= ble, int write, void *b return ret; } =20 -static struct ctl_table ipv6_table_template[] =3D { +static const struct ctl_table ipv6_table_template[] =3D { { .procname =3D "bindv6only", .data =3D &init_net.ipv6.sysctl.bindv6only, diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_con= ntrack_standalone.c index be2953c7d702e92031d4bcf7e707741abed0f49c..f4f2d82192d54ed9831b9677743= f1139820e5a2e 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -639,7 +639,7 @@ enum nf_ct_sysctl_index { NF_SYSCTL_CT_LAST_SYSCTL, }; =20 -static struct ctl_table nf_ct_sysctl_table[] =3D { +static const struct ctl_table nf_ct_sysctl_table[] =3D { [NF_SYSCTL_CT_MAX] =3D { .procname =3D "nf_conntrack_max", .data =3D &nf_conntrack_max, diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index fca840484ebf77853316704fa2ce7cc619524573..2b94c211427de7b2e9aa374033e= ac26ddd874e14 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -92,7 +92,7 @@ static struct ctl_table sctp_table[] =3D { #define SCTP_PF_RETRANS_IDX 2 #define SCTP_PS_RETRANS_IDX 3 =20 -static struct ctl_table sctp_net_table[] =3D { +static const struct ctl_table sctp_net_table[] =3D { [SCTP_RTO_MIN_IDX] =3D { .procname =3D "rto_min", .data =3D &init_net.sctp.rto_min, diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c index ca003e8a03760cd8dbb9e9f7cd5a9738eeeb7e71..357152a50faf10e5c33468c034d= d1777e0bed079 100644 --- a/net/xfrm/xfrm_sysctl.c +++ b/net/xfrm/xfrm_sysctl.c @@ -13,7 +13,7 @@ static void __net_init __xfrm_sysctl_init(struct net *net) } =20 #ifdef CONFIG_SYSCTL -static struct ctl_table xfrm_table[] =3D { +static const struct ctl_table xfrm_table[] =3D { { .procname =3D "xfrm_aevent_etime", .maxlen =3D sizeof(u32), --=20 2.50.1 From nobody Tue Sep 29 08:26:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97CED3D9DA8; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; cv=none; b=SfQBgtNMw9+fwrmcybfd7VhDGzjIGShnhmcbCn90mytA5bt0L9X2r9Wt8uTzLW5Cfx0S43e9bOvSUc/2B4QkikxPjXfLBFy4oX9xNLjP0RMXXRTVAiUy1i5vA7V0SFNVELl5f//q5Q4FBI5/D/dmc7ZVpRUgY3kJ1s/XQRML4Fk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786366880; c=relaxed/simple; bh=mfG7Azw81hPEVdqzwgIOg8Z+aGmBTWEtxIP+wtpAXiY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ucs+YvlBq4i96l/i4YYEjDuCoWpdHbsSVVIfCefVY/Bqs+akCVBJrDl3ii6fXwGzHfEPfwCmxwpCaAJ84+bqwZcKjRcsJ3RaWpnpCGChP2Bjpgv2xhftORNhOTwAJKh4cML8ygD1OvrM0JgoOiZA3Q75rhuk11RTG5SHi2zcXWY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hswFVdlv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hswFVdlv" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6C029C2BCFC; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1786366880; bh=mfG7Azw81hPEVdqzwgIOg8Z+aGmBTWEtxIP+wtpAXiY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=hswFVdlvA9HXbD2zDYECoxGn1LecujnqYHYlTR9fyEW+RID83KoIaaYyIqHrSX6VC 56Ed8jUdNUNWoyf8lh8p3k1yogzn1yB38XvNsbvxNUPH8uzGpmuEc0tbXCBHKGhg9K QnFZfaHyQx8KfXreeTh5FhuN59F4zr5kXA5Zp+wWjPook4efFvcQHPeRIc2WKnbWB8 FHm63oPwSSrj/ob+ZcpR7bKDSdrPk+6fCr0V2vhxA7QkyNdUsBYJ6i1bDqjscct0A8 /IB3GJr0yudArqPz7z4UVzSTXejLtFlM+Ia1mpTLlKTamtDj5N4ZEJdZFP9D19MGAL icRjlXce328Mg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B085C5B56B; Mon, 10 Aug 2026 13:01:20 +0000 (UTC) From: Joel Granados Date: Mon, 10 Aug 2026 15:01:04 +0200 Subject: [PATCH v4 3/3] net: Const qualify network templated ctl_tables Arrays Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260810-jag-net_const_qualify-v4-3-77e888237c69@kernel.org> References: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> In-Reply-To: <20260810-jag-net_const_qualify-v4-0-77e888237c69@kernel.org> To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , David Ahern , Ido Schimmel , Pablo Neira Ayuso , Florian Westphal , Phil Sutter , Marcelo Ricardo Leitner , Xin Long , Steffen Klassert , Herbert Xu , "D. Wythe" , Dust Li , Sidraya Jayagond , Wenjia Zhang , Mahanta Jambigi , Tony Lu , Wen Gu , Kuniyuki Iwashima , Stefano Garzarella Cc: chia-yu.chang@nokia-bell-labs.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, coreteam@netfilter.org, linux-sctp@vger.kernel.org, linux-rdma@vger.kernel.org, linux-s390@vger.kernel.org, virtualization@lists.linux.dev, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=13709; i=joel.granados@kernel.org; h=from:subject:message-id; bh=mfG7Azw81hPEVdqzwgIOg8Z+aGmBTWEtxIP+wtpAXiY=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGp5y53Tj1wbx1niL50rI9zUuw4Po8QHCSOxm dq7OT3P7cqBVokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqecudAAoJELqXzVK3 lkFPKpUL/3FC3496puI/yFKlPtUQ5Ei426Wr1E2Y0oJGWl7bLOF8SQAA1FBeo1bd+3GxxC1aer/ zbfxAkDxpPLyhiDSA49Kv5d7PYXeeOXnD1kj/mQ3TrNb2w8o+0ATO5gbmGKe3Ddzh8UafOAHk0D IWOszlNtDoK3ybUNy39cs20v+IvgPsZP0IPPNKwvWD2vB3y6QUyPom6g8VAb9q46BGSHIgHIpLJ reKb6mfImtGrcgU5yHO1hwbAG9bM096lato6BGKIzdg181veV3Gu42qERsSzuAltXOsJzhbrBmh cf8rWvC1FNOyJqTEVxXovilBDtym1QZ2dzgyR9JOKNJXYcBlj2C9Vi1jFf6KO6mk8X8JvYoZvPc 3AeTyXCPkVYhp4XG/wzIRJGfmj7N+prPlkYnHxQ3k/gDkY+FJqf7oKAO/FpiJ0YUxxDD5E1MgPg sUTJ38N4xUPRQXuSeXhLifoH4VFS1asaPbeW5t8uABEGZjD5PE6DVBSYxyEQ1GBiEqi29KAxy86 8c= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add duplication helpers in the cases where the ctl_table array elements are modified after duplication. Helpers return a ctl_table as const pointer allowing the const qualification of the static global ctl_table array. Signed-off-by: Joel Granados Reviewed-by: Simon Horman --- net/core/sysctl_net_core.c | 38 +++++++++++++++++---------- net/ipv4/sysctl_net_ipv4.c | 54 +++++++++++++++++++++++------------= ---- net/ipv4/xfrm4_policy.c | 22 ++++++++++++---- net/ipv6/xfrm6_policy.c | 22 ++++++++++++---- net/netfilter/nf_hooks_lwtunnel.c | 4 +-- net/smc/smc_sysctl.c | 26 ++++++++++++++----- net/unix/sysctl_net_unix.c | 21 +++++++++++---- net/vmw_vsock/af_vsock.c | 25 +++++++++++++----- 8 files changed, 146 insertions(+), 66 deletions(-) diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index b508618bfc12393ba926ebf5a2dd4ea73ef03ee8..eb35da3556f4aa00cecd4582ab9= 4e339d2518506 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -678,7 +678,7 @@ static struct ctl_table net_core_table[] =3D { }, }; =20 -static struct ctl_table netns_core_table[] =3D { +static const struct ctl_table netns_core_table[] =3D { #if IS_ENABLED(CONFIG_RPS) { .procname =3D "rps_default_mask", @@ -787,26 +787,38 @@ static int __init fb_tunnels_only_for_init_net_sysctl= _setup(char *str) } __setup("fb_tunnels=3D", fb_tunnels_only_for_init_net_sysctl_setup); =20 -static __net_init int sysctl_core_net_init(struct net *net) +static const struct ctl_table *netns_core_table_dup(struct net *net) { size_t table_size =3D ARRAY_SIZE(netns_core_table); struct ctl_table *tbl; + int i; + + tbl =3D kmemdup(netns_core_table, sizeof(netns_core_table), GFP_KERNEL); + if (!tbl) + return NULL; + + for (i =3D 0; i < table_size; ++i) { + if (tbl[i].data =3D=3D &sysctl_wmem_max) + break; + + tbl[i].data +=3D (char *)net - (char *)&init_net; + } + for (; i < table_size; ++i) + tbl[i].mode &=3D ~0222; + + return tbl; +} + +static __net_init int sysctl_core_net_init(struct net *net) +{ + size_t table_size =3D ARRAY_SIZE(netns_core_table); + const struct ctl_table *tbl; =20 tbl =3D netns_core_table; if (!net_eq(net, &init_net)) { - int i; - tbl =3D kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); + tbl =3D netns_core_table_dup(net); if (tbl =3D=3D NULL) goto err_dup; - - for (i =3D 0; i < table_size; ++i) { - if (tbl[i].data =3D=3D &sysctl_wmem_max) - break; - - tbl[i].data +=3D (char *)net - (char *)&init_net; - } - for (; i < table_size; ++i) - tbl[i].mode &=3D ~0222; } =20 net->core.sysctl_hdr =3D register_net_sysctl_sz(net, "net/core", tbl, tab= le_size); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index ca1180dba1dea9ce72028ba49b7f953da343336b..2f0363bca2a88d68276670cfce6= fb04398f82bc5 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -624,7 +624,7 @@ static struct ctl_table ipv4_table[] =3D { }, }; =20 -static struct ctl_table ipv4_net_table[] =3D { +static const struct ctl_table ipv4_net_table[] =3D { { .procname =3D "tcp_max_tw_buckets", .data =3D &init_net.ipv4.tcp_death_row.sysctl_max_tw_buckets, @@ -1654,35 +1654,45 @@ static struct ctl_table ipv4_net_table[] =3D { }, }; =20 -static __net_init int ipv4_sysctl_init_net(struct net *net) +static const struct ctl_table *ipv4_net_table_dup(struct net *net) { size_t table_size =3D ARRAY_SIZE(ipv4_net_table); struct ctl_table *table; + int i; + + table =3D kmemdup(ipv4_net_table, sizeof(ipv4_net_table), GFP_KERNEL); + if (!table) + return NULL; + + for (i =3D 0; i < table_size; i++) { + if (table[i].data) { + /* Update the variables to point into + * the current struct net + */ + table[i].data +=3D (void *)net - (void *)&init_net; + } else { + /* Entries without data pointer are global; + * Make them read-only in non-init_net ns + */ + table[i].mode &=3D ~0222; + } + if (table[i].extra2 >=3D (void *)&init_net.ipv4 && + table[i].extra2 < (void *)(&init_net.ipv4 + 1)) + table[i].extra2 +=3D (void *)net - (void *)&init_net; + } + return table; +} + +static __net_init int ipv4_sysctl_init_net(struct net *net) +{ + size_t table_size =3D ARRAY_SIZE(ipv4_net_table); + const struct ctl_table *table; =20 table =3D ipv4_net_table; if (!net_eq(net, &init_net)) { - int i; - - table =3D kmemdup(table, sizeof(ipv4_net_table), GFP_KERNEL); + table =3D ipv4_net_table_dup(net); if (!table) goto err_alloc; - - for (i =3D 0; i < table_size; i++) { - if (table[i].data) { - /* Update the variables to point into - * the current struct net - */ - table[i].data +=3D (void *)net - (void *)&init_net; - } else { - /* Entries without data pointer are global; - * Make them read-only in non-init_net ns - */ - table[i].mode &=3D ~0222; - } - if (table[i].extra2 >=3D (void *)&init_net.ipv4 && - table[i].extra2 < (void *)(&init_net.ipv4 + 1)) - table[i].extra2 +=3D (void *)net - (void *)&init_net; - } } =20 net->ipv4.ipv4_hdr =3D register_net_sysctl_sz(net, "net/ipv4", table, diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 58faf1ddd2b151e4569bb6351029718dac37521b..ab7a01029d490416d36482f7a31= 89f83d6670f42 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -141,7 +141,7 @@ static const struct xfrm_policy_afinfo xfrm4_policy_afi= nfo =3D { }; =20 #ifdef CONFIG_SYSCTL -static struct ctl_table xfrm4_policy_table[] =3D { +static const struct ctl_table xfrm4_policy_table[] =3D { { .procname =3D "xfrm4_gc_thresh", .data =3D &init_net.xfrm.xfrm4_dst_ops.gc_thresh, @@ -151,18 +151,30 @@ static struct ctl_table xfrm4_policy_table[] =3D { }, }; =20 -static __net_init int xfrm4_net_sysctl_init(struct net *net) +static const struct ctl_table *xfrm4_policy_table_dup(struct net *net) { struct ctl_table *table; + + table =3D kmemdup(xfrm4_policy_table, sizeof(xfrm4_policy_table), + GFP_KERNEL); + if (!table) + return NULL; + + table[0].data =3D &net->xfrm.xfrm4_dst_ops.gc_thresh; + + return table; +} + +static __net_init int xfrm4_net_sysctl_init(struct net *net) +{ + const struct ctl_table *table; struct ctl_table_header *hdr; =20 table =3D xfrm4_policy_table; if (!net_eq(net, &init_net)) { - table =3D kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL); + table =3D xfrm4_policy_table_dup(net); if (!table) goto err_alloc; - - table[0].data =3D &net->xfrm.xfrm4_dst_ops.gc_thresh; } =20 hdr =3D register_net_sysctl_sz(net, "net/ipv4", table, diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 3b749475f6ed6573eec7337b502d9188ee199bee..5ec063cb4aa4378e70fff002dd0= 3abf2029b247f 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -187,7 +187,7 @@ static void xfrm6_policy_fini(void) } =20 #ifdef CONFIG_SYSCTL -static struct ctl_table xfrm6_policy_table[] =3D { +static const struct ctl_table xfrm6_policy_table[] =3D { { .procname =3D "xfrm6_gc_thresh", .data =3D &init_net.xfrm.xfrm6_dst_ops.gc_thresh, @@ -197,18 +197,30 @@ static struct ctl_table xfrm6_policy_table[] =3D { }, }; =20 -static int __net_init xfrm6_net_sysctl_init(struct net *net) +static const struct ctl_table *xfrm6_policy_table_dup(struct net *net) { struct ctl_table *table; + + table =3D kmemdup(xfrm6_policy_table, sizeof(xfrm6_policy_table), + GFP_KERNEL); + if (!table) + return NULL; + + table[0].data =3D &net->xfrm.xfrm6_dst_ops.gc_thresh; + + return table; +} + +static int __net_init xfrm6_net_sysctl_init(struct net *net) +{ + const struct ctl_table *table; struct ctl_table_header *hdr; =20 table =3D xfrm6_policy_table; if (!net_eq(net, &init_net)) { - table =3D kmemdup(table, sizeof(xfrm6_policy_table), GFP_KERNEL); + table =3D xfrm6_policy_table_dup(net); if (!table) goto err_alloc; - - table[0].data =3D &net->xfrm.xfrm6_dst_ops.gc_thresh; } =20 hdr =3D register_net_sysctl_sz(net, "net/ipv6", table, diff --git a/net/netfilter/nf_hooks_lwtunnel.c b/net/netfilter/nf_hooks_lwt= unnel.c index 2d890dd04ff89041e6aec3741f24cdd7bc47d1fe..4e1eef1ba0f1559ca35f024723a= f551c6c9e7d35 100644 --- a/net/netfilter/nf_hooks_lwtunnel.c +++ b/net/netfilter/nf_hooks_lwtunnel.c @@ -54,7 +54,7 @@ int nf_hooks_lwtunnel_sysctl_handler(const struct ctl_tab= le *table, int write, } EXPORT_SYMBOL_GPL(nf_hooks_lwtunnel_sysctl_handler); =20 -static struct ctl_table nf_lwtunnel_sysctl_table[] =3D { +static const struct ctl_table nf_lwtunnel_sysctl_table[] =3D { { .procname =3D "nf_hooks_lwtunnel", .data =3D NULL, @@ -66,8 +66,8 @@ static struct ctl_table nf_lwtunnel_sysctl_table[] =3D { =20 static int __net_init nf_lwtunnel_net_init(struct net *net) { + const struct ctl_table *table; struct ctl_table_header *hdr; - struct ctl_table *table; =20 table =3D nf_lwtunnel_sysctl_table; if (!net_eq(net, &init_net)) { diff --git a/net/smc/smc_sysctl.c b/net/smc/smc_sysctl.c index b1efed5462435b1a6f2f59584a4cf47f5f6e1981..09dad48337f6164f5765fa79341= 2bdebf47e61ca 100644 --- a/net/smc/smc_sysctl.c +++ b/net/smc/smc_sysctl.c @@ -97,7 +97,7 @@ static int proc_smc_hs_ctrl(const struct ctl_table *ctl, = int write, } #endif /* CONFIG_SMC_HS_CTRL_BPF */ =20 -static struct ctl_table smc_table[] =3D { +static const struct ctl_table smc_table[] =3D { { .procname =3D "autocorking_size", .data =3D &init_net.smc.sysctl_autocorking_size, @@ -195,14 +195,29 @@ static struct ctl_table smc_table[] =3D { #endif /* CONFIG_SMC_HS_CTRL_BPF */ }; =20 -int __net_init smc_sysctl_net_init(struct net *net) +static const struct ctl_table *smc_table_dup(struct net *net) { size_t table_size =3D ARRAY_SIZE(smc_table); struct ctl_table *table; + int i; + + table =3D kmemdup(smc_table, sizeof(smc_table), GFP_KERNEL); + if (!table) + return NULL; + + for (i =3D 0; i < table_size; i++) + table[i].data +=3D (void *)net - (void *)&init_net; + + return table; +} + +int __net_init smc_sysctl_net_init(struct net *net) +{ + size_t table_size =3D ARRAY_SIZE(smc_table); + const struct ctl_table *table; =20 table =3D smc_table; if (!net_eq(net, &init_net)) { - int i; #if IS_ENABLED(CONFIG_SMC_HS_CTRL_BPF) struct smc_hs_ctrl *ctrl; =20 @@ -214,12 +229,9 @@ int __net_init smc_sysctl_net_init(struct net *net) rcu_read_unlock(); #endif /* CONFIG_SMC_HS_CTRL_BPF */ =20 - table =3D kmemdup(table, sizeof(smc_table), GFP_KERNEL); + table =3D smc_table_dup(net); if (!table) goto err_alloc; - - for (i =3D 0; i < table_size; i++) - table[i].data +=3D (void *)net - (void *)&init_net; } =20 net->smc.smc_hdr =3D register_net_sysctl_sz(net, "net/smc", table, diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c index e02ed6e3955c06b60cf4afb02656df8956f075ba..47660d5726bbd7d812762f4feff= a9a0a42499d7d 100644 --- a/net/unix/sysctl_net_unix.c +++ b/net/unix/sysctl_net_unix.c @@ -13,7 +13,7 @@ =20 #include "af_unix.h" =20 -static struct ctl_table unix_table[] =3D { +static const struct ctl_table unix_table[] =3D { { .procname =3D "max_dgram_qlen", .data =3D &init_net.unx.sysctl_max_dgram_qlen, @@ -23,18 +23,29 @@ static struct ctl_table unix_table[] =3D { }, }; =20 -int __net_init unix_sysctl_register(struct net *net) +static const struct ctl_table *unix_table_dup(struct net *net) { struct ctl_table *table; =20 + table =3D kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL); + if (!table) + return NULL; + + table[0].data =3D &net->unx.sysctl_max_dgram_qlen; + + return table; +} + +int __net_init unix_sysctl_register(struct net *net) +{ + const struct ctl_table *table; + if (net_eq(net, &init_net)) { table =3D unix_table; } else { - table =3D kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL); + table =3D unix_table_dup(net); if (!table) goto err_alloc; - - table[0].data =3D &net->unx.sysctl_max_dgram_qlen; } =20 net->unx.ctl =3D register_net_sysctl_sz(net, "net/unix", table, diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 622dbd0467994428f1a590f559b78d8c17f6ba60..caebef73ea58d2b6043ca3fe3b6= 872f92fbe9fa6 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -2899,7 +2899,7 @@ static int vsock_net_child_mode_string(const struct c= tl_table *table, int write, return 0; } =20 -static struct ctl_table vsock_table[] =3D { +static const struct ctl_table vsock_table[] =3D { { .procname =3D "ns_mode", .data =3D &init_net.vsock.mode, @@ -2925,20 +2925,31 @@ static struct ctl_table vsock_table[] =3D { }, }; =20 -static int __net_init vsock_sysctl_register(struct net *net) +static const struct ctl_table *vsock_table_dup(struct net *net) { struct ctl_table *table; =20 + table =3D kmemdup(vsock_table, sizeof(vsock_table), GFP_KERNEL); + if (!table) + return NULL; + + table[0].data =3D &net->vsock.mode; + table[1].data =3D &net->vsock.child_ns_mode; + table[2].data =3D &net->vsock.g2h_fallback; + + return table; +} + +static int __net_init vsock_sysctl_register(struct net *net) +{ + const struct ctl_table *table; + if (net_eq(net, &init_net)) { table =3D vsock_table; } else { - table =3D kmemdup(vsock_table, sizeof(vsock_table), GFP_KERNEL); + table =3D vsock_table_dup(net); if (!table) goto err_alloc; - - table[0].data =3D &net->vsock.mode; - table[1].data =3D &net->vsock.child_ns_mode; - table[2].data =3D &net->vsock.g2h_fallback; } =20 net->vsock.sysctl_hdr =3D register_net_sysctl_sz(net, "net/vsock", table, --=20 2.50.1