mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
Fix SIGSEGV when closing SSL async socket while sending/receiving (#24795)
Async SSL socket SIGSEGV's sometimes when calling socket.close() while
send/recv. The issue was found here
https://github.com/nitely/nim-hyperx/pull/59.
Possibly related: #24024
This can occur when closing the socket while sending or receiving,
because `socket.sslHandle` is freed. The sigsegv can also occur on calls
that require `socket.bioIn` or `socket.bioOut` because those use
`socket.sslHandle` internally. This PR checks sslHandle is set before
doing any operation that requires it.
(cherry picked from commit 9ace1f97ac)
This commit is contained in:
committed by
narimiran
parent
4d41384f09
commit
e799d2fca0
@@ -207,6 +207,9 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
|
||||
Protocol(protocol), buffered, inheritable)
|
||||
|
||||
when defineSsl:
|
||||
proc raiseSslHandleError =
|
||||
raiseSSLError("The SSL Handle is closed/unset")
|
||||
|
||||
proc getSslError(socket: AsyncSocket, err: cint): cint =
|
||||
assert socket.isSsl
|
||||
assert err < 0
|
||||
@@ -227,6 +230,8 @@ when defineSsl:
|
||||
|
||||
proc sendPendingSslData(socket: AsyncSocket,
|
||||
flags: set[SocketFlag]) {.async.} =
|
||||
if socket.sslHandle == nil:
|
||||
raiseSslHandleError()
|
||||
let len = bioCtrlPending(socket.bioOut)
|
||||
if len > 0:
|
||||
var data = newString(len)
|
||||
@@ -246,6 +251,8 @@ when defineSsl:
|
||||
await sendPendingSslData(socket, flags)
|
||||
of SSL_ERROR_WANT_READ:
|
||||
var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
|
||||
if socket.sslHandle == nil:
|
||||
raiseSslHandleError()
|
||||
let length = len(data)
|
||||
if length > 0:
|
||||
let ret = bioWrite(socket.bioIn, cast[cstring](addr data[0]), length.cint)
|
||||
@@ -262,6 +269,8 @@ when defineSsl:
|
||||
op: untyped) =
|
||||
var opResult {.inject.} = -1.cint
|
||||
while opResult < 0:
|
||||
if socket.sslHandle == nil:
|
||||
raiseSslHandleError()
|
||||
ErrClearError()
|
||||
# Call the desired operation.
|
||||
opResult = op
|
||||
@@ -306,6 +315,8 @@ proc connect*(socket: AsyncSocket, address: string, port: Port) {.async.} =
|
||||
await connect(socket.fd.AsyncFD, address, port, socket.domain)
|
||||
if socket.isSsl:
|
||||
when defineSsl:
|
||||
if socket.sslHandle == nil:
|
||||
raiseSslHandleError()
|
||||
if not isIpAddress(address):
|
||||
# Set the SNI address for this connection. This call can fail if
|
||||
# we're not using TLSv1+.
|
||||
@@ -727,6 +738,8 @@ proc close*(socket: AsyncSocket) =
|
||||
defer:
|
||||
socket.fd.AsyncFD.closeSocket()
|
||||
socket.closed = true # TODO: Add extra debugging checks for this.
|
||||
when defineSsl:
|
||||
socket.sslHandle = nil
|
||||
|
||||
when defineSsl:
|
||||
if socket.isSsl:
|
||||
|
||||
Reference in New Issue
Block a user