summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-06-27 19:54:35 +0300
committerDavid S. Miller <davem@davemloft.net>2019-06-27 19:54:35 +0300
commit582737f9904c6e84b7db2d417b2bf244374719e1 (patch)
tree485cac7117ac0bb3dd6713baaedaa37f5d7a7094
parent5b9469a285ebc85af29736a6d9fa995aea0dbf0b (diff)
parentbb2bd090854cc608d4d8a4d14955eb13dffa94ab (diff)
downloadlinux-582737f9904c6e84b7db2d417b2bf244374719e1.tar.xz
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.c3
-rwxr-xr-xtools/testing/selftests/net/rtnetlink.sh20
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