From nobody Sat Jul 25 21:30:55 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 1A33A37A839; Mon, 13 Jul 2026 11:07:54 +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=1783940874; cv=none; b=OyI/YAUarbzGH0KlaQM4b/K4lyUPY6MwuvQqaDmOoAlHZHh+RGuKAh4XGUe6rTgjfP/KlkFhlTQMa0M/oYwjC2+MV+a0mQ1hENCghp+rY+NSloYVZ8hSBiyU1P6ns5uKluT908YKQ6sO6qj928/wGXctd8qUNLKoW4/+q0LcOxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783940874; c=relaxed/simple; bh=gFPfNAZb5Emut5tl59jtS1GCSawh67g0IOaptPFibj4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GWYRxsUty+wLcsMpnbfHJJWMAUu8+8jg62cmjmBdts+oKht/WX+5IAVEMeG196UjLjXIRY+tevO3TN/vQ4coFP92r16LPo97nj67/Gium+xE7jGhMg7f70WlrjDV0JTq8UDb1EbWEUVw4AXbP2LIOxytiN3ejksN2GhuHynSN8o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OoTPnIF6; 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="OoTPnIF6" Received: by smtp.kernel.org (Postfix) with ESMTPS id C59C1C2BCF5; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783940873; bh=gFPfNAZb5Emut5tl59jtS1GCSawh67g0IOaptPFibj4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=OoTPnIF6SRLmVMupyhjeUKZcJU6AwKweMwZvPnhmtHyFwjFGZN6LED68Pg9kUqDIh QnIthYMOQS0FSZyN1buNkwC7IBnD/H8mjUCso0YSIVQgD3rz7hwLyyHbzgQHsM/7et ZMhrwojxoZ1IP71Bxifb4A/pv98lRSCNrDNqk2b+hWFAtomwindDIrfc8DsdmItmku 9UWDy/4ZhoDm6QwHErqcuP1uhsqGZI4fOzzRpLoXobSgVpMST0T+HlbbsFjoxIVHg/ J3TRolG2lzwG4pisXO7RHNB6bmwRtJM2ALur1waxVeb26jVXjtOo06m7mJb102PZH8 SjIX+F9U8UW0w== 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 A3BBCC44507; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) From: Joel Granados Date: Mon, 13 Jul 2026 13:07:42 +0200 Subject: [PATCH RFC net-next v3 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: <20260713-jag-net_const_qualify-v3-1-7289fe9eaea6@kernel.org> References: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@kernel.org> In-Reply-To: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@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: 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=3574; i=joel.granados@kernel.org; h=from:subject:message-id; bh=gFPfNAZb5Emut5tl59jtS1GCSawh67g0IOaptPFibj4=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGpUxwZskgenDOU98txc57mfzp9zCAPadshX1 w9t16Ag3hXFGYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqVMcGAAoJELqXzVK3 lkFPFuML/RuQe3IepvdaZwOqXPTFSxjiaQ9bHG5EjMlqTZJymTxUXke4CX6cffYqR8LOCXv/zqI Xz6yMTCeEaKdC/KbKlarrXHYnX0dUo/F3SqzxbWAoouVQN77rnoI7iQbY+TDK0GEy2zZONsm95u Vf+EfOQeGZuxwgpbCYUR8IBhhpqcVfuF0vI8vaxi7bhmmK30aRoBtLG+WYyHIgf/N7CXmGwRFxC yDHVArNMtiBNObUr0CVTFLxn8/BXuAIVrsNttsPGQm6aDvm3AQd87+wUS2otzOefZp82bJUl73e IzkI9JlAq/XN9dgNUEPdpolmegObR57+ikTaZzNrILLpVchdIIKBR4cZfPkGGVcjwBnrXrvM9Zy kksDs+AIzzP/SDuNq8GseNIMT37Jo/NFsSdfK+eblk8DVjuKx+gEwV7GHjkzZkGe6PEWWgIhT8f uCYW4EEdIC4+bpgG8ygVgbaTDyA1+W81V10LuKN5vBvLR6iuqzESCQGH1rg5ryeHGO+tKQvK3f8 Ig= 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 --- include/net/net_namespace.h | 4 ++-- net/sysctl_net.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 80de5e98a66d6c9273aa7c5b9d489b22cef8559a..dca0ec809483bec604f4ca3d99d= fea32834af8fa 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -522,12 +522,12 @@ 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..4714887113d90a191c300c9c49a= 6317d5609efeb 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -114,16 +114,16 @@ __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 +149,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 Sat Jul 25 21:30:55 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 1A3B537A83B; Mon, 13 Jul 2026 11:07:54 +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=1783940874; cv=none; b=q+fljzfWFhyJI7XJIz9b/W86+7RMqe/5f/9QuYrfE0NG87c4AOj83PvKC8t33DiPDSVR78dupm+uoC+GswTBm6VYJ9aWFzoES7aozhMvDyrEuS3mjIGUxMQHy+07phNX4r3VqnOIYpUc552URu4WFdDm0d6AWfZuOxlD5sgRS5k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783940874; c=relaxed/simple; bh=ZzghU9jdt4BJJ4IlRLVmOi7j3K0cQTWaD4Og3j5Q90U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YQoQFd2XFc7qWUJKtDLkVLHgXRbiIOr5ziF1HCrfcT/e5eThgQINoJ4uYtnCfjR+yEvVyFFKyaKpnbWwv/juL4oHAWQM+dRVkHaiVUhQGJJywbUYwNPz2TYpeMW0hhgG+O7xRCqBGxBoQrakjj7uhcp5sNNIS+fKD4nS3bL+Dt0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EFjsziI/; 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="EFjsziI/" Received: by smtp.kernel.org (Postfix) with ESMTPS id D6546C2BCF6; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783940873; bh=ZzghU9jdt4BJJ4IlRLVmOi7j3K0cQTWaD4Og3j5Q90U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EFjsziI/mGfueRicxx6aewwFNFseJDdhCJPCOfrOIrKfrRax4V78tKlEx8RgJh0jO rTwNH2ZiTA5CyiTtWzb8WRrTM7U09LUInFdlk10Mt0aZfcLr3yTMPyEHJnWFRjQoVe Iq6IuBFtdn+OskqKwYAAtIvZKhGfBaRU6pvWhK8lMu8PTxJ8qG2xOrb2g7vmQKAboM ALk8NY/eQRc6+Ue81pOkrg/J1NavEUJqTAjTFW/Fv1JUdmdEnz6Cad9ooAMBz4ygR0 FHMtb2m5jvRmxArUPi52YG4yHsTI5PCFex9hFqDZ0iUtNKAnrnKT9FWA3qwxwD4ocm zFkmPEFe8ocKQ== 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 B6621C44508; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) From: Joel Granados Date: Mon, 13 Jul 2026 13:07:43 +0200 Subject: [PATCH RFC net-next v3 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: <20260713-jag-net_const_qualify-v3-2-7289fe9eaea6@kernel.org> References: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@kernel.org> In-Reply-To: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@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: 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=ZzghU9jdt4BJJ4IlRLVmOi7j3K0cQTWaD4Og3j5Q90U=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGpUxwY+Xw/qHCYC+bjLVFiRD6foyFLDCcWQW QN1TonaLsB1sokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqVMcGAAoJELqXzVK3 lkFP9J8L/34pEjhY6Y3+wj4Y4xpsgpzo3tIv3DUXkdX/CgHwMIaSkss33feZj9x4ackkKdflapk iNGPQizMsKTrRQbW4gOhTUiY43oJIcwSXBppQLP/LRn1B9LO6lHpfFNsTJvBSHPTODJjTmJV6kn TVa1z0IosYw6SZchkWtp6raEKsBpYdaZ4HHCspvvX1/gR1bKWPEwd4h5Ui2bzEHVW5BOpabibAZ VMj1/GM8uIxnLWmFaVaFJt/8uXQtkMEM18NzjvbSzzQeKY0xDuqrLfcwD/inEHzG57fTbj20gRL S9Q7K93rM9W7dOViKAXiO+LRGTAgUff++NilzvVTU/BwNPf96umX9iSRvXn2wXiyWXwS/z8cFKD VQyb/KBl3B5b27jaypo9Uf+rLBAlN29UCXMf9NglZhTS7y7XAbhnO55l1Vvq9Lw6IbVCGpcIlT/ hlD+EnE7LtezC2CfYqYIXXqmkXIn+Lix6t8Ml7rJiVDC4J1KxrZ/VBXzEhNibF9+JdUwcg29a96 /M= 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 --- 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 a35b72662e431661da1672f428cae6bb3110480b..19edc08ae20c4f16d3bcf479dc2= 5022d55cbb5af 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -2798,7 +2798,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 a1301334da48c0f911da06ce448a76ecfb0d25cf..96b37c102a634c6715a5fbd1d39= ca415302ff859 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 15e7db9a3ab2e325f3951ac20c067a973a049618..331f45af9c4990d78a10a5c2c4e= fbcbca21813dc 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 Sat Jul 25 21:30:55 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 1A20C3769FE; Mon, 13 Jul 2026 11:07:54 +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=1783940874; cv=none; b=Ooj1zFrROtFYzUYpEF3OXsT4b4pwDTL6xpy2xIlkoRPXPhJ3CoruzmWv1uBHINjdflB8e8w+9k0g7N59WYuIofSqaZbtKhYNhTnSTT2/utd8zUsti+TfOUTA3Q3xvBplrz7P1iyxcAIgxJGsV8Res9uIJyaWsbujrtXyAJQ1JKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783940874; c=relaxed/simple; bh=v0+MG609dZTjGEN7kUhnpd5ADiTo5bAurAa1W9JmYKs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IPPgvYqybT5rjR1JgPW7JNaYfhXS+tFHW4wSVahxgmDpuJmxuuxcQPV21YLk3EPdqI19oniOB57TY0OI5/AaIhuqW7M69jXoaJGtZRwJNZhCZlb0ZAPJ6+q1iZFsLx81Uu/AthQDINlEb+hlGoYtXi0nvm5hyDm4XwnG+thDQUs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZQ6yw0ee; 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="ZQ6yw0ee" Received: by smtp.kernel.org (Postfix) with ESMTPS id E3BACC2BCFA; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1783940873; bh=v0+MG609dZTjGEN7kUhnpd5ADiTo5bAurAa1W9JmYKs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZQ6yw0eeoHmWjLiNBiFZuU2WDWuyxUstyByICxagzKh+teIDgseiWHJ3F1nrGXpeD +GYhYDXrrx2NhCqp5p6AIY1xqnNrSFD26tJi4POSJ187ulOWlmSmj673y8YN9X4Hef yu/vcyA5rv9Rxn0Ri41GO4jTyT46hck58VXvc8QS8oQYjoyzMsYy2QHYKkQcsfKRqt K8CCld7X1KIgOM/PQqvRW2QWZ4ctiGub+W3DN7uGiQcSeXq3EtNBYcbW2ah03ZLTw8 tg7mrEy4uQg4l03jxMPl6AKytLkf3DQOVtVeBSZGEP0DuWHQemeqD7cZVh8XMEyLuZ LGnrpIIvYDEbQ== 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 C69C7C44501; Mon, 13 Jul 2026 11:07:53 +0000 (UTC) From: Joel Granados Date: Mon, 13 Jul 2026 13:07:44 +0200 Subject: [PATCH RFC net-next v3 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: <20260713-jag-net_const_qualify-v3-3-7289fe9eaea6@kernel.org> References: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@kernel.org> In-Reply-To: <20260713-jag-net_const_qualify-v3-0-7289fe9eaea6@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: 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=v0+MG609dZTjGEN7kUhnpd5ADiTo5bAurAa1W9JmYKs=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGpUxwc5IEmEUrK0ky3OGnOlyhZX0IuZs9fuC HlMAC2ruSOzdYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJqVMcHAAoJELqXzVK3 lkFPcOEL/3gh1ZlNROJQUz2bR/chdON08U8HaJt8WsCxMwDE+poTeX1IiTwASupaM837S7At5q/ ww9PmHIH91IhAhEDjy0UX+SZVg9i/5rrB120OE1+ca7pAIMYzLCM8fBMCK0Kjk+pL1gyGNnbFmp fcz9NIcMD1g1kSqJWoHobyul+LwhO/1SqFCxTajeI7GnivboWXkRsK+47f8fhqiPBNGI9aNg2tE xCUdKxDZ9lUcfzlX8svdSbZo3UVOtGTiUASgC0t5jQ8BJqbJsTHpoaVYHf+bZ0SirlouhDJxgNC 4uDTllGBaI11paF4zrXNsPkvx59yTsMAxQPUwFjrfOp7QnhLBEaKPL8lXR2GTVIdgjrLB6dn1Ga rUb4ybILLIUkvjX0Bem18RanSK8/hNPGPzC17VUiq12g5TenibITX2nHRTZnPVV+4w4nZwlBR5M YIffm/BmHkZ09wGAdoV24djw5Ixf4gAPA7u+SrCmbg8mCKApvs4He/5dRqFHBKPtDqLMwH4WFJ6 bw= 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 --- 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 125ea9a5b8a082052380b7fd7ed7123f5247d7cc..1e0385b62cde3f6d23382f92bba= d5d7fdd09f1ef 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -186,7 +186,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, @@ -196,18 +196,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