| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Alexey Kodanev <[email protected]>
- Date: Mon, 5 Feb 2018 15:10:35 +0300
- Subject: [PATCH] sctp: fix dst refcnt leak in sctp_v6_get_dst()
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- When going through the bind address list in sctp_v6_get_dst() and
- the previously found address is better ('matchlen > bmatchlen'),
- the code continues to the next iteration without releasing currently
- held destination.
- Fix it by releasing 'bdst' before continue to the next iteration, and
- instead of introducing one more '!IS_ERR(bdst)' check for dst_release(),
- move the already existed one right after ip6_dst_lookup_flow(), i.e. we
- shouldn't proceed further if we get an error for the route lookup.
- Fixes: dbc2b5e9a09e ("sctp: fix src address selection if using secondary addresses for ipv6")
- Signed-off-by: Alexey Kodanev <[email protected]>
- Acked-by: Neil Horman <[email protected]>
- Acked-by: Marcelo Ricardo Leitner <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- Signed-off-by: Fabian Grünbichler <[email protected]>
- ---
- net/sctp/ipv6.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
- diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
- index 5d4c15bf66d2..e35d4f73d2df 100644
- --- a/net/sctp/ipv6.c
- +++ b/net/sctp/ipv6.c
- @@ -326,8 +326,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
- bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
-
- - if (!IS_ERR(bdst) &&
- - ipv6_chk_addr(dev_net(bdst->dev),
- + if (IS_ERR(bdst))
- + continue;
- +
- + if (ipv6_chk_addr(dev_net(bdst->dev),
- &laddr->a.v6.sin6_addr, bdst->dev, 1)) {
- if (!IS_ERR_OR_NULL(dst))
- dst_release(dst);
- @@ -336,8 +338,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
- }
-
- bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
- - if (matchlen > bmatchlen)
- + if (matchlen > bmatchlen) {
- + dst_release(bdst);
- continue;
- + }
-
- if (!IS_ERR_OR_NULL(dst))
- dst_release(dst);
- --
- 2.14.2
|