Commit d36f8434da8c333aa3837cf421a52f3835642759

Authored by Eric Dumazet
Committed by Greg Kroah-Hartman
1 parent d397617f75

inet: fix possible request socket leak

[ Upstream commit 3257d8b12f954c462d29de6201664a846328a522 ]

In commit b357a364c57c9 ("inet: fix possible panic in
reqsk_queue_unlink()"), I missed fact that tcp_check_req()
can return the listener socket in one case, and that we must
release the request socket refcount or we leak it.

Tested:

 Following packetdrill test template shows the issue

0     socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0    setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0    bind(3, ..., ...) = 0
+0    listen(3, 1) = 0

+0    < S 0:0(0) win 2920 <mss 1460,sackOK,nop,nop>
+0    > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
+.002 < . 1:1(0) ack 21 win 2920
+0    > R 21:21(0)

Fixes: b357a364c57c9 ("inet: fix possible panic in reqsk_queue_unlink()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 2 changed files with 2 additions and 2 deletions Side-by-side Diff

... ... @@ -1348,7 +1348,7 @@
1348 1348 req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr);
1349 1349 if (req) {
1350 1350 nsk = tcp_check_req(sk, skb, req, false);
1351   - if (!nsk)
  1351 + if (!nsk || nsk == sk)
1352 1352 reqsk_put(req);
1353 1353 return nsk;
1354 1354 }
... ... @@ -946,7 +946,7 @@
946 946 &ipv6_hdr(skb)->daddr, tcp_v6_iif(skb));
947 947 if (req) {
948 948 nsk = tcp_check_req(sk, skb, req, false);
949   - if (!nsk)
  949 + if (!nsk || nsk == sk)
950 950 reqsk_put(req);
951 951 return nsk;
952 952 }