Wie OpenSSL ordnungsgemäß deinitialisiert wird

8

In meinem OpenSSL-Client habe ich das Problem, dass ich genau in dem Moment, in dem ich Libeay32 und ssleay32 statisch anstelle von dynamisch verknüpfte, Unmengen von Speicherleckfehlern von Visual Leak Detector bekam. Ich kopierte die Befehle aus dem OP in diesem Thread , aber ich hatte noch 6 übrig. Dann fügte ich sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); hinzu, wie von 4LegsDrivenCat im selben Thread empfohlen, und nur 4 mehr waren übrig, die anscheinend mit dem Laden eines vertrauenswürdigen Zertifikats verwandt sind, das ich verwende, um mit dem Zertifikat des Servers zu vergleichen.

Ich benutze Visual Studio 2013 Express, OpenSSL 1.0.1L (beide 32 und 64 Bit), VLD 2.4RC2 und mein PC ist Windows 7 64 Bit.

Der folgende Callstack ist 64 Bit von VLD im abgesicherten Modus. In 32 Bit stürzte VLD im abgesicherten Modus ab (während es im schnellen Modus arbeitet, aber keinen ordentlichen Anrufstapel liefert). Ich entfernte die Teile des Callstacks, die sich auf meine eigenen Funktionen sowie die Hex-Daten bezogen.

%Vor%

bearbeiten: Ich habe die Lecks auf den Aufruf von SSL_CTX_load_verify_locations festgelegt. Weiß jemand, was ich bei Verwendung dieser Funktion deaktivieren muss? Wenn Sie nur diese Funktion kommentieren, verschwinden die Undichtigkeiten. Das liegt nicht an den Parametern, die ich an sie weitergebe.

    
Alex 24.04.2015, 10:48
quelle

2 Antworten

17
  

d: \ cfiles \ Projekte \ winssl \ openssl-1.0.1l \ crypto \ err \ err.c

Wenn man sich daran anhängt, sieht es so aus, als ob ein Fehlerzustand (oder Strings) frei sein muss.

  

Wie OpenSSL ordnungsgemäß deinitialisiert wird

Der Code zum Starten und Herunterfahren wird unten angezeigt (einschließlich FIPS). Wenn Sie beispielsweise DH-Parameter laden, müssen Sie sie ebenfalls bereinigen.

Dr. Henson war sehr hilfreich mit seinem Vorschlag, ERR_remove_state für jeden Thread aufzurufen. Siehe Reihenfolge der Bereinigung, um Speicherlecks zu vermeiden? auf der OpenSSL-Mailingliste.

>

Start

  • SSL_library_init();
  • SSL_load_error_strings();
  • FIPS_mode_set(1);
  • CRYPTO_set_id_callback(<fn>);
  • CRYPTO_set_locking_callback(<fn>);

Herunterfahren

  • FIPS_mode_set(0);
  • CRYPTO_set_locking_callback(NULL);
  • CRYPTO_set_id_callback(NULL);
  • ENGINE_cleanup();
  • CONF_modules_unload();
  • ERR_free_strings();
  • EVP_cleanup();
  • CRYPTO_cleanup_all_ex_data();

Und für jeden Thread:

  • ERR_remove_state();

Sie benötigen nur CRYPTO_set_id_callback und CRYPTO_set_locking_callback , wenn Ihr Programm multi-threaded ist. Weitere Informationen finden Sie in der Themenseite von Openssl .

Ich glaube, Sie können SSL_COMP_free_compression_methods in OpenSSL 1.0.2 und höher aufrufen. Dies betrifft einige der unten aufgeführten Beschwerden. Aber es ist nicht in OpenSSL 1.0.1 und darunter verfügbar.

  

SSL_COMP_get_compression_methods () ...

Ja, das verursacht ein Leck. Es ist gut bekannt und aufgrund ssl_comp_methods wird nur langsam zugewiesen, aber nie freigegeben. Siehe OpenSSL-Problem 2561: Speicherverlust mit integrierten SSL-Komprimierungen .

Einige der OpenSSL-Entwickler sind nicht der Meinung, dass es Zeit ist, sie zu beheben. Siehe Kleiner Speicherverlust auf Multithreadserver auf OpenSSL Mailingliste.

Das Folgende ist eine der Positionen des Entwicklers:

  

Eine feste Menge an Speicher, die nicht freigegeben wird und unabhängig von ist   Die Anzahl der ausgeführten Operationen ist KEIN Speicherverlust. Bibliotheken   Speicher für die Lebensdauer des Prozesses während einer Zeit zu reservieren   Initialisierung oder erstmalige Verwendung einer Funktion. Das ist normal.

     

Dies zu verfolgen ist eine Verschwendung von Zeit IMHO.

Und hier ist ein weiterer Thread über dieses spezielle Leck: Bevorzugte Methode, ssl_comp_methods freizugeben? . Und hier ist die Antwort desselben Entwicklers:

  

Warum ist jemand besessen davon, Speicher freizugeben, der statisch belegt ist?   Zeiger höchstens einmal. Es ist kein "Speicherleck" damit verbunden   Zuweisungen, da die Menge an zusätzlichem Speicher belegt ist.

Was er nicht realisiert hat, ist Java und .Net wird die Bibliothek während des Lebenszyklus eines Programms viele Male laden / entladen, so dass eine kleine Menge von "Who cares" unbegrenzt wachsen kann.

Als er über den alternativen Anwendungsfall informiert wurde, war hier seine Antwort. Ich denke, er schlägt vor, dass Oracle und Java ihre Sprachen neu gestalten. Oder verwenden Sie OpenSSL nicht in ihnen.

  

Das Entladen von gemeinsam genutzten Bibliotheken ist generell unsicher.

Hier war die Antwort eines der Leute, die eine Java VM pflegen:

  

Als Betreuer einer "alternativen" JavaVM kann ich das bestätigen   musste unbedingt das Entladen der Bibliothek unterstützen, weil ein Kunde war   es stark zu benutzen - und das war vor ein paar Jahren. Frühzeitige Sun VMs   Bibliotheksentladung wurde nicht unterstützt, aber auch diese VMs nicht   Müll-sammeln veraltete Klassen entweder.

Hier ein Abschnitt über das ssl_comp_methods Leck beheben.

In allen Fällen müssen Sie das unten beschriebene Patch hinzufügen.

Um ein Programm manuell zu erstellen, fügen Sie einfach eine Funktion mit dem Namen free_compressions (oder ähnlich) hinzu und rufen sie beim Herunterfahren wie alle anderen oben aufgeführten Methoden auf. Die Funktion muss exportiert werden.

Um es unter Linux automatisch zu machen, bedarf es einiger Tricks. Sie müssen eine GCC-Erweiterung verwenden: __attribute__ ((destructor)) .

%Vor%

Um es automatisch unter Windows zu tun, müssen Sie es in DllMain tun. Aber Sie müssen vorsichtig sein mit was Sie in DllMain tun und wie Sie es tun. Also vielleicht so etwas wie:

%Vor%

-----

  

Warum wird dieser Thread heruntergestimmt? Der Thread, den ich verlinkt habe, ist viel weniger detailliert und hat 10 upvotes (plus eins von mir). Bist du in den letzten Jahren viel strenger geworden?

Mit Blick auf den nahen Grund ( was Sie im Moment nicht tun können ), war die Schlussabstimmung mit dem Grund geworfen:

  

Fragen, die Debugging-Hilfe suchen ("Warum funktioniert dieser Code nicht?") muss das gewünschte Verhalten, ein spezifisches Problem oder einen Fehler und den kürzesten Code enthalten, der notwendig ist, um es in der Frage selbst zu reproduzieren.

Normalerweise gilt das. Aber in deinem Fall nicht; und es ist nicht leicht für diejenigen erkennbar, die mit dem Problem nicht vertraut sind. In der Tat könnten Sie ein einfaches Programm schreiben, das nur die Bibliothek initialisiert und dann unitialisiert und es wird wahrscheinlich undicht ...

Aus politischen Gründen kann die Website keine Regel erstellen "Geben Sie immer relevanten Code mit Ausnahme einiger OpenSSL-Speicherlecks an" (was effektiv ist, um Ihren Fall zu bearbeiten).

    
jww 28.04.2015, 18:56
quelle
4

Kleiner Zusatz zu jww , wenn Ihre OpenSSL-Version mit der zlib-Bibliothek erstellt wird, sollten Sie COMP_zlib_cleanup (); Abschnitt abschalten. Weil sein DSO-Modul nicht standardmäßig freigegeben wird. Der Code für den vollständigen Herunterfahren sollte also lauten:

%Vor%     
23W 23.10.2015 10:06
quelle