CVE-2024-53079

Yüksək

Təsvir

Linux kernel-də aşağıdakı zəiflik aradan qaldırılmışdır: mm/thp: təxirə salınmış bölünmənin növbədən çıxarılması adlandırmasının və kilidləməsinin düzəldilməsi Son dəyişikliklər THP təxirə salınmış bölünmə növbələrinə daha çox yük qoyur: yükləmə altında uzun müddətdir mövcud olan yarış şəraitləri (race conditions) üzə çıxaraq list_del korruksiyalarına, "Bad page state" hallarına və daha pis nəticələrə səbəb olur (hər ikisində BUG-ları saxladığım üçün adətən bunların necə pis bitdiyini görmürəm). Müvafiq son dəyişikliklər bunlardır: 6.8 versiyasının mTHP-si, 6.10 versiyasının mTHP swapout funksiyası, 6.12 versiyasının mTHP swapin funksiyası, təkmilləşdirilmiş swap ayırması və az istifadə edilən THP bölünməsi. Kilidləməni düzəltməzdən əvvəl: large_rmappable-ı ləğv etməyən, lakin yanlış adlandırılan folio_undo_large_rmappable() funsiyasını onun həqiqətən yerinə yetirdiyi işə uyğun olaraq folio_unqueue_deferred_split() kimi yenidən adlandırın. Lakin bu funksiya və onun daxili __callee-si çox məhdud istifadəyə malik mm daxili elementləridir: istifadəni yoxlamaq üçün şərh və WARN_ON_ONCE-lər əlavə edin; həmçinin təxirə salınmış bölünmənin növbədən çıxarılıb-çıxarılmadığını bildirmək üçün bool qaytarın ki, bu daha sonra təhlükəsizlik yoxlamaları ətrafındakı WARN_ON_ONCE-lərdə istifadə edilə bilsin (beləliklə çağırıcıları __folio_unqueue_deferred_split() daxilindəki mürəkkəb şərtlərdən xilas etmiş oluruq). free_unref_folios() funksiyasından folio_unqueue_deferred_split()-i tamamilə çıxarın, çünki bütün çağırıcılar artıq onu öncədən çağırırlar (əgər kimsə bunu unudarsa, bad_page() bunu bildirəcək) - yalnız özü artıq heç bir çağırıcısı olmayan və ayrıca silinəcək put_pages_list() çağırıcısı istisna olmaqla. Swapout: mem_cgroup_swapout() funksiyası THP foliosunu təxirə salınmış bölünmə siyahısından yoxlamadan və növbədən çıxarmadan folio->memcg_data-nı 0-a sıfırlayırdı; bu təəssüf ki, belə idi, çünki split_queue_lock memcg-dən asılıdır (memcg aktiv olduqda); buna görə də swapout belə THP-ləri daha sonra, folionu boşaldarkən pgdat-ın kilidindən istifadə edərək növbədən çıxarırdı: bu isə potensial olaraq memcg siyahısını korlayırdı. __remove_mapping() burada refcount-u 0-da dondurduğu üçün memcg_data-nı sıfırlamazdan əvvəl folio_unqueue_deferred_split() çağırmaqda heç bir problem yoxdur. Bu, 5.4 versiyasının 87eaceb3faa5 ("mm: thp: make deferred split shrinker memcg aware") commit-inə geri gedir: həmin commit təxirə salınmış növbəyə əlavə etməzdən əvvəl swapcache-in yoxlanmasını ehtiva edirdi, lakin THP-ni swapcache-ə əlavə etməzdən əvvəl təxirə salınmış növbənin yoxlanması yox idi. Bu, reclaim prosesindəki adi hadisələr ardıcıllığı ilə yaxşı işləyirdi (baxmayaraq ki, təxirə salınmış növbədəki THP-nin swap-a çıxarıla biləcəyi bir neçə nadir yol var idi), lakin 6.12 versiyasının dafff3f4c850 ("mm: split underused THPs") commit-i reclaim zamanı az istifadə edilən THP-lərin bölünməsindən qaçır, bu isə təxirə salınmış növbədəki swapcache THP-lərini geniş yayılmış hala gətirir. Təxirə salınmış növbəyə əlavə etməzdən əvvəl swapcache yoxlamasını saxlayaq? Bəli: bu artıq vacib deyil, lakin mövcud davranışı qoruyub saxlayır və yəqin ki, faydalı optimallaşdırma olacaq (vmstat göstərdi ki, yoxlama silindikdə swapping yükü altında növbədə daha çox trafik olur); onun şərhini yeniləyin. Memcg-v1 köçürmə (köhnəlmiş): mem_cgroup_move_account() funksiyası, swapout-da olduğu kimi, THP foliosunu təxirə salınmış siyahıdan yoxlamadan və növbədən çıxarmadan folio->memcg_data-nı dəyişirdi və bəzən "from" memcg siyahısını korlayırdı. Burada Refcount sıfırdan fərqlidir, ona görə də folio_unqueue_deferred_split() yalnız düzəlişi təsdiqləmək üçün WARN_ON_ONCE-də istifadə edilə bilər, düzəliş isə daha əvvəl edilməlidir: mem_cgroup_move_charge_pte_range() əvvəlcə THP-ni bölməyə çalışır (bölünmə təbii ki, növbədən çıxarır) və ya uğursuz olduqda onu ötürür. İdeal deyil, lakin charge köçürülməsi tələb olunmuşdu və khugepaged daha sonra THP-ni bərpa etməlidir: heç kim sadəcə bu köhnəlmiş hal üçün yeni xüsusi növbədən çıxarma kodu istəmir. 87eaceb3faa5 commit-i bir təxirə salınmış siyahıdan digərinə köçürmək üçün kodu ehtiva edirdi (lakin refcount sıfırdan fərqli olduqda bunun təhlükəsiz olmadığını nəzərə almamışdı); lakin bu, 5.6 versiyasının fac0516b5534 ("mm: thp: don't need care deferred split queue in memcg charge move path") commit-i tərəfindən silindi, orada iddia edilirdi ki, PMD mapping-in mövcudluğu THP-nin təxirə salınmış siyahıda ola bilməyəcəyini zəmanət verir. Yuxarıda qeyd edildiyi kimi, bu nadir hallarda yanlış idi və indi isə tez-tez yanlış olur. 6.11 versiyasına backport edilməsi sadə olmalıdır. Daha erkən backport-larda digər _deferred_list düzəlişlərinin və asılılıqlarının daxil edildiyinə əmin olunmalıdır. Backport-lar üçün güclü bir səbəb yoxdur, lakin onlar kənar hallarını (cornercases) düzəldə bilər.

CiddilikYüksək
CVSS7.8
İstismar ehtimalı—
MəhsulLinux Kernel
Dərc19 noy 2024
İlk görülmə19 noy 2024
Zəiflik növüCWE-667CWE-667

Necə düzəltmək olar

Yeniləyin
  • linux linux_kernel6.6.62, 6.11.8 və ya daha yeni versiya

Təsirlənən məhsullar

MəhsulTəsirlənən versiyalarDüzəldildiyi versiya
linux linux_kernel5.4 ≤ v < 6.6.62, 6.7 ≤ v < 6.11.8, 6.126.6.62, 6.11.8

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.

Intelligence 360 paketində

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.

CVE-2024-53079 · Linux Kernel · Dark Radar