From 1730554f253deb65fe5112c54b2f898d5318a328 Mon Sep 17 00:00:00 2001
From: Florian Westphal <fw@strlen.de>
Date: Sun, 3 Aug 2008 18:13:44 -0700
Subject: [PATCH] ipv6: syncookies: free reqsk on xfrm_lookup error

cookie_v6_check() did not call reqsk_free() if xfrm_lookup() fails,
leaking the request sock.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 net/ipv6/syncookies.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index a46badd1082d..ec394cf5a19b 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -199,10 +199,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 	ireq6 = inet6_rsk(req);
 	treq = tcp_rsk(req);
 
-	if (security_inet_conn_request(sk, skb, req)) {
-		reqsk_free(req);
-		goto out;
-	}
+	if (security_inet_conn_request(sk, skb, req))
+		goto out_free;
 
 	req->mss = mss;
 	ireq->rmt_port = th->source;
@@ -255,14 +253,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 		fl.fl_ip_dport = inet_rsk(req)->rmt_port;
 		fl.fl_ip_sport = inet_sk(sk)->sport;
 		security_req_classify_flow(req, &fl);
-		if (ip6_dst_lookup(sk, &dst, &fl)) {
-			reqsk_free(req);
-			goto out;
-		}
+		if (ip6_dst_lookup(sk, &dst, &fl))
+			goto out_free;
+
 		if (final_p)
 			ipv6_addr_copy(&fl.fl6_dst, final_p);
 		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
-			goto out;
+			goto out_free;
 	}
 
 	req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
@@ -273,7 +270,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
 	ireq->rcv_wscale = rcv_wscale;
 
 	ret = get_cookie_sock(sk, skb, req, dst);
-
-out:	return ret;
+out:
+	return ret;
+out_free:
+	reqsk_free(req);
+	return NULL;
 }
 
-- 
GitLab