CVE-2026-98974
>_ Opis
Tłumaczenie automatyczne – może zawierać nieścisłości.
W jądrze Linuksa usunięto następującą lukę:
xfs: napraw wymianę zakresu wymiany na rozmiar pliku eof
Norbert Szetei zamieścił łatkę zawierającą niekompletny opis m.in
błąd we fladze TO_EOF XFS_IOC_EXCHANGE_RANGE. Sztuczki z błędami
Exchange-range do modyfikowania pliku tak, aby miał wspólne bloki
zaczynając od EOF, co nigdy nie jest dozwolone, ponieważ pliki nigdy tego nie robiły
zapisane dane poza EOF i możesz udostępniać tylko zapisane bloki danych.
To jest klucz do wszystkich nieprawidłowych zachowań, które po nich nastąpią.
W końcu dostałem od Norberta opis tego, co się dzieje:
> Uczciwe. Tutaj jest z fizycznymi numerami bloków, 4k bloków. peer to plik
> zostaje przepisany, a plik 1 jest tym, który kończy się flagą
> wyczyszczone.
>
> Start, nic nie zostało udostępnione:
>
> rozmiar równorzędny 4096 -> [100]
> rozmiar pliku 1 12288 -> [200] [201] [202]
> dawca1 rozmiar 4096 -> [300]
> dawca2 rozmiar 4096 -> [400]
>
> 1. Blok peera FICLONERANGE w środkowym slocie pliku 1:
>
> rozmiar równorzędny 4096 -> [100]
> rozmiar pliku 1 12288 -> [200] [100] [202] ustawiona flaga łącza zwrotnego
> ^^^^^ oba pliki mają własny blok 100
>
> 2. XFS_IOC_EXCHANGE_RANGE plik1 względem dawcy1, file1_offset 0,
> file2_offset 8192, długość 0, TO_EOF. Jeden blok jest wymieniany i rozmiary
> są z nim wymieniane:
>
> plik1 rozmiar 4096 -> [200] [100] [300] ustawiona flaga reflinku
> ^^^^^^^^^^^^ nadal w posiadaniu, ale rozmiar już przekroczył
> dawca1 rozmiar 12288 -> [202]
>
> plik1 mówi, że ma długość jednego bloku, podczas gdy nadal posiada trzy. Nic nie było
> niemapowane. file2_offset to blok 2, więc ta wymiana nie może wyczyścić flagi.
>
> 3. XFS_IOC_EXCHANGE_RANGE plik 1 względem dawcy2, oba przesunięcia 0, długość 4096.
> Według i_disk_size są to dwa jednoblokowe pliki wymieniające wszystko, więc
> xmi_can_exchange_reflink_flags() zgadza się i flaga zostaje wyczyszczona:
>
> plik1 rozmiar 4096 -> [400] [100] [300] flaga reflink WYCZYSZCZONA
> dawca2 rozmiar 4096 -> [200]
>
> Blok 100 jest nadal współdzielony z peerami.
>
> 4. pwrite(file1, 4096, 4096), czyli drugie miejsce pliku 1, blok 100.
> xfs_is_cow_inode(file1) ma wartość false, więc nie ma CoW:
>
> rozmiar równorzędny 4096 -> [100] ten sam blok, nowa zawartość
>
> Tylko blok 100 się tu liczy. PoC poniżej, odczytuje plik
> wywołany peer w bieżącym katalogu. System plików wymaga reflinku i
> zakres wymiany, który mkfs.xfs 7.x domyślnie włącza.
Więc tak, TO_EOF psuje rozmiar pliku, nawet jeśli tak jest w rzeczywistości
prawidłowo wymieniając blok danych. Poniżej przedstawiono zamierzone
zachowanie XFS_EXCHANGE_RANGE_TO_EOF, zgodnie z opisem na jego stronie podręcznika:
„Zignoruj parametr długości. Wszystkie bajty w pliku1_fd z pliku1_offset
do EOF są przenoszone do pliku2_fd, a rozmiar pliku2 jest ustawiany na
(plik2_offset+(plik1_długość-plik1_przesunięcie)). Tymczasem wszystkie bajty w
plik2 z przesunięcia_pliku2 do EOF są przenoszone do pliku1, a rozmiar pliku1 wynosi
ustaw na (file1_offset+(file2_length-file2_offset)).”
Innymi słowy, jeśli wymienimy tylko część danych pliku, to
powinien wymieniać tylko część rozmiaru pliku związaną z
wymieniane dane. Niestety, kod zamienia rozmiar pliku ondisk i
rozmiary plików incore, co jest nieprawidłowe, jeśli obiekt wywołujący przekazuje plik a
niezerowe przesunięcie.
Po pomieszaniu rozmiarów plików PoC korzysta z drugiego zakresu wymiany
wywołaj coś, co wygląda na plik jednoblokowy bez reflinku. Ponieważ
rozmiar pliku jest ustawiony niepoprawnie, zakres wymiany myśli, że wymienia
pełną zawartość dwóch plików i usuwa flagę linku zwrotnego na uszkodzonym
plik. Umożliwia to rozszerzony zapis uszkodzonego pliku w celu przepisania pliku
wspólny blok, który znajduje się tuż za EOF. Stało się to znane potocznie
jako refluks.
Po prawidłowym ustawieniu rozmiarów plików, drugi zakres wymiany nr
już myśli, że dokonuje wymiany pełnej zawartości, więc nie zostanie wyczyszczony
flagę reflink na którymkolwiek z argumentów pliku.
Norbert kontynuował poprzednią wersję tej łatki, dodając drugą
skarga dotycząca nieprawidłowej obsługi stanu i_disk_size:
> Przesunięcia są ograniczane względem incore i_size, ale od niego odejmowane
>
---obcięty---
>_ Referencje
Dane podatności pochodzą z oficjalnych źródeł (CVE® List / NVD). Opisy po polsku są tłumaczone automatycznie i mogą zawierać nieścisłości – na stronie rekordu można wyświetlić wersję angielską.
This product uses the NVD API but is not endorsed or certified by the NVD.
Copyright © 1999–2026, The MITRE Corporation. CVE is a registered trademark and the CVE logo is a registered trademark of The MITRE Corporation.
CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE®). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy. ALL DOCUMENTS AND THE INFORMATION CONTAINED THEREIN PROVIDED BY MITRE ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
NVD Terms of Use / CVE® Terms of Use / nvd.nist.gov / cve.org