diff options
| author | Fernando Fernandez Mancera <fmancera@suse.de> | 2026-06-22 15:08:56 +0200 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-23 19:12:47 -0700 |
| commit | 6a1b50e585f033f3e201f42a18b37f070095fb80 (patch) | |
| tree | e9751c67bb7c7ab2c49971eb763ca9ebc96acdd8 /net | |
| parent | 3e0e51c0ee1d08cc9d48dc17f3248d5b31cf8066 (diff) | |
| download | ath-6a1b50e585f033f3e201f42a18b37f070095fb80.tar.gz | |
ipv6: fix state corruption during proxy_ndp sysctl restart
When handling proxy_ndp, if rtnl_net_trylock() fails, the operation is
retried but as the value was already modified by the initial
proc_dointvec() call, the restarted syscall will read the newly modified
value as the 'old' state.
Fix this by taking the RTNL lock before parsing the input value if the
operation is a write.
Fixes: c92d5491a6d9 ("netconf: add support for IPv6 proxy_ndp")
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260622130857.5115-6-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv6/addrconf.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5d96cbf76134a..82b6f603faa04 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -6482,20 +6482,19 @@ static int addrconf_sysctl_disable(const struct ctl_table *ctl, int write, static int addrconf_sysctl_proxy_ndp(const struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos) { + struct net *net = ctl->extra2; int *valp = ctl->data; - int ret; int old, new; + int ret; + + if (write && !rtnl_net_trylock(net)) + return restart_syscall(); old = *valp; ret = proc_dointvec(ctl, write, buffer, lenp, ppos); new = *valp; if (write && old != new) { - struct net *net = ctl->extra2; - - if (!rtnl_net_trylock(net)) - return restart_syscall(); - if (valp == &net->ipv6.devconf_dflt->proxy_ndp) { inet6_netconf_notify_devconf(net, RTM_NEWNETCONF, NETCONFA_PROXY_NEIGH, @@ -6514,8 +6513,9 @@ static int addrconf_sysctl_proxy_ndp(const struct ctl_table *ctl, int write, idev->dev->ifindex, &idev->cnf); } - rtnl_net_unlock(net); } + if (write) + rtnl_net_unlock(net); return ret; } |
