Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.5.0, 5.6.0, 5.7, 5.8
-
None
-
5312621f796def296e39ceeb9f22abe696033e69
Description
[OpenSSL backend]
This behavior used to work in Qt 4.
QSslSocket::abort() and QSslSocket::close (called by abort()), do not update the QSslSocket's socket state.
Consider an SSL server that is accepting a client.
The server is inside the QSslSocketPrivate::startHandshake() method, and emits peerVerifyError.
The slot of peerVerifyError in turn calls QSslSocket::abort() on the socket to terminate it immediately.
The documentation for the peerVerifyError siganl says this is a valid use-case: "[...] By connecting to this signal, you can manually choose to tear down the connection from inside the connected slot before the handshake has completed. [...]".
Unfortunately, calling abort() doesn't update the socket state.
After emitting peerVerifyError(), QSslSocket attempts to determine whether the socket is still connected – or if the slot decided to tear down the connection.
Unfortunately, this check always returns ConnectedState – because abort()/close() do not update the state to UnconnectedState after tearing down the connection.
The result is that QSslSocket continues execution of QSslSocket::startHandshake() and, eventually calls continueHandshake(), which tries to dereference the 'SSL *' for the connection – which is now NULL.
Boom.