Skip to content

Commit 9ace1f9

Browse files
authored
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 nitely/nim-hyperx#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.
1 parent 1d32607 commit 9ace1f9

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

lib/pure/asyncnet.nim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ proc newAsyncSocket*(domain, sockType, protocol: cint,
207207
Protocol(protocol), buffered, inheritable)
208208

209209
when defineSsl:
210+
proc raiseSslHandleError =
211+
raiseSSLError("The SSL Handle is closed/unset")
212+
210213
proc getSslError(socket: AsyncSocket, err: cint): cint =
211214
assert socket.isSsl
212215
assert err < 0
@@ -227,6 +230,8 @@ when defineSsl:
227230

228231
proc sendPendingSslData(socket: AsyncSocket,
229232
flags: set[SocketFlag]) {.async.} =
233+
if socket.sslHandle == nil:
234+
raiseSslHandleError()
230235
let len = bioCtrlPending(socket.bioOut)
231236
if len > 0:
232237
var data = newString(len)
@@ -246,6 +251,8 @@ when defineSsl:
246251
await sendPendingSslData(socket, flags)
247252
of SSL_ERROR_WANT_READ:
248253
var data = await recv(socket.fd.AsyncFD, BufferSize, flags)
254+
if socket.sslHandle == nil:
255+
raiseSslHandleError()
249256
let length = len(data)
250257
if length > 0:
251258
let ret = bioWrite(socket.bioIn, cast[cstring](addr data[0]), length.cint)
@@ -262,6 +269,8 @@ when defineSsl:
262269
op: untyped) =
263270
var opResult {.inject.} = -1.cint
264271
while opResult < 0:
272+
if socket.sslHandle == nil:
273+
raiseSslHandleError()
265274
ErrClearError()
266275
# Call the desired operation.
267276
opResult = op
@@ -306,6 +315,8 @@ proc connect*(socket: AsyncSocket, address: string, port: Port) {.async.} =
306315
await connect(socket.fd.AsyncFD, address, port, socket.domain)
307316
if socket.isSsl:
308317
when defineSsl:
318+
if socket.sslHandle == nil:
319+
raiseSslHandleError()
309320
if not isIpAddress(address):
310321
# Set the SNI address for this connection. This call can fail if
311322
# we're not using TLSv1+.
@@ -727,6 +738,8 @@ proc close*(socket: AsyncSocket) =
727738
defer:
728739
socket.fd.AsyncFD.closeSocket()
729740
socket.closed = true # TODO: Add extra debugging checks for this.
741+
when defineSsl:
742+
socket.sslHandle = nil
730743
731744
when defineSsl:
732745
if socket.isSsl:

0 commit comments

Comments
 (0)