CVE-2024-57976
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılıb: btrfs: cow_file_range() uğursuz olduqda folio təmizləməsinin düzgün yerinə yetirilməsi [SƏHV] COW düzəlişi BUG_ON() olaraq qeyd edilib sınaqdan keçirilərkən (bu, yeni pin_user_pages*() dəyişikliyi ilə bağlıdır və yeni kənar çirkli səhifələrin yaranmasına səbəb olmamalıdır), COW düzəliş yoluna daxil olmaqla BUG_ON()-ın tetiklediyi sistem çökməsi baş verdi. Bu BUG_ON() uğursuz btrfs_run_delalloc_range() funksiyasından dərhal sonra baş verir: BTRFS error (device dm-2): failed to run delalloc range, root 348 ino 405 folio 65536 submit_bitmap 6-15 start 90112 len 106496: -28 ------------[ cut here ]------------ kernel BUG at fs/btrfs/extent_io.c:1444! Internal error: Oops - BUG: 00000000f2000800 [#1] SMP CPU: 0 UID: 0 PID: 434621 Comm: kworker/u24:8 Tainted: G OE 6.12.0-rc7-custom+ #86 Hardware name: QEMU KVM Virtual Machine, BIOS unknown 2/2/2022 Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs] pc : extent_writepage_io+0x2d4/0x308 [btrfs] lr : extent_writepage_io+0x2d4/0x308 [btrfs] Call trace: extent_writepage_io+0x2d4/0x308 [btrfs] extent_writepage+0x218/0x330 [btrfs] extent_write_cache_pages+0x1d4/0x4b0 [btrfs] btrfs_writepages+0x94/0x150 [btrfs] do_writepages+0x74/0x190 filemap_fdatawrite_wbc+0x88/0xc8 start_delalloc_inodes+0x180/0x3b0 [btrfs] btrfs_start_delalloc_roots+0x174/0x280 [btrfs] shrink_delalloc+0x114/0x280 [btrfs] flush_space+0x250/0x2f8 [btrfs] btrfs_async_reclaim_data_space+0x180/0x228 [btrfs] process_one_work+0x164/0x408 worker_thread+0x25c/0x388 kthread+0x100/0x118 ret_from_fork+0x10/0x20 Code: aa1403e1 9402f3ef aa1403e0 9402f36f (d4210000) ---[ end trace 0000000000000000 ]--- [SƏBƏB] Həmin uğursuzluq əsasən cow_file_range() funksiyasından qaynaqlanır, burada biz -ENOSPC xətası ilə qarşılaşa bilərik. -ENOSPC artıq bizim sahə rezervasiya kodu ilə bağlı bir xəta olsa da, gəlin yalnız xətanın idarə edilməsinə diqqət yetirək. Məsələn, 4K sektor ölçüsü və 4K səhifə ölçüsü ilə bir inode-un [0, 64K) diapazonunda aşağıdakı çirkli sahəyə malik olduğumuzu təsəvvür edək: 0 16K 32K 48K 64K |///////////////////////////////////////| |#######################################| Burada |///| səhifələrin hələ də çirkli olduğunu, |###| isə extent io ağacının EXTENT_DELALLOC bayrağına malik olduğunu bildirir. - Səhifə 0 üçün extent_writepage() funksiyasına daxil olunur. - [0, 64K) diapazonu üçün btrfs_run_delalloc_range() funksiyasına daxil olunur. - [0, 64K) diapazonu üçün cow_file_range() funksiyasına daxil olunur. - btrfs_reserve_extent() funksiyası yalnız bir 16K extent rezerv etdi. Beləliklə, [0, 16K) diapazonu üçün extent xəritəsi yaratdıq və extent-i sıraladıq. 0 16K 32K 48K 64K |////////|//////////////////////////////| |<- OE ->|##############################| Və [0, 16K) diapazonunun delalloc bayrağı sıfırlandı. Lakin hələ heç bir bio göndərmədiyimiz üçün aidiyyatı 4 səhifə hələ də çirkli qalır. - btrfs_reserve_extent() funksiyası -ENOSPC ilə geri dönür. İndi biz bütün EXTENT_DELALLOC* bayraqlarını və qalan diapazonlar üçün çirkli bayraqları sıfırlayacaq xəta təmizləmə prosesini həyata keçirməliyik: 0 16K 32K 48K 64K |////////| | | | | Qeyd edin ki, [0, 16K) diapazonunun səhifələri hələ də çirkli qalır. - Bir müddət sonra, səhifə diapazonu hələ də çirkli bayraqlara malik olduğu üçün [0, 16K) diapazonu üçün yenidən writeback tetiklənir. - EXTENT_DELALLOC bayrağı olmadığı üçün btrfs_run_delalloc_range() heç bir işlem görməyəcək. - extent_writepage_io() səhifə 0-da sıralama bayrağının olmadığını aşkar edir. Bu, COW düzəliş yoluna yönəldir və BUG_ON()-ı tetikləyir. Təəssüf ki, bu xəta idarəetmə problemi btrfs-in ilk tətbiqinə qədər uzanır. Xoşbəxtlikdən, COW düzəlişinin istifadəsi sayəsində, ən azı bu, nüvənin (kernel) çökməsinə səbəb olmayacaq. [DÜZƏLİŞ] Extent və folio-ları dərhal kiliddən açmaq əvəzinə, ya xəta baş verənə qədər, ya da bütün delalloc diapazonu tamamlanana qədər onları kilidli saxlayırıq. Bütün delalloc diapazonu xətasız tamamlandıqda, biz sadəcə bütün diapazonu PAGE_SET_ORDERED (və !keep_locked hallarında PAGE_UNLOCK) ilə kiliddən açırıq.
Necə düzəltmək olar
- linux linux_kernel6.12.36, 6.13.2 və ya daha yeni versiya
Təsirlənən məhsullar
| Məhsul | Təsirlənən versiyalar | Düzəldildiyi versiya |
|---|---|---|
| linux linux_kernel | v < 6.12.36, 6.13 ≤ v < 6.13.2 | 6.12.36, 6.13.2 |
Versiyanızı yoxlayın
Məhsulu seçin və istifadə etdiyiniz versiyanı yazın; versiyanın təsirlənən aralıqda olub-olmadığını görün.
Attack Surface Management
Domenlərinizə bağlı aktivləri, onlarda işləyən texnologiyaları və məlum zəiflikləri bir siyahıda görün.