CVE-2021-47635
Açıklama
Linux çekirdeğinde aşağıdaki güvenlik açığı giderilmiştir: ubifs: Sayfa özel olarak ayarlandığında refcount ekleme düzeltmesi MM, bir sayfanın PG_private bayrağı ile ayarlanmış olması durumunda o sayfadaki refcount değerinin artırılması gerektiğini ve pageout(), migrate_page() gibi ana akışların, page_has_private() true döndürdüğünde bir ek sayfa referans sayısı olduğunu varsayacağını çok net bir şekilde tanımlamıştır [1]. Aksi takdirde, sayfa taşıma işleminde bir BUG oluşabilir: 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 Bu noktadan önce, grab_cache_page_write_begin() üzerinden alınan bir sayfada refcount'un ne anlama geldiği kavramını netleştirmeliyiz. İki durum vardır: Durum 1: refcount 3'tür, sayfa __page_cache_alloc tarafından oluşturulmuştur. TİP_A - yazma işlemi bu sayfayı kullanıyor TİP_B - sayfa, __add_to_page_cache_locked() çağrılarak belirli bir eşlemeye atanmıştır TİP_C - sayfa, lru_cache_add() çağrılarak mevcut CPU'ya karşılık gelen pagevec listesine eklenmiştir Durum 2: refcount 2'dir, sayfa eşlemenin ağacından alınmıştır TİP_B - sayfa belirli bir eşlemeye atanmıştır TİP_A - yazma işlemi bu sayfayı kullanıyor (page_cache_get_speculative() çağrısı ile) Dosya sistemi, xxx_write_end() içinde put_page() çağrısını yaparak bir refcount serbest bırakır; serbest bırakılan refcount TİP_A'ya (yazma görevi onu kullanıyor) karşılık gelir. Eğer bir sayfayı kullanan herhangi bir işlem varsa, sayfa taşıma işlemi expected_page_refs()'nin sayfa refcount değerine eşit olup olmadığını değerlendirerek sayfayı atlar. BUG şu süreçten kaynaklanmaktadır: 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 // sayfayı cpu 0'ın pagevec'ine koyar (refcnf = 3, sayfa oluşturma süreci için) ubifs_write_end SetPagePrivate(page_a) // sayfa sayısını artırmaz! 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'indeki tüm sayfaları gezer __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 alır (taşıma[1] + eşleme[1] + özel[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, özel bayrağını ayarladıktan sonra sayfa refcount değerini artırmaz; bu da sayfa taşıma görevinin sayfanın başka hiçbir işlem tarafından kullanılmadığını düşünmesine ve dolayısıyla sayfanın taşınmasına yol açar. Bu durum, diğer işlemler tarafından çağrılan put_page() (örneğin okuma işleminin lru_cache_add çağırması) ile sayfa taşıma işlemi tarafından çağrılan page_ref_unfreeze() arasında sayfa refcount üzerinde eşzamanlı erişime neden olur.
Nasıl düzeltilir
- linux linux_kernel5.10.110, 5.15.33, 5.16.19, 5.17.2 ya da sonraki bir sürüm
Etkilenen ürünler
| Ürün | Etkilenen sürümler | Düzeltildiği sürüm |
|---|---|---|
| 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 |
Sürümünüzü kontrol edin
Ürünü seçin ve kullandığınız sürümü yazın; sürümün etkilenen aralıkta olup olmadığını görün.
Attack Surface Management
Alan adlarınıza bağlı varlıkları, bu varlıklarda çalışan teknolojileri ve bilinen zafiyetleri tek listede görün.