]>
Commit | Line | Data |
---|---|---|
38c79e81 FG |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Tommi Rantala <tommi.t.rantala@nokia.com> | |
3 | Date: Mon, 5 Feb 2018 21:48:14 +0200 | |
4 | Subject: [PATCH] sctp: fix dst refcnt leak in sctp_v4_get_dst | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | Fix dst reference count leak in sctp_v4_get_dst() introduced in commit | |
10 | 410f03831 ("sctp: add routing output fallback"): | |
11 | ||
12 | When walking the address_list, successive ip_route_output_key() calls | |
13 | may return the same rt->dst with the reference incremented on each call. | |
14 | ||
15 | The code would not decrement the dst refcount when the dst pointer was | |
16 | identical from the previous iteration, causing the dst refcnt leak. | |
17 | ||
18 | Testcase: | |
19 | ip netns add TEST | |
20 | ip netns exec TEST ip link set lo up | |
21 | ip link add dummy0 type dummy | |
22 | ip link add dummy1 type dummy | |
23 | ip link add dummy2 type dummy | |
24 | ip link set dev dummy0 netns TEST | |
25 | ip link set dev dummy1 netns TEST | |
26 | ip link set dev dummy2 netns TEST | |
27 | ip netns exec TEST ip addr add 192.168.1.1/24 dev dummy0 | |
28 | ip netns exec TEST ip link set dummy0 up | |
29 | ip netns exec TEST ip addr add 192.168.1.2/24 dev dummy1 | |
30 | ip netns exec TEST ip link set dummy1 up | |
31 | ip netns exec TEST ip addr add 192.168.1.3/24 dev dummy2 | |
32 | ip netns exec TEST ip link set dummy2 up | |
33 | ip netns exec TEST sctp_test -H 192.168.1.2 -P 20002 -h 192.168.1.1 -p 20000 -s -B 192.168.1.3 | |
34 | ip netns del TEST | |
35 | ||
36 | In 4.4 and 4.9 kernels this results to: | |
37 | [ 354.179591] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
38 | [ 364.419674] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
39 | [ 374.663664] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
40 | [ 384.903717] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
41 | [ 395.143724] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
42 | [ 405.383645] unregister_netdevice: waiting for lo to become free. Usage count = 1 | |
43 | ... | |
44 | ||
45 | Fixes: 410f03831 ("sctp: add routing output fallback") | |
46 | Fixes: 0ca50d12f ("sctp: fix src address selection if using secondary addresses") | |
47 | Signed-off-by: Tommi Rantala <tommi.t.rantala@nokia.com> | |
48 | Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | |
49 | Acked-by: Neil Horman <nhorman@tuxdriver.com> | |
50 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
51 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
52 | --- | |
53 | net/sctp/protocol.c | 10 ++++------ | |
54 | 1 file changed, 4 insertions(+), 6 deletions(-) | |
55 | ||
56 | diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c | |
57 | index 989a900383b5..e1a3ae4f3cab 100644 | |
58 | --- a/net/sctp/protocol.c | |
59 | +++ b/net/sctp/protocol.c | |
60 | @@ -514,22 +514,20 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |
61 | if (IS_ERR(rt)) | |
62 | continue; | |
63 | ||
64 | - if (!dst) | |
65 | - dst = &rt->dst; | |
66 | - | |
67 | /* Ensure the src address belongs to the output | |
68 | * interface. | |
69 | */ | |
70 | odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr, | |
71 | false); | |
72 | if (!odev || odev->ifindex != fl4->flowi4_oif) { | |
73 | - if (&rt->dst != dst) | |
74 | + if (!dst) | |
75 | + dst = &rt->dst; | |
76 | + else | |
77 | dst_release(&rt->dst); | |
78 | continue; | |
79 | } | |
80 | ||
81 | - if (dst != &rt->dst) | |
82 | - dst_release(dst); | |
83 | + dst_release(dst); | |
84 | dst = &rt->dst; | |
85 | break; | |
86 | } | |
87 | -- | |
88 | 2.14.2 | |
89 |