]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0018-sctp-fix-dst-refcnt-leak-in-sctp_v6_get_dst.patch
e6de54aa7f2cfd901f30d1776c8be01b7f037446
[pve-kernel.git] / patches / kernel / 0018-sctp-fix-dst-refcnt-leak-in-sctp_v6_get_dst.patch
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
30 index edb462b0b73b..e626d72868fe 100644
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