RefluXFS (CVE-2026-64600): root przez wyścig w XFS
Po serii błędów, które pisały tylko w pamięci, przychodzi RefluXFS, i ten zostawia ślad na dysku. To podatność typu local privilege escalation w jądrze Linuksa, oznaczona jako CVE-2026-64600 z oceną CVSS 7.8. Zwykły, nieuprzywilejowany użytkownik może przez nią nadpisać zawartość dowolnego czytelnego pliku na wolumenie XFS i w efekcie zdobyć roota. Co gorsza, siedzi w jądrze od 2017 roku, a klasyczne zabezpieczenia nic tu nie dają. Błąd znalazł zespół Qualys Threat Research Unit i opisał go 22 lipca.
Skąd nazwa i na czym polega błąd
Nazwa to gra słów: reflink plus XFS. Reflink to funkcja copy-on-write w XFS, dzięki której dwa pliki mogą współdzielić te same bloki fizyczne na dysku, dopóki jeden z nich nie zostanie zmieniony. Dopiero przy zapisie jądro robi kopię, alokuje nowy, prywatny blok i przełącza na niego plik. To standard w RHEL 8 i nowszych, gdzie reflink=1 jest ustawione domyślnie.
Problem to wyścig (race condition) na tej właśnie ścieżce copy-on-write. Gdy jądro musi zaalokować transakcję w logu XFS, na chwilę zwalnia blokadę i-węzła (ILOCK) i czeka na miejsce w logu. Po jej odzyskaniu popełnia błąd: sprawdza licznik referencji bloku pod starym, nieaktualnym adresem, zamiast ponownie odczytać aktualne mapowanie pliku. W tym krótkim oknie wszystko może się zmienić.
Jak wygląda atak
Wyścig ustawia się dwoma równoległymi zapisami O_DIRECT w ten sam współdzielony blok:
- Plik A współdzieli blok fizyczny P z innym plikiem (refcount = 2).
- Atakujący wysyła dwa równoległe zapisy
O_DIRECTw ten sam offset pliku A. - Pierwszy zapisujący wchodzi w copy-on-write i żeby zaalokować transakcję, zrzuca ILOCK.
- W tym oknie drugi zapisujący kończy pełny cykl CoW: przemapowuje A na nowy blok i zbija licznik referencji P do jednego.
- Pierwszy zapisujący odzyskuje blokadę, sprawdza licznik pod starym adresem P, widzi jeden i uznaje blok za prywatny.
- Pisze
O_DIRECTprosto w blok P, z pominięciem page cache. A blok P wciąż stoi pod oryginalnym plikiem, więc dane atakującego lądują na dysku, w cudzym pliku.
Mając prymityw „nadpisz dowolny czytelny plik", eskalacja jest prosta: wystarczy podmienić coś, co root i tak uruchomi z pełnymi uprawnieniami, na przykład skrypt crona, plik wykonywalny albo konfigurację. Od tego momentu jest root.
Dlaczego to takie groźne
Kilka rzeczy składa się na wyjątkowo paskudny profil:
- Zapis idzie na dysk, nie do pamięci.
O_DIRECTomija page cache, więc zmiana jest trwała i przetrwa restart. To odwrotność świeżej rodziny DirtyClone, gdzie modyfikacja żyła tylko w page cache. - Zero egzotycznych wymagań. Nie trzeba przestrzeni nazw użytkownika, żadnych dodatkowych capabilities, żadnej niestandardowej konfiguracji. Wystarczy lokalne konto, wolumen XFS z reflinkiem i zapisywalny katalog obok czytelnego celu.
- Hardening nie pomaga. KASLR, SMEP, SMAP, lockdown jądra, profile seccomp, granice kontenerów, nic z tego nie blokuje tej ścieżki. Podatność działa również przy SELinux w trybie Enforcing.
- Cisza w logach. Wykorzystanie nie zostawia wpisów w logu jądra.
Jedyny plus dla obrońcy jest taki, że skoro zmiana ląduje na dysku, to narzędzia kontroli integralności plików (AIDE, Tripwire, sumy kontrolne) po fakcie ją zauważą. Szkoda tylko, że po fakcie.
Kogo to dotyczy
Praktycznie każdego, kto trzyma dane na XFS z włączonym reflinkiem, a to domyślna konfiguracja w całej rodzinie Red Hata: RHEL 8/9/10, CentOS Stream, Oracle Linux, Rocky, AlmaLinux, CloudLinux, Amazon Linux 2023, Fedora. Qualys szacuje ponad 16 milionów podatnych systemów. Szczególnie narażone są maszyny wielodostępne: serwery z wieloma kontami, hosty kontenerów, środowiska CI.
Jak się bronić
Najważniejsze: zaktualizuj jądro i zrestartuj system. Poprawka trafiła do mainline 16 lipca (commit 2f4acd0, „xfs: resample the data fork mapping after cycling ILOCK"). Łatka robi dokładnie to, czego brakowało: po odzyskaniu ILOCK ponownie próbkuje mapowanie pliku, zamiast ufać staremu adresowi bloku. Dystrybucje wypuściły załatane jądra tego samego dnia co ujawnienie.
Z mitygacjami jest gorzej niż zwykle, bo praktycznie ich nie ma:
- Wyłączenie reflinka działa tylko przy tworzeniu systemu plików (
mkfs.xfs -m reflink=0). Na istniejącym wolumenie nie przełączysz tego w locie, więc dla działających maszyn to nie jest opcja. - Red Hat udostępnił doraźny skrypt SystemTap, ale to obejście tymczasowe, wymaga ręcznego wgrania i nie przeżywa restartu.
Krótko: tej podatności nie da się obejść konfiguracją ani odizolować. Realnym rozwiązaniem jest świeże jądro i reboot.
Kalendarium
- 2017 (Linux 4.11, commit
3c68d44a2b49): błąd trafia do jądra wraz z obsługą reflinka - 16 lipca 2026: poprawka scalona do mainline (commit
2f4acd0) - 22 lipca 2026: publiczne ujawnienie (Qualys, oss-security) i errata dystrybucji
Ciekawostka
RefluXFS jest o tyle nietypowy, że Qualys znalazł go z pomocą modelu AI, któremu zadano konkretne zadanie: poszukać w jądrze błędu w stylu klasycznego Dirty COW. Efektem jest właśnie ten wyścig w XFS. Niezależnie od tego, jak go znaleziono, poprawka jest zwykłą, klasyczną łatką na logikę blokowania.
Wniosek
RefluXFS przypomina, że współdzielenie bloków między plikami to potężna funkcja, ale każdy moment, w którym jądro na chwilę puszcza blokadę, to potencjalne okno na wyścig. Jedna pominięta ponowna weryfikacja mapowania wystarczyła, żeby zamienić dwa niewinne zapisy w nadpisanie cudzego pliku na dysku. Jeśli trzymasz dane na XFS w środowisku wielodostępnym, potraktuj to priorytetowo: zaktualizuj jądro i zrestartuj, bo tutaj nie ma drogi na skróty.
Źródła: Qualys Threat Research, Qualys Advisory, oss-security, Red Hat, The Hacker News