]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.0.8/bridge-fix-multicast-router-rlist-endless-loop.patch
5.0-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.0.8 / bridge-fix-multicast-router-rlist-endless-loop.patch
1 From foo@baz Fri Jul 3 19:59:52 PDT 2015
2 From: Nikolay Aleksandrov <razor@blackwall.org>
3 Date: Tue, 9 Jun 2015 10:23:57 -0700
4 Subject: bridge: fix multicast router rlist endless loop
5
6 From: Nikolay Aleksandrov <razor@blackwall.org>
7
8 [ Upstream commit 1a040eaca1a22f8da8285ceda6b5e4a2cb704867 ]
9
10 Since the addition of sysfs multicast router support if one set
11 multicast_router to "2" more than once, then the port would be added to
12 the hlist every time and could end up linking to itself and thus causing an
13 endless loop for rlist walkers.
14 So to reproduce just do:
15 echo 2 > multicast_router; echo 2 > multicast_router;
16 in a bridge port and let some igmp traffic flow, for me it hangs up
17 in br_multicast_flood().
18 Fix this by adding a check in br_multicast_add_router() if the port is
19 already linked.
20 The reason this didn't happen before the addition of multicast_router
21 sysfs entries is because there's a !hlist_unhashed check that prevents
22 it.
23
24 Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
25 Fixes: 0909e11758bd ("bridge: Add multicast_router sysfs entries")
26 Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
27 Signed-off-by: David S. Miller <davem@davemloft.net>
28 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29 ---
30 net/bridge/br_multicast.c | 7 +++----
31 1 file changed, 3 insertions(+), 4 deletions(-)
32
33 --- a/net/bridge/br_multicast.c
34 +++ b/net/bridge/br_multicast.c
35 @@ -1166,6 +1166,9 @@ static void br_multicast_add_router(stru
36 struct net_bridge_port *p;
37 struct hlist_node *slot = NULL;
38
39 + if (!hlist_unhashed(&port->rlist))
40 + return;
41 +
42 hlist_for_each_entry(p, &br->router_list, rlist) {
43 if ((unsigned long) port >= (unsigned long) p)
44 break;
45 @@ -1193,12 +1196,8 @@ static void br_multicast_mark_router(str
46 if (port->multicast_router != 1)
47 return;
48
49 - if (!hlist_unhashed(&port->rlist))
50 - goto timer;
51 -
52 br_multicast_add_router(br, port);
53
54 -timer:
55 mod_timer(&port->multicast_router_timer,
56 now + br->multicast_querier_interval);
57 }