Search code examples
delphiindydelphi-xe7indy10delphi-10-seattle

Delphi XE7/10 Seattle DataSnap OpenSSL Access Violation on finalization


After adding a call to an https website in our DataSnap TCP server, it started crashing on finalization.

The crash is on Data.DBXOpenSSL.pas more specifically on this method:

class procedure TRSACypher.ClearKey(var AKey: PRSAPeer);
begin
  if AKey <> nil then
    IPPeerProcs._RSA_free(AKey); // Crash here
  AKey := nil;
end;

The exception is:

First chance exception at $00000000. Exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'. Process Project1.exe (3996)

I wrote a project which reproduces the problem and it crashes on both XE7 and Delphi 10 Seattle, the project is hosted here:

https://gist.github.com/fabioxgn/aaaddb5aa65db5d17202

What the project does is simple:

  • Make a GET call using OpenSSL to https://google.com
  • Starts the DataSnap server
  • Opens and then closes a single connection to this DataSnap server

A few points:

  • If don't make the https call, everything works fine
  • This only happens with the RSA filter enabled, if I remove the filter it doesn't crash

Any clues about what is making this crash? I tried debbuging but this code uses a lot of IPPeerFactory and I couldn't find the final code which is run.

Edit

I've opened a report and they confirmed it as a bug: https://quality.embarcadero.com/browse/RSP-12495


Solution

  • From what Embarcadero R&D team found out, the problem is that Indy is finalized before Data.DBXOpenSSL. When Indy is finalized, it nils the function pointers to all OpenSSL methods. When Data.DBXOpenSSL is finalized it executes code which tries to use a function pointer that is now nil.

    As a temporary work around, it is possible to avoid the error and change the initialization and finalization sequences by making the Indy abstraction unit as the first unit in the uses clause (IPPeerClient on the client side, IPPeerServer on the server side) of a project.