Skip to content

Commit 1dd31de

Browse files
committed
Fixes issues with dynamic loading OpenSSL. Fixes #13903.
This fixes at least a couple of issues: * Procs loaded from the DLL being used even when the pointer is nil. * The actual issue (#13903) which appeared to cause stack corruption on Android 7.1.1 with OpenSSL 1.1.1f. The change that fixed this was the move to loading the procs in `sslSym`.
1 parent c835c8c commit 1dd31de

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

lib/wrappers/openssl.nim

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
244244
# and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2
245245
# SSLv23_method(), SSLv23_server_method(), SSLv23_client_method() are removed in 1.1.0
246246

247-
when compileOption("dynlibOverride", "ssl"):
247+
when compileOption("dynlibOverride", "ssl") or defined(noOpenSSLHacks):
248248
# Static linking
249249

250250
when defined(openssl10):
@@ -285,28 +285,39 @@ else:
285285
proc thisModule(): LibHandle {.inline.} =
286286
var thisMod {.global.}: LibHandle
287287
if thisMod.isNil: thisMod = loadLib()
288+
288289
result = thisMod
289290

290291
proc sslModule(): LibHandle {.inline.} =
291292
var sslMod {.global.}: LibHandle
292293
if sslMod.isNil: sslMod = loadLibPattern(DLLSSLName)
294+
293295
result = sslMod
294296

295-
proc sslSym(name: string): pointer =
296-
var dl = thisModule()
297-
if not dl.isNil:
298-
result = symAddr(dl, name)
297+
proc sslSym(name: string, alternativeName = ""): pointer =
298+
# Load from DLL.
299+
var sslDynlib = sslModule()
300+
if not sslDynlib.isNil:
301+
result = symAddr(sslDynlib, name)
302+
if result.isNil and alternativeName.len > 0:
303+
result = symAddr(sslDynlib, alternativeName)
304+
305+
# Attempt to load from current exe.
299306
if result.isNil:
300-
dl = sslModule()
301-
if not dl.isNil:
302-
result = symAddr(dl, name)
307+
let thisDynlib = thisModule()
308+
if thisDynlib.isNil: raiseInvalidLibrary(name)
309+
result = symAddr(thisDynlib, name)
310+
if result.isNil and alternativeName.len > 0:
311+
result = symAddr(sslDynlib, alternativeName)
303312

304313
proc loadPSSLMethod(method1, method2: string): PSSL_METHOD =
305314
## Load <method1> from OpenSSL if available, otherwise <method2>
306-
let m1 = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method1))
307-
if not m1.isNil:
308-
return m1()
309-
cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method2))()
315+
let methodSym = sslSym(method1, method2)
316+
if methodSym.isNil:
317+
raise newException(LibraryError, "Could not load " & method1 & " nor " & method2)
318+
else:
319+
let method2Proc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](methodSym)
320+
return method2Proc()
310321

311322
proc SSL_library_init*(): cint {.discardable.} =
312323
## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
@@ -325,7 +336,7 @@ else:
325336
loadPSSLMethod("SSLv23_client_method", "TLS_client_method")
326337

327338
proc SSLv23_method*(): PSSL_METHOD =
328-
loadPSSLMethod("SSLv23_method", "TLS_method")
339+
result = loadPSSLMethod("SSLv23_method", "TLS_method")
329340

330341
proc SSLv2_method*(): PSSL_METHOD =
331342
loadPSSLMethod("SSLv2_method", "TLS_method")

0 commit comments

Comments
 (0)