Organizacja Trifecta Tech Foundation, rozwijająca projekty takie jak ntpd-rs, sudo-rs, zlib-rs i bzip2-rs, ogłosiła przejście Firefoksa na użycie biblioteki zlib-rs do kompresji i dekompresji przy użyciu metody gzip. Oprócz ochrony przed problemami związanymi z błędami w zarządzaniu pamięcią, przejście z zlib na zlib-rs doprowadziło do zauważalnego wzrostu wydajności — w przeprowadzonych testach przyspieszenie wyniosło od 3,3 do 32,5 razy w przypadku pojedynczych operacji dekodowania oraz od 2,7 do 10,86 razy w przypadku dekodowania ciągłego strumienia.
Biblioteka zlib-rs była używana w wersji Firefoksa 151, ale po jej integracji niektórzy użytkownicy napotkali problem, który prowadził do awaryjnego zamknięcia z powodu przekroczenia dopuszczalnych granic. Zauważono, że w kodzie w języku Rust problem powodował awaryjne zatrzymanie, podczas gdy podobna sytuacja w C doprowadziłaby do niewidocznego uszkodzenia danych bez zatrzymywania działania. Jako rozwiązanie w wersji 151.0.1 powrócono do używania starej biblioteki zlib.
Pierwsze objawy problemu zauważono podczas testowania wczesnych wersji ponad rok temu, ale na systemach deweloperów nie udało się go odtworzyć. Ostatecznie, po roku testowania na użytkownikach wersji beta, zdecydowano się na aktywację zlib-rs w wersji Firefoksa 151. Po nowej serii zgłoszeń o problemach i analizie wzorców ustalono, że awaria została spowodowana błędem w mikroprogramie CPU Intel opartym na mikroarchitekturze Raptor Lake 13 i 14 generacji związanym z używaniem niewłaściwego rejestru.
Problem wystąpił, ponieważ generator kodu LLVM używał instrukcji "mov byte ptr [rsi + rdi + 1], ch" przy zapisywaniu w pamięci wyników kodowania Huffmana. Wykonanie tej instrukcji na CPU Raptor Lake powodowało, że zamiast 8-15 bitów z rejestru RCX, odpowiadających wskazanemu w instrukcji rejestrowi CH, do pamięci zapisywały się bity 0-7, odpowiadające rejestrowi CL. Podczas przygotowań do wersji Firefoksa 152 błąd został naprawiony obejściem, a łatka przeniesiona do głównego składu zlib-rs. Generacja problematycznej instrukcji została zauważona w LLVM 22 (w rozwijanej gałęzi LLVM 23 nie jest generowana).
Źródło: opennet.ru
