CVE-2021-47635
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılıb: ubifs: Səhifə private təyin edildikdən sonra refcount-un əlavə edilməsi üçün düzəliş MM qaydasını [1] çox aydın şəkildə müəyyən etmişdir ki, səhifəyə PG_private bayrağı təyin edildikdən sonra həmin səhifədə refcount artırılmalıdır; həmçinin pageout(), migrate_page() kimi əsas axınlar, əgər page_has_private() true qaytararsa, bir əlavə səhifə istinad sayının olduğunu fərz edəcəkdir. Əks halda, səhifə miqrasiyasında BUG baş verə bilər: page:0000000080d05b9d refcount:-1 mapcount:0 mapping:000000005f4d82a8 index:0xe2 pfn:0x14c12 aops:ubifs_file_address_operations [ubifs] ino:8f1 dentry name:"f30e" flags: 0x1fffff80002405(locked|uptodate|owner_priv_1|private|node=0| zone=1|lastcpupid=0x1fffff) page dumped because: VM_BUG_ON_PAGE(page_count(page) != 0) ------------[ cut here ]------------ kernel BUG at include/linux/page_ref.h:184! invalid opcode: 0000 [#1] SMP CPU: 3 PID: 38 Comm: kcompactd0 Not tainted 5.15.0-rc5 RIP: 0010:migrate_page_move_mapping+0xac3/0xe70 Call Trace: ubifs_migrate_page+0x22/0xc0 [ubifs] move_to_new_page+0xb4/0x600 migrate_pages+0x1523/0x1cc0 compact_zone+0x8c5/0x14b0 kcompactd+0x2bc/0x560 kthread+0x18c/0x1e0 ret_from_fork+0x1f/0x30 Bundan əvvəl, grab_cache_page_write_begin() funksiyasından alınan səhifədə refcount-un nə məna verdiyi konsepsiyasını dəqiqləşdirməliyik. Burada 2 vəziyyət var: Vəziyyət 1: refcount 3-dür, səhifə __page_cache_alloc tərəfindən yaradılıb. TYPE_A - yazı prosesi bu səhifədən istifadə edir TYPE_B - səhifə __add_to_page_cache_locked() çağırılaraq konkret bir mapping-ə təyin edilib TYPE_C - səhifə lru_cache_add() çağırılaraq cari CPU-ya uyğun pagevec siyahısına əlavə edilib Vəziyyət 2: refcount 2-dir, səhifə mapping ağacından alınıb TYPE_B - səhifə konkret bir mapping-ə təyin edilib TYPE_A - yazı prosesi bu səhifədən istifadə edir (page_cache_get_speculative() çağıraraq) Fayl sistemi xxx_write_end() funksiyasında put_page() çağıraraq bir refcount-u azaldır, azaldılan refcount TYPE_A-ya (yazı tapşırığı ondan istifadə edir) uyğundur. Əgər səhifədən istifadə edən hər hansı proses varsa, səhifə miqrasiyası prosesi expected_page_refs()-in səhifə refcount-una bərabər olub-olmadığını yoxlayaraq həmin səhifəni ötürəcəkdir. BUG aşağıdakı proses səbəbindən baş verir: PA(cpu 0) kcompactd(cpu 1) compact_zone ubifs_write_begin page_a = grab_cache_page_write_begin add_to_page_cache_lru lru_cache_add pagevec_add // səhifəni cpu 0-ın pagevec-inə yerləşdirir (refcnf = 3, səhifənin yaradılması prosesi üçün) ubifs_write_end SetPagePrivate(page_a) // səhifə sayını artırmır! unlock_page(page_a) put_page(page_a) // refcnt = 2 [...] PB(cpu 0) filemap_read filemap_get_pages add_to_page_cache_lru lru_cache_add __pagevec_lru_add // cpu 0-ın pagevec-indəki bütün səhifələri gəzir __pagevec_lru_add_fn SetPageLRU(page_a) isolate_migratepages isolate_migratepages_block get_page_unless_zero(page_a) // refcnt = 3 list_add(page_a, from_list) migrate_pages(from_list) __unmap_and_move move_to_new_page ubifs_migrate_page(page_a) migrate_page_move_mapping expected_page_refs 3 olur (migration[1] + mapping[1] + private[1]) release_pages put_page_testzero(page_a) // refcnt = 3 page_ref_freeze // refcnt = 0 page_ref_dec_and_test(0 - 1 = -1) page_ref_unfreeze VM_BUG_ON_PAGE(-1 != 0, page) UBIFS private bayrağını təyin etdikdən sonra səhifə refcount-unu artırmır, bu da səhifə miqrasiyası tapşırığının səhifənin digər proseslər tərəfindən istifadə edilmədiyini düşünməsinə və beləliklə səhifənin miqrasiya olunmasına səbəb olur. Bu, digər proses tərəfindən çağırılan put_page() (məsələn, oxuma prosesi lru_cache_add çağırır) və miqrasiya tərəfindən çağırılan page_ref_unfreeze() arasında səhifə refcount-una eyni vaxtda müraciətə səbəb olur.
Necə düzəltmək olar
- linux linux_kernel5.10.110, 5.15.33, 5.16.19, 5.17.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 | 2.6.27 ≤ v < 5.10.110, 5.11 ≤ v < 5.15.33, 5.16 ≤ v < 5.16.19, 5.17 ≤ v < 5.17.2 | 5.10.110, 5.15.33, 5.16.19, 5.17.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.