CVE-2021-47209
Təsvir
Linux kernelində aşağıdakı zəiflik həll edilmişdir: sched/fair: Ölü tapşırıq qruplarının cfs_rq-ları yenidən əldə etməsinin qarşısını alın Kevin update_blocked_averages() funksiyasında cfs_rq-nun istifadədən sonra azad edilməsinə (use-after-free) işarə edən çökmələr barədə məlumat verir. İlkin sazlama göstərdi ki, free_fair_sched_group() funksiyasında kfree() ilə azad edilmək üzrə olan tapşırıq qrupunda canlı cfs_rq-lar (on_list=1) mövcuddur. Lakin bunun necə baş verə biləcəyi aydın deyildi. Onun kernel konfiqurasiyası təsadüfən struct sched_entity-nin elə yerləşməsinə səbəb olmuşdu ki, 'my_q' üzvü birbaşa obyektin ortasına düşürdü və bu da təsadüfən SLUB-ın freelist göstəricisi ilə üst-üstə düşürdü. Bu, SLAB_FREELIST_HARDENED-in freelist göstəricisinin təhrif edilməsi ilə birlikdə #GP şəklində etibarlı giriş pozuntusuna səbəb oldu və UAF-ın tez aşkar olunmasına gətirib çıxardı. Görünür, Michal da eyni problemlə üzləşib[1]. O, artıq düzgün diaqnoz qoymuşdu ki, a7b359fc6a37 commit-i ("sched/fair: Correctly insert cfs_rq's to list on unthrottle") cfs_rq-ları artıq işləyən tapşırıqları olmayan tapşırıq qruplarına, yəni ölü olanlara da yenidən əlavə etməklə UAF üçün ilkin şərtlərin yaranmasına səbəb olur. Lakin onun təhlili əsl kök səbəbi qaçırır və bunu yalnız çökmə backtrace-indən görmək mümkün deyil, çünki əsl günahkar tg_unthrottle_up() funksiyasının əlverişsiz vaxtda timer kəsilməsi vasitəsilə sched_cfs_period_timer() tərəfindən çağırılmasıdır. unregister_fair_sched_group() ölməkdə olan tapşırıq qrupundan bütün cfs_rq-ları ayırdıqda, özünü kəsilmədən qorumur. Əgər timer kəsilməsi bütün CPU-lar üzərində iterasiya edərkən və ya unregister_fair_sched_group() bitdikdən sonra, lakin tapşırıq qrupu ayrılmazdan əvvəl baş verərsə, sched_cfs_period_timer() icra olunacaq və tapşırıq qruplarının siyahısını gəzərək cfs_rq-ları unthrottle etməyə, yəni onları ölməkdə olan tapşırıq qrupuna yenidən əlavə etməyə çalışacaq. Bunlar sonradan -- free_fair_sched_group() funksiyasında -- hələ də əlaqələndirilmiş halda kfree() ilə azad ediləcək və Kevin ilə Michalın gördüyü atəşfəşanlığa səbəb olacaq. Bu yarış vəziyyətini düzəltmək üçün ölməkdə olan tapşırıq qrupunun əvvəlcə ayrılmasını təmin etmək lazımdır. Lakin sadəcə qeydiyyatdan çıxarma və tapşırıq qrupunun ayrılması sırasını dəyişmək kifayət etmir, çünki paralel RCU gəzənləri hələ də onu görə bilər, aşağıdakı kimi: CPU1: CPU2: : timer IRQ: : do_sched_cfs_period_timer(): : : : distribute_cfs_runtime(): : rcu_read_lock(); : : : unthrottle_cfs_rq(): sched_offline_group(): : : walk_tg_tree_from(…,tg_unthrottle_up,…): list_del_rcu(&tg->list); : (1) : list_for_each_entry_rcu(child, &parent->children, siblings) : : (2) list_del_rcu(&tg->siblings); : : tg_unthrottle_up(): unregister_fair_sched_group(): struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; : : list_del_leaf_cfs_rq(tg->cfs_rq[cpu]); : : : : if (!cfs_rq_is_decayed(cfs_rq) || cfs_rq->nr_running) (3) : list_add_leaf_cfs_rq(cfs_rq); : : : : : : : : : ---kəsilmiş---
Necə düzəltmək olar
- linux linux_kernel5.15.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 | 5.13 ≤ v < 5.15.5 | 5.15.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.