net/tcp: Do cleanup on tcp_md5_key_copy() failure
authorDmitry Safonov <dima@arista.com>
Wed, 23 Nov 2022 17:38:58 +0000 (17:38 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 1 Dec 2022 23:53:05 +0000 (15:53 -0800)
If the kernel was short on (atomic) memory and failed to allocate it -
don't proceed to creation of request socket. Otherwise the socket would
be unsigned and userspace likely doesn't expect that the TCP is not
MD5-signed anymore.

Signed-off-by: Dmitry Safonov <dima@arista.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c

index 5d83a332f1ddc94cbfdce736c3de236f232c292c..7fae586405cfb10011a0674289280bf400dfa8d8 100644 (file)
@@ -1619,13 +1619,8 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
        addr = (union tcp_md5_addr *)&newinet->inet_daddr;
        key = tcp_md5_do_lookup(sk, l3index, addr, AF_INET);
        if (key) {
-               /*
-                * We're using one, so create a matching key
-                * on the newsk structure. If we fail to get
-                * memory, then we end up not copying the key
-                * across. Shucks.
-                */
-               tcp_md5_key_copy(newsk, addr, AF_INET, 32, l3index, key);
+               if (tcp_md5_key_copy(newsk, addr, AF_INET, 32, l3index, key))
+                       goto put_and_exit;
                sk_gso_disable(newsk);
        }
 #endif
index 80df917ced5f2928b6a754c7b9aa4c080b93f35a..11b736a76bd7e46c8f521d5cfef74be5ae9deee0 100644 (file)
@@ -1364,13 +1364,14 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
        /* Copy over the MD5 key from the original socket */
        key = tcp_v6_md5_do_lookup(sk, &newsk->sk_v6_daddr, l3index);
        if (key) {
-               /* We're using one, so create a matching key
-                * on the newsk structure. If we fail to get
-                * memory, then we end up not copying the key
-                * across. Shucks.
-                */
-               tcp_md5_key_copy(newsk, (union tcp_md5_addr *)&newsk->sk_v6_daddr,
-                                AF_INET6, 128, l3index, key);
+               const union tcp_md5_addr *addr;
+
+               addr = (union tcp_md5_addr *)&newsk->sk_v6_daddr;
+               if (tcp_md5_key_copy(newsk, addr, AF_INET6, 128, l3index, key)) {
+                       inet_csk_prepare_forced_close(newsk);
+                       tcp_done(newsk);
+                       goto out;
+               }
        }
 #endif