diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
| -rw-r--r-- | net/ipv6/addrconf.c | 16 | 
1 files changed, 14 insertions, 2 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index de7a194a64a..143791da062 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -502,8 +502,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)  	if (p == &net->ipv6.devconf_dflt->forwarding)  		return 0; -	if (!rtnl_trylock()) +	if (!rtnl_trylock()) { +		/* Restore the original values before restarting */ +		*p = old;  		return restart_syscall(); +	}  	if (p == &net->ipv6.devconf_all->forwarding) {  		__s32 newf = net->ipv6.devconf_all->forwarding; @@ -4028,12 +4031,15 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,  {  	int *valp = ctl->data;  	int val = *valp; +	loff_t pos = *ppos;  	int ret;  	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);  	if (write)  		ret = addrconf_fixup_forwarding(ctl, valp, val); +	if (ret) +		*ppos = pos;  	return ret;  } @@ -4075,8 +4081,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)  	if (p == &net->ipv6.devconf_dflt->disable_ipv6)  		return 0; -	if (!rtnl_trylock()) +	if (!rtnl_trylock()) { +		/* Restore the original values before restarting */ +		*p = old;  		return restart_syscall(); +	}  	if (p == &net->ipv6.devconf_all->disable_ipv6) {  		__s32 newf = net->ipv6.devconf_all->disable_ipv6; @@ -4095,12 +4104,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,  {  	int *valp = ctl->data;  	int val = *valp; +	loff_t pos = *ppos;  	int ret;  	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);  	if (write)  		ret = addrconf_disable_ipv6(ctl, valp, val); +	if (ret) +		*ppos = pos;  	return ret;  }  |