WpisyCVE-2026-31431 (Copy Fail): Jak Appbox ograniczył ryzyko

CVE-2026-31431 (Copy Fail): Jak Appbox ograniczył ryzyko

5 min czytania
przez rid

W zeszłym tygodniu ujawniono poważną lukę w kernelu Linux, CVE-2026-31431. Oto jak Appbox ograniczył jej skutki i wdrożył poprawkę kernela Debian.

CVE-2026-31431 (Copy Fail) - Jak ograniczyliśmy ryzyko

W zeszłym tygodniu ujawniono poważną lokalną eskalację uprawnień w kernelu Linux: CVE-2026-31431, nazywaną "Copy Fail". Dotyczy szerokiego zakresu wersji kernela w nowoczesnych dystrybucjach Linux, a publiczny exploit pojawił się krótko po ujawnieniu.

Chcę jasno powiedzieć, co się stało, co to oznacza dla Appbox i co z tym zrobiliśmy. Krótka wersja: dzięki temu, jak zbudowane są nasze kontenery, aplikacje działające z remapowaniem przestrzeni nazw użytkowników były już chronione przed przekształceniem tego błędu w host root, nawet zanim wdrożyliśmy spatchowane kernele. Wczoraj (May 4, 2026) przeprowadziliśmy też awaryjną konserwację, aby zaktualizować każdy serwer do spatchowanego kernela, więc błąd został już całkowicie usunięty z naszej floty.

Czym jest "Copy Fail"?

CVE-2026-31431 to luka w kryptograficznym API kernela AF_ALG. Poprzez przypięcie się do konkretnego szyfru (authencesn(hmac(sha256),cbc(aes))) i nadużycie sposobu, w jaki kernel wplata strony do bufora roboczego, nieuprzywilejowany lokalny użytkownik może zapisywać dowolne 4-bajtowe fragmenty bezpośrednio do page cache plików, których nie powinien móc modyfikować - w tym binariów SUID, takich jak /usr/bin/su.

Gdy kopia su w page cache zostanie nadpisana małym złośliwym ELF-em, następne uruchomienie wykonuje kod atakującego jako UID 0. Koniec gry dla hosta.

Jeśli interesują Cię techniczne szczegóły (deasemblacja shellcode, ślady syscalli i cała reszta), świetny jest opis Andrei Veriego: CVE-2026-31431: Copy Fail vs. rootless containers. Wykonał też pracę pokazującą - z dowodami eBPF i uid_map - dokładnie to, o czym zaraz powiemy: przestrzenie nazw użytkowników neutralizują ten exploit.

Dlaczego aplikacje Appbox były już chronione

Exploit polega na tym, że setuid(0) faktycznie nadaje root hosta. W kontenerze uruchomionym z włączonymi user namespaces tak się nie dzieje.

Przestrzenie nazw użytkowników mapują przestrzeń UID kontenera na inny (nieuprzywilejowany) zakres UID na hoście. Gdy więc exploit powiedzie się wewnątrz kontenera i setuid(0) zwróci sukces, wynikowa powłoka "root" jest mapowana na zwykłego nieuprzywilejowanego użytkownika hosta - nie prawdziwego roota. Shellcode działa, prompt zmienia się na #, ale na hoście:

podman     27943  0.0  0.0   2984  2028 pts/1    S+   22:15   0:00 sleep 100

I tyle. Brak dostępu do plików hosta, brak /etc/shadow, brak root hosta. Granica przestrzeni nazw kontenera zatrzymuje przejście do ucieczki na poziom host-root.

Na poziomie platformy każdy Appbox otrzymuje własny daemon Docker uruchomiony z włączonym remapowaniem przestrzeni nazw użytkowników. W pseudokodzie wygląda to mniej więcej tak:

start_docker_daemon(
  userns_remap = appbox_id,
  container_namespace = appbox_id
)

To mapowanie jest oparte na dedykowanym podrzędnym zakresie UID/GID na hoście:

write "/etc/subuid" -> "<appbox-id>:<host-subuid-start>:65536"
write "/etc/subgid" -> "<appbox-id>:<host-subgid-start>:65536"

Oprócz tego definicje aplikacji nadal mogą jawnie nadpisywać UsernsMode, gdy aplikacja wymaga specjalnej obsługi:

container_config = {
  userns_mode: app.userns_mode,
  network_mode: app.network_mode,
  ...
}

Dokładny opis brzmi więc tak: remapowanie przestrzeni nazw użytkowników jest częścią domyślnej konfiguracji platformy, a wyjątki per aplikacja są jawne. Istnieje niewielka liczba aplikacji, które potrzebują innych ustawień, ponieważ udostępniają funkcje wymagające dodatkowych capabilities, i te przypadki są obsługiwane oddzielnie.

Innymi słowy: dla aplikacji działających w normalnej konfiguracji z remapowaniem Copy Fail nie mógł zamienić kompromitacji kontenera w root hosta.

Co i tak chcieliśmy naprawić

Przestrzenie nazw użytkowników zatrzymują ucieczkę na hosta, ale nie sprawiają, że błąd znika wewnątrz kontenera. Atakujący nadal mógłby eskalować do "container root" w granicach aplikacji, co, choć ograniczone, nadal jest złym stanem higieny bezpieczeństwa. Sam kernel był podatny i chcieliśmy to usunąć.

Gdy dowiedzieliśmy się o błędzie, natychmiast zaczęliśmy oceniać naszą ekspozycję. Mimo że remapowanie przestrzeni nazw użytkowników już blokowało stronę problemu związaną z ucieczką na hosta dla naszej normalnej konfiguracji aplikacji, nadal chcieliśmy jak najszybciej usunąć bazową lukę w kernelu.

Co zrobiliśmy wczoraj

W niedzielę wieczorem zaplanowaliśmy awaryjną konserwację na Monday, May 4, 2026, najwcześniejsze okno, w którym mogliśmy wdrożyć aktualizację kernela w całej flocie.

Podczas okna:

  • Każdy host został zaktualizowany przy użyciu oficjalnych pakietów kernela Debian zawierających poprawkę "Copy Fail".
  • Cel był prosty: całkowicie usunąć podatną ścieżkę kernela, a nie tylko polegać na naszej istniejącej izolacji przestrzeni nazw.

Konserwacja jest zakończona. Każdy host Appbox działa teraz na spatchowanym kernelu.

Co to oznacza dla Ciebie

  • Nie musiałeś nic robić. Twoje aplikacje nadal działały, a ewentualne krótkie zakłócenia podczas okna konserwacyjnego były jedynym efektem widocznym dla klientów.
  • Nawet przed wczorajszą poprawką remapowanie przestrzeni nazw użytkowników oznaczało, że ten błąd nie mógł zamienić normalnej kompromitacji aplikacji w root hosta. Właśnie do takich scenariuszy istnieje ten model izolacji.
  • Na przyszłość nasza polityka pozostaje bez zmian: przestrzenie nazw użytkowników pozostają domyślnie włączone, a bardzo nieliczne wyjątki przechodzą dodatkowy przegląd bezpieczeństwa.

Szerszy obraz

To jedna z tych CVE, w których nagłówek ("lokalna eskalacja uprawnień, publiczny exploit, dotknięty każdy nowoczesny kernel") brzmi katastrofalnie, i dla wielu środowisk współdzielonych naprawdę taki był. Powód, dla którego nie było to katastrofalne dla nas, jest ten sam, dla którego lata temu podjęliśmy decyzje architektoniczne czasem kosztujące nas trochę kompatybilności: uruchamiamy aplikacje z zasadą najmniejszych uprawnień wbudowaną w warstwę kontenerów, a nie doklejoną po fakcie.

Defence in depth naprawdę działa. Błąd w warstwie kernela? Zatrzymała go warstwa przestrzeni nazw. Błąd w warstwie przestrzeni nazw? Obniżanie capabilities i seccomp zatrzymują większość reszty. Nie udajemy, że pojedyncza warstwa jest idealna, po prostu dbamy o to, żeby zawsze istniała kolejna.

Jeśli masz pytania w tej sprawie albo dotyczące konfiguracji konkretnych aplikacji, skontaktuj się z nami.


Masz pytania? Skontaktuj się z nami pod adresem support@appbox.co albo otwórz zgłoszenie na billing.appbox.co.

rid

rid

Software Engineer | Writer | Designer