]>
Commit | Line | Data |
---|---|---|
38c79e81 FG |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Alexey Kodanev <alexey.kodanev@oracle.com> | |
3 | Date: Mon, 5 Feb 2018 15:10:35 +0300 | |
4 | Subject: [PATCH] sctp: fix dst refcnt leak in sctp_v6_get_dst() | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | When going through the bind address list in sctp_v6_get_dst() and | |
10 | the previously found address is better ('matchlen > bmatchlen'), | |
11 | the code continues to the next iteration without releasing currently | |
12 | held destination. | |
13 | ||
14 | Fix it by releasing 'bdst' before continue to the next iteration, and | |
15 | instead of introducing one more '!IS_ERR(bdst)' check for dst_release(), | |
16 | move the already existed one right after ip6_dst_lookup_flow(), i.e. we | |
17 | shouldn't proceed further if we get an error for the route lookup. | |
18 | ||
19 | Fixes: dbc2b5e9a09e ("sctp: fix src address selection if using secondary addresses for ipv6") | |
20 | Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> | |
21 | Acked-by: Neil Horman <nhorman@tuxdriver.com> | |
22 | Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | |
23 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
24 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
25 | --- | |
26 | net/sctp/ipv6.c | 10 +++++++--- | |
27 | 1 file changed, 7 insertions(+), 3 deletions(-) | |
28 | ||
29 | diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c | |
eac000ce | 30 | index edb462b0b73b..e626d72868fe 100644 |
38c79e81 FG |
31 | --- a/net/sctp/ipv6.c |
32 | +++ b/net/sctp/ipv6.c | |
33 | @@ -326,8 +326,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |
34 | final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); | |
35 | bdst = ip6_dst_lookup_flow(sk, fl6, final_p); | |
36 | ||
37 | - if (!IS_ERR(bdst) && | |
38 | - ipv6_chk_addr(dev_net(bdst->dev), | |
39 | + if (IS_ERR(bdst)) | |
40 | + continue; | |
41 | + | |
42 | + if (ipv6_chk_addr(dev_net(bdst->dev), | |
43 | &laddr->a.v6.sin6_addr, bdst->dev, 1)) { | |
44 | if (!IS_ERR_OR_NULL(dst)) | |
45 | dst_release(dst); | |
46 | @@ -336,8 +338,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |
47 | } | |
48 | ||
49 | bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); | |
50 | - if (matchlen > bmatchlen) | |
51 | + if (matchlen > bmatchlen) { | |
52 | + dst_release(bdst); | |
53 | continue; | |
54 | + } | |
55 | ||
56 | if (!IS_ERR_OR_NULL(dst)) | |
57 | dst_release(dst); | |
58 | -- | |
59 | 2.14.2 | |
60 |