mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
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: c92d5491a6 ("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>
This commit is contained in:
committed by
Jakub Kicinski
parent
3e0e51c0ee
commit
6a1b50e585
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user