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.
Attachments
For Gerrit Dashboard: QTBUG-53906 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
161935,7 | QSslSocket (OpenSSL) - handle abort/close on sslErrors emitted | 5.6 | qt/qtbase | Status: MERGED | +2 | 0 |
162518,9 | QSslSocket::transmit (macOS/iOS) - do not use invalid context | 5.6 | qt/qtbase | Status: MERGED | +2 | 0 |