summaryrefslogtreecommitdiff
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2019-06-27 14:03:32 +0200
committerDavid S. Miller <davem@davemloft.net>2019-06-27 09:54:34 -0700
commit6a9e9cea4c51dd7137f381710bb42e2ad6e7e285 (patch)
tree57b256e5356e97686e4c57fad2236b0f947c187e /net/ipv4/devinet.c
parent5b9469a285ebc85af29736a6d9fa995aea0dbf0b (diff)
net: ipv4: fix infinite loop on secondary addr promotion
secondary address promotion causes infinite loop -- it arranges for ifa->ifa_next to point back to itself. Problem is that 'prev_prom' and 'last_prim' might point at the same entry, so 'last_sec' pointer must be obtained after prev_prom->next update. Fixes: 2638eb8b50cf ("net: ipv4: provide __rcu annotation for ifa_list") Reported-by: Ran Rozenstein <ranro@mellanox.com> Reported-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c3
1 files changed, 2 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);
}