diff options
author | David S. Miller <davem@davemloft.net> | 2019-06-27 09:54:35 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-27 09:54:35 -0700 |
commit | 582737f9904c6e84b7db2d417b2bf244374719e1 (patch) | |
tree | 485cac7117ac0bb3dd6713baaedaa37f5d7a7094 | |
parent | 5b9469a285ebc85af29736a6d9fa995aea0dbf0b (diff) | |
parent | bb2bd090854cc608d4d8a4d14955eb13dffa94ab (diff) |
Merge branch 'net-ipv4-fix-circular-list-infinite-loop'
Florian Westphal says:
====================
net: ipv4: fix circular-list infinite loop
Tariq and Ran reported a regression caused by net-next commit
2638eb8b50cf ("net: ipv4: provide __rcu annotation for ifa_list").
This happens when net.ipv4.conf.$dev.promote_secondaries sysctl is
enabled -- we can arrange for ifa->next to point at ifa, so next
process that tries to walk the list loops forever.
Fix this and extend rtnetlink.sh with a small test case for this.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/devinet.c | 3 | ||||
-rwxr-xr-x | tools/testing/selftests/net/rtnetlink.sh | 20 |
2 files changed, 22 insertions, 1 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 7874303220c5..137d1892395d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -428,8 +428,9 @@ no_promotions: if (prev_prom) { struct in_ifaddr *last_sec; - last_sec = rtnl_dereference(last_prim->ifa_next); rcu_assign_pointer(prev_prom->ifa_next, next_sec); + + last_sec = rtnl_dereference(last_prim->ifa_next); rcu_assign_pointer(promote->ifa_next, last_sec); rcu_assign_pointer(last_prim->ifa_next, promote); } diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index ed606a2e3865..505628884783 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -269,6 +269,25 @@ kci_test_addrlft() echo "PASS: preferred_lft addresses have expired" } +kci_test_promote_secondaries() +{ + promote=$(sysctl -n net.ipv4.conf.$devdummy.promote_secondaries) + + sysctl -q net.ipv4.conf.$devdummy.promote_secondaries=1 + + for i in $(seq 2 254);do + IP="10.23.11.$i" + ip -f inet addr add $IP/16 brd + dev "$devdummy" + ifconfig "$devdummy" $IP netmask 255.255.0.0 + done + + ip addr flush dev "$devdummy" + + [ $promote -eq 0 ] && sysctl -q net.ipv4.conf.$devdummy.promote_secondaries=0 + + echo "PASS: promote_secondaries complete" +} + kci_test_addrlabel() { ret=0 @@ -1161,6 +1180,7 @@ kci_test_rtnl() kci_test_polrouting kci_test_route_get kci_test_addrlft + kci_test_promote_secondaries kci_test_tc kci_test_gre kci_test_gretap |