CVE-2026-90131
WysokieCVSS 7.1Prawdopodobieństwo exploitacji (EPSS)
Niskie ryzykoPercentyl 4 - wyżej niż 4% wszystkich znanych CVE
Streszczenie
W jądrze Linux w module NTFS funkcja ntfs_read_iomap_begin_resident() odczytuje rekord MFT bez blokady ni->mrec_lock, podczas gdy inne funkcje modyfikują ten sam bufor pod tą blokadą. Prowadzi to do wyścigu danych (data race) i możliwości odczytu niespójnych wartości pól długości i przesunięcia atrybutów. Problem został rozwiązany przez utrzymanie blokady mrec_lock od początku odczytu rezydentnego iomap aż do iomap_end().
Ocena ryzyka
Wyścig danych może powodować uszkodzenie lub błędny odczyt danych na systemach plików NTFS, co w skrajnych przypadkach prowadzi do niestabilności jądra lub błędów aplikacji. Ryzyko występuje głównie w scenariuszach równoczesnego odczytu (mmap) i operacji link()/unlink() na tym samym pliku.
Rekomendacja
Zaktualizuj jądro Linux do wersji zawierającej poprawkę dla CVE-2026-90131. Jeśli aktualizacja nie jest możliwa, unikaj równoczesnych operacji link()/unlink() na plikach NTFS podczas ich odczytu przez mmap.
Inne podatności w Linux kernel NTFS
Zobacz wszystkie- CVE-2026-89614Krytyczne
W jądrze Linux sterownik ntfs ogranicza skanowanie bitmapy wolnych klastrów na podstawie rozmiaru $Bitmap, a nie liczby klastrów wolumenu. Obraz z $Bitmap obejmującą więcej klastrów niż wolumen pozwala na indeksowanie poza tablicą lcn_empty_bits_per_page.
- CVE-2026-89613Krytyczne
W jądrze Linux sterownik ntfs nie odrzuca atrybutów z pustymi mapping pairs, jeśli mają niespójne highest VCN i rozmiar. Brak walidacji może prowadzić do nieprawidłowego przetwarzania.
- CVE-2026-89612Krytyczne
W jądrze Linux funkcja parse_ntfs_boot_sector() dekoduje 64-bitowe LCN sektora rozruchowego NTFS do typu s64. Spreparowana wartość z wysokim bitem staje się ujemna i przechodzi sprawdzenie górnej granicy, co prowadzi do dostępu poza granicami tablicy lcn_empty_bits_per_page.
- CVE-2026-89611Krytyczne
W jądrze Linux funkcja ntfs_attr_update_meta() nie waliduje przesunięcia nazwy atrybutu podczas konwersji między atrybutami niesparsowanymi i sparowanymi. Złośliwy rekord MFT może ustawić name_offset tak, że nazwa wykracza poza granice atrybutu lub nakłada się na mapping pairs.
- CVE-2026-98141Średnie
W jądrze Linux w funkcji update_reparse_data() sterownika ntfs ignorowana jest wartość zwracana przez set_reparse_index(). Gdy wstawienie indeksu się nie powiedzie, kod usuwa zapisane dane reparse jako sprzątanie, ale nadal zwraca 0, więc symlink(2) zgłasza sukces mimo braku danych reparse na dysku.
- CVE-2026-98140Średnie
W jądrze Linux funkcja write_mft_record_nolock() sterownika ntfs mapuje folio rekordu MFT za pomocą kmap_local_folio(), ale ścieżki błędów pre_write_mst_fixup() i bio_add_folio() skaczą do etykiety błędu bez odmapowania. Ponieważ mapowania kmap_local są uporządkowane stosowo per zadanie, wyciek jednego psuje zagnieżdżenie dla zewnętrznych mapowań.
- CVE-2026-98139Średnie
W jądrze Linux funkcja ntfs_cluster_free_from_rl_nolock() sterownika ntfs dodaje długość zakresu do nr_freed zawsze gdy warunek księgowania błędów jest fałszywy, co obejmuje przypadki, w których ntfs_bitmap_clear_run() faktycznie zawiodło. Ponieważ nieudane ntfs_bitmap_clear_run() wycofuje częściowe modyfikacje, żadne bity nie zostały wyczyszczone, a mimo to długość zakresu zawyża vol->free_clusters.
- CVE-2026-98138Średnie
W jądrze Linux funkcja ntfs_sync_fs() sterownika ntfs bezwarunkowo czyści bit dirty, podczas gdy ntfs_put_super() i ścieżka ponownego montowania tylko do odczytu robią to tylko gdy NVolErrors(vol) jest fałszywe. W efekcie każde sync() na wolumenie z zapisanym błędem oznacza wolumen jako czysty, przez co nie jest przeprowadzane odzyskiwanie.
- CVE-2026-98137Średnie
W jądrze Linux funkcja ntfs_dio_zero_range() sterownika ntfs zwraca 0 lub ujemny errno z blkdev_issue_zeroout(), nigdy wartości dodatniej. Sprawdzenie błędu zerowania w ntfs_attr_fallocate() nigdy się więc nie uruchamiało, przez co nieudana operacja zerowania była po cichu ignorowana, a nowo przydzielone klastry były wliczane do initialized_size.
- CVE-2026-98136Wysokie
W jądrze Linux funkcja ntfs_attr_find_in_attrdef() sterownika ntfs przechodzi przez tablicę $AttrDef w pamięci, ale warunek pętli ogranicza tylko początek każdego wpisu, nie cały wpis. Wolumen którego rozmiar danych $AttrDef jest mniejszy niż jeden wpis (np. 120 bajtów) powoduje odczyt poza alokacją podczas tworzenia pliku.
Oryginalny opis (angielski, źródło NVD)
In the Linux kernel, the following vulnerability has been resolved: ntfs: serialize resident iomap reads with mrec_lock ntfs_read_iomap_begin_resident() walks the MFT record through ntfs_attr_lookup() -> ntfs_attr_find() without taking ni->mrec_lock, while ntfs_attr_record_resize(), ntfs_make_room_for_attr() and ntfs_resident_attr_record_add() memmove() the same base_ni->mrec buffer under that lock. map_mft_record() only takes a reference and does not serialize, so the reader can observe torn attribute length and offset fields while a writer is relocating the records. KCSAN reports the race between the mmap read fault path and both link() and unlink(): BUG: KCSAN: data-race in ntfs_attr_find / ntfs_attr_record_resize write to 0xffff888100af1018 of 4 bytes by task 96 on cpu 1: ntfs_attr_record_resize+0xd2/0x130 ntfs_attr_record_rm+0xad/0x530 ntfs_delete+0x224/0x640 ntfs_unlink+0x14d/0x280 vfs_unlink+0x157/0x520 read to 0xffff888100af1018 of 4 bytes by task 95 on cpu 0: ntfs_attr_find+0x104/0x5b0 ntfs_attr_lookup+0x39c/0x10c0 ntfs_read_iomap_begin_resident+0xc6/0x230 ntfs_read_iomap_begin+0x5d/0xa0 iomap_iter+0x2e2/0x6e0 iomap_read_folio+0x147/0x2a0 ntfs_read_folio+0x108/0x170 filemap_read_folio+0x35/0x100 filemap_fault+0x993/0x1000 value changed: 0x00000250 -> 0x000001f0 The address is mrec + 0x18, i.e. mft_record.bytes_in_use, and the change is the 96 bytes of one $FILE_NAME attribute being removed. Keep base_ni->mrec_lock from the resident read iomap lookup through iomap_end(). This protects both the attribute walk and the subsequent copy from iomap->inline_data, which points into the MFT record. The non-resident path is left alone: ntfs_lookup() already holds the directory inode's mrec_lock when it reads an index folio through read_mapping_folio(), and taking the lock in the shared wrapper deadlocks there with recursive locking on mrec_lock. The comment above the read_mapping_folio() call in fs/ntfs/dir.c notes the same hazard. The seek path uses the same lookup helper but does not dereference iomap->inline_data. Release the lock before returning from that path, whereas the regular read path records base_ni in iomap->private and releases the lock from its iomap_end() callback. Tested with a reproducer that faults in a 16-byte resident file while another thread runs link()/unlink() on it. Before: 40 KCSAN reports in about one second. After: no reports in 180 seconds over 206,090 read iterations and 423,540 link/unlink cycles. A PROVE_LOCKING build shows no lockdep splat with the same reproducer running for 60 seconds.
Dane podatności pochodzą z NVD (NIST) · CISA KEV · EPSS

