Commit b389d1af authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Jakub Kicinski
Browse files

net/tcp: Do cleanup on tcp_md5_key_copy() failure



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: default avatarDmitry Safonov <dima@arista.com>
Acked-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 459837b5
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -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
+8 −7
Original line number Diff line number Diff line
@@ -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