Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2017-01-26 13:20:53 +0100
committerMichal Kubecek <mkubecek@suse.cz>2017-01-26 13:20:59 +0100
commitc499ea818c2eed476d5468b6c021eb9f30b20d4a (patch)
treec52e8c53a6086ae074539dbe7b6e175a79645491
parent4dd4ff1d0c172e499bc787a5277d677ac5072b12 (diff)
tcp: plug dst leak in tcp_v6_conn_request() (bsc#1010175).
-rw-r--r--patches.fixes/tcp-plug-dst-leak-in-tcp_v6_conn_request.patch89
-rw-r--r--series.conf1
2 files changed, 90 insertions, 0 deletions
diff --git a/patches.fixes/tcp-plug-dst-leak-in-tcp_v6_conn_request.patch b/patches.fixes/tcp-plug-dst-leak-in-tcp_v6_conn_request.patch
new file mode 100644
index 0000000000..3bd4031852
--- /dev/null
+++ b/patches.fixes/tcp-plug-dst-leak-in-tcp_v6_conn_request.patch
@@ -0,0 +1,89 @@
+From: Neal Cardwell <ncardwell@google.com>
+Date: Thu, 28 Jun 2012 12:34:21 +0000
+Subject: tcp: plug dst leak in tcp_v6_conn_request()
+Patch-mainline: v3.6-rc1
+Git-commit: 9f10d3f6f966ef6f6a8d025a4b1d341923d04607
+References: bsc#1010175
+
+The code in tcp_v6_conn_request() was implicitly assuming that
+tcp_v6_send_synack() would take care of dst_release(), much as
+tcp_v4_send_synack() already does. This resulted in
+tcp_v6_conn_request() leaking a dst if sysctl_tw_recycle is enabled.
+
+This commit restructures tcp_v6_send_synack() so that it accepts a dst
+pointer and takes care of releasing the dst that is passed in, to plug
+the leak and avoid future surprises by bringing the IPv6 behavior in
+line with the IPv4 side.
+
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Michal Kubecek <mkubecek@suse.cz>
+
+---
+ net/ipv6/tcp_ipv6.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 23feb006fa45..f2168a82a42d 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -478,19 +478,18 @@ out:
+ }
+
+
+-static int tcp_v6_send_synack(struct sock *sk,
++static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
++ struct flowi6 *fl6,
+ struct request_sock *req,
+ struct request_values *rvp)
+ {
+ struct inet6_request_sock *treq = inet6_rsk(req);
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct sk_buff * skb;
+- struct flowi6 fl6;
+- struct dst_entry *dst;
+ int err = -ENOMEM;
+
+- dst = inet6_csk_route_req(sk, &fl6, req);
+- if (!dst)
++ /* First, grab a route. */
++ if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
+ goto done;
+
+ skb = tcp_make_synack(sk, dst, req, rvp);
+@@ -498,9 +497,9 @@ static int tcp_v6_send_synack(struct sock *sk,
+ if (skb) {
+ __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
+
+- ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
++ ipv6_addr_copy(&fl6->daddr, &treq->rmt_addr);
+ rcu_read_lock();
+- err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt));
++ err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt));
+ rcu_read_unlock();
+ err = net_xmit_eval(err);
+ }
+@@ -513,8 +512,10 @@ done:
+ static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
+ struct request_values *rvp)
+ {
++ struct flowi6 fl6;
++
+ TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
+- return tcp_v6_send_synack(sk, req, rvp);
++ return tcp_v6_send_synack(sk, NULL, &fl6, req, rvp);
+ }
+
+ static inline void syn_flood_warning(struct sk_buff *skb)
+@@ -1336,7 +1337,7 @@ have_isn:
+
+ security_inet_conn_request(sk, skb, req);
+
+- if (tcp_v6_send_synack(sk, req,
++ if (tcp_v6_send_synack(sk, dst, &fl6, req,
+ (struct request_values *)&tmp_ext) ||
+ want_cookie)
+ goto drop_and_free;
+--
+2.11.0
+
diff --git a/series.conf b/series.conf
index 6c7c33b4d7..5dd94e07e2 100644
--- a/series.conf
+++ b/series.conf
@@ -2722,6 +2722,7 @@
patches.fixes/tcp-fix-inet6_csk_route_req-for-link-local-addresses.patch
patches.fixes/tcp-pass-fl6-to-inet6_csk_route_req.patch
patches.fixes/tcp-use-inet6_csk_route_req-in-tcp_v6_send_synack.patch
+ patches.fixes/tcp-plug-dst-leak-in-tcp_v6_conn_request.patch
########################################################
# tipc