CVE-2025-37821
Təsvir
Linux nüvəsində aşağıdakı zəiflik aradan qaldırılıb: sched/eevdf: se->slice dəyərinin U64_MAX olaraq təyin edilməsi və nəticədə baş verən çökmənin düzəldilməsi dequeue_entities() funksiyasında sched_entity-nin slice dəyərini U64_MAX edə bilən bir kod yolu mövcuddur ki, bu da bəzən sistemin çökməsinə səbəb olur. Sözügedən hal, dequeue_entities() gecikdirilmiş qrup obyektini növbədən çıxarmaq üçün çağırıldıqda və daha sonra həmin obyektin valideyninin növbədən çıxarılması gecikdirildikdə baş verir. Bu halda: 1. dequeue_entities() əvvəlindəki if (entity_is_task(se)) else blokunda slice dəyəri cfs_rq_min_slice(group_cfs_rq(se)) olaraq təyin edilir. Əgər obyekt gecikdirilibsə, onun növbədə gözləyən tapşırıqları yoxdur, buna görə də cfs_rq_min_slice() U64_MAX qaytarır. 2. Birinci for_each_sched_entity() dövrü obyekti növbədən çıxarır. 3. Əgər obyekt valideyninin yeganə övladı idisə, növbəti iterasiya valideyni növbədən çıxarmağa çalışır. 4. Valideynin növbədən çıxarılması gecikdirilməlidirsə, birinci for_each_sched_entity() dövründən _slice dəyərini yeniləmədən_ çıxılır. 5. İkinci for_each_sched_entity() dövrü valideynin ->slice dəyərini saxlanılmış slice ilə təyin edir ki, bu hələ də U64_MAX-dır. Bu, sonrakı hesablamaları pozur və potensial olaraq fəlakətli nəticələrə yol açır. Production mühitində müşahidə etdiyimiz təzahür belə idi: 6. update_entity_lag() funksiyasında limit-i hesablamaq üçün se->slice istifadə olunur və nəticədə çox böyük mənfi ədəd alınır. 7. limit dəyəri se->vlag = clamp(vlag, -limit, limit) ifadəsində istifadə olunur. Limit mənfi olduğu üçün vlag > limit olur və se->vlag eyni böyük mənfi ədədə təyin edilir. 8. place_entity() funksiyasında se->vlag miqyası dəyişdirilir, bu isə daşmaya (overflow) səbəb olur və digər böyük (müsbət və ya mənfi) ədəd yaranır. 9. Tənzimlənmiş ləngimə se->vruntime-dan çıxılır, bu da se->vruntime-ı böyük bir ədəd qədər artırır və ya azaldır. 10. pick_eevdf() funksiyası entity_eligible()/vruntime_eligible() funksiyalarını çağırır; vruntime növbədəki digər vruntimelərdən çox uzaq olduğu üçün onlar yanlış şəkildə false qaytarır və bu da (vruntime - cfs_rq->min_vruntime) * load hesablamasının daşmasına səbəb olur. 11. Heç bir element uyğun görünmür, ona görə də pick_eevdf() NULL qaytarır. 12. pick_next_entity() funksiyası pick_eevdf()-ın qaytardığı dəyəri istinad etməyə çalışır və sistem çökür. drgn vasitəsilə core dump-lardan cfs_rq vəziyyətlərinin çıxarılması, xarakterik böyük vruntime diapazonlarını və saxta vlag dəyərlərini göstərdi. Həmçinin canlı sistemlərdə se->slice-ın U64_MAX olaraq təyin edildiyini izlədim (bu adətən "zərərsiz" idi, çünki çökmə üçün iş növbəsinin qalan hissəsinin xüsusi bir vəziyyətdə olması lazım idi). Problem, slice dəyərinin həmişə boş olmayan ilk cfs_rq-dan təyin edilməsi ilə dequeue_entities() funksiyasında düzəldildi.
Necə düzəltmək olar
- linux linux_kernel6.12.29, 6.14.5 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 | 6.12 ≤ v < 6.12.29, 6.13 ≤ v < 6.14.5, 6.15 | 6.12.29, 6.14.5 |
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.