[PATCH] net/handshake: a handshake can only be cancelled once

Scott Mayhew <[email protected]>
Newsgroups dev.linux.lists.kernel-tls-handshake,org.kernel.vger.netdev
Message-ID <[email protected]>
When a handshake request is cancelled it is removed from the
handshake_net->hn_requests list, but it is still present in the
handshake_rhashtbl until it is destroyed.

If a second cancellation request arrives for the same handshake request,
then remove_pending() will return false... and assuming
HANDSHAKE_F_REQ_COMPLETED isn't set in req->hr_flags, we'll continue
processing through the out_true label, where we put another reference on
the sock and a refcount underflow occurs.

This can happen for example if a handshake times out - particularly if
the SUNRPC client sends the AUTH_TLS probe to the server but doesn't
follow it up with the ClientHello due to a problem with tlshd.  When the
timeout is hit on the server, the server will send a FIN, which triggers
a cancellation request via xs_reset_transport().  When the timeout is
hit on the client, another cancellation request happens via
xs_tls_handshake_sync().

Fixes: 3b3009ea8abb ("net/handshake: Create a NETLINK service for handling handshake requests")
Signed-off-by: Scott Mayhew <[email protected]>
---
 net/handshake/request.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/handshake/request.c b/net/handshake/request.c
index 274d2c89b6b2..c7b20d167a55 100644
--- a/net/handshake/request.c
+++ b/net/handshake/request.c
@@ -333,6 +333,10 @@ bool handshake_req_cancel(struct sock *sk)
 		return false;
 	}
 
+	/* Duplicate cancellation request */
+	trace_handshake_cancel_none(net, req, sk);
+	return false;
+
 out_true:
 	trace_handshake_cancel(net, req, sk);
 
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.