zlib is een van de weinige stukken C-code van derden binnen sgcWebSockets. Het is de motor achter de WebSocket-extensie permessage-deflate, dus elk gecomprimeerd frame dat uw server verstuurt of ontvangt gaat erdoorheen, en het verzorgt de HTTP-contentcodering. sgcOpenAPI deelt dezelfde broncode en gebruikt dus dezelfde kopie. Vanaf 2026.8.0 stapt die kopie over van zlib 1.2.12 naar zlib 1.3.1.
De wijziging is onzichtbaar in de API. Er hoeft niets in uw code aangepast te worden en het compressiegedrag blijft gelijk. Wat wel uitleg verdient, is waarom een versieverhoging van een kleine C-bibliotheek meer is dan het vervangen van een bestand, en wat we gedaan hebben om zeker te weten dat het veilig is op elke compiler die we ondersteunen.
Wat 1.3.1 oplost, en waarom u geen risico liep
De belangrijkste fix tussen 1.2.12 en 1.3.1 is CVE-2022-37434, een heap over-read in inflate(). Die is alleen bereikbaar wanneer de aanroepende applicatie aan zlib een gz_header doorgeeft waarvan het veld extra naar een buffer wijst. zlib kopieert dan het gzip extra field daarin, en in 1.2.12 ontbrak bij die kopie een grenscontrole.
sgcWebSockets voldeed nooit aan die voorwaarde. Het roept inflateGetHeader alleen aan met een op nul geïnitialiseerde gz_header, en het kent nooit een waarde toe aan head.extra, dus de betreffende tak kon niet bereikt worden. We hebben dit in de broncode gecontroleerd voordat we besloten wat te doen, en we zeggen het onomwonden: applicaties die met eerdere versies gebouwd zijn, waren via dit pad niet kwetsbaar.
We hebben toch bijgewerkt. Versienummers zijn wat geautomatiseerde scanners en leveranciersvragenlijsten lezen, geen call graphs, en een klant die een dependency scan draait zou onze redenering niet moeten hoeven reconstrueren om een bevinding af te sluiten. Bijwerken beëindigt het gesprek in plaats van het telkens opnieuw te moeten voeren.
Waarom zlib bijwerken geen bestandsvervanging is
zlib wordt in uw executable meegecompileerd in plaats van als DLL uitgeleverd, en daarom staat er bij een sgcWebSockets-applicatie geen zlib1.dll naast. Dat linken gebeurt met voorgecompileerde objectbestanden, en Delphi is kieskeurig over hun formaat. zlib bijwerken betekent dus die objectbestanden opnieuw bouwen, en er is niet één set maar zijn er drie.
| Gebruikt door | Formaat | Gebouwd met |
|---|---|---|
| Delphi 7 tot XE | OMF | bcc32, ZEXPORT=__fastcall |
| XE2 en later, Win32 | OMF | bcc32, ZEXPORT=__cdecl |
| XE2 en later, Win64 | COFF | MSVC cl |
De twee 32 bits sets verschillen in aanroepconventie, omdat de oudere compilers zlib linken met de Delphi register-conventie terwijl XE2 en later cdecl gebruiken. De 64 bits set heeft weer een ander objectformaat. Het is goed om op te merken dat bcc64 die niet kan produceren, omdat die ELF-objecten uitstoot terwijl de Delphi Win64-linker COFF wil, dus die set wordt met de Microsoft-compiler gebouwd.
Hier merkt u niets van. Het is simpelweg de reden waarom een zlib-verhoging een bouwoefening is en geen download.
Geverifieerd op elke compiler, niet alleen op de nieuwste
Opnieuw gebouwde objectbestanden kunnen schoon compileren en toch fout zijn, dus een linktest alleen is niet genoeg. Elke ondersteunde compiler is gebruikt om een programma te bouwen en vervolgens uit te voeren dat een buffer comprimeert, weer decomprimeert, byte voor byte vergelijkt, en verifieert dat de gelinkte objectbestanden de verwachte versie melden.
uses
sgcIdCTypes, sgcIdGlobal, sgcIdZLibHeaders;
var
vPackedLen: TIdC_ULONG;
begin
vPackedLen := SizeOf(vPacked);
if compress(PIdAnsiChar(@vPacked[0]), vPackedLen,
PIdAnsiChar(@vSrc[0]), SizeOf(vSrc)) <> 0 then
raise Exception.Create('compress failed');
WriteLn('zlib ', String(AnsiString(zlibVersion))); // zlib 1.3.1
end;
Dat draaide op Delphi 7, Delphi 2007, Delphi 2009 en RAD Studio XE6 tot en met 13, op Win32 en op Win64 waar dat platform bestaat. Alle 25 combinaties slagen en melden 1.3.1.
Een sluimerende 64 bits bug die onderweg opgelost werd
De matrix bracht iets aan het licht dat niets met de nieuwe versie te maken had. Op Delphi 10 Seattle kozen 64 bits builds de 32 bits objectbestanden, die niet in een 64 bits executable gelinkt kunnen worden en een Bad object file format-fout opleverden. De oorzaak was een oude conditie die bedoeld was om een Seattle-specifiek probleem te omzeilen, en die precies die ene combinatie naar de verkeerde set objectbestanden stuurde. Seattle 64 bits gebruikt nu dezelfde objectbestanden als elk ander 64 bits doel, en compileert.
sgcOpenAPI krijgt dezelfde update
sgcOpenAPI deelt zijn broncode met sgcWebSockets, zlib inbegrepen, dus het stapt in dezelfde release over naar 1.3.1 zonder aparte actie van uw kant.
Wat u moet doen
Installeer 2026.8.0 en bouw uw projecten opnieuw. Er is geen property in te stellen, geen unit toe te voegen of te verwijderen, en niets aan de distributie te wijzigen, omdat zlib al in uw executable zat en daar nog steeds zit. Houdt u een software bill of materials bij voor uw eigen product, werk dan de zlib-vermelding bij naar 1.3.1 en kunt u elke notitie over CVE-2022-37434 die u meedroeg laten vallen.
