CVE-2026-46223
Təsvir
Linux kernel-də aşağıdakı zəiflik aradan qaldırılmışdır: cgroup: rmdir zamanı css percpu_ref kill əməliyyatını cgroup boşalana qədər təxirə salın v7.0 versiyasına qədər uzanan commitlər zənciri, alt sistemin ->css_offline() funksiyasının tapşırıqlar hələ də cgroup-da kernel tərəfli işləri yerinə yetirdiyi müddətdə işləməməsi ilə bağlı kontroller invariantını təmin etmək üçün rmdir prosesini yenidən işləmişdir. [1] d245698d727a ("cgroup: Defer task cgroup unlink until after the task is done switching out") [2] a72f73c4dd9b ("cgroup: Don't expose dead tasks in cgroup") [3] 1b164b876c36 ("cgroup: Wait for dying tasks to leave on rmdir") [4] 4c56a8ac6869 ("cgroup: Fix cgroup_drain_dying() testing the wrong condition") [5] 13e786b64bd3 ("cgroup: Increment nr_dying_subsys_* from rmdir context") [1] nömrəli commit task cset unlink əməliyyatını do_exit()-dən finish_task_switch()-ə köçürmüşdür ki, tapşırığın cset bağlantısı yalnız tapşırıq planlaşdırmanı tam dayandırdıqdan sonra kəsilsin. Bu, exit_signals() mərhələsini keçmiş tapşırıqların son kontekst dəyişimi (context switch) baş verənə qədər cset->tasks-də qalmasına səbəb olmuşdur və bu da istifadəçi sahəsinin (userspace) rmdir-dən sonra görməyi gözlədiyi ilə kernelin gözləməli olduğu arasında fərqlilik yaradaraq bir sıra problemlərə yol açmışdır. [2]-[5] arasındakı commitlər bu uyğunsuzluğu aradan qaldırmağa çalışmışdır: [2] çıxan tapşırıqları cgroup.procs-dən filtrləmişdir; [3] rmdir(2)-ni onlar üçün TASK_UNINTERRUPTIBLE vəziyyətində gözlətmişdir; [4] gözləmə şərtini düzəltmişdir; [5] nr_dying_subsys_* dəyərinin sinxron şəkildə görünməsini təmin etmişdir. [3]-dəki cgroup_drain_dying() gözləməsi çıxılmaz vəziyyətə gətirdikləri üzrə yanlış idi. rmdir çağıran tərəf eyni zamanda pidns ləğvinə (teardown) mane olan zombi prosesin yığıcısı (reaper) olduqda (məsələn, host PID 1 systemd, həmin ləğv zamanı ona aid edilmiş yetim pid-ləri yığdıqda), rmdir həmin pid-lərin azad olmasını gözləyərək TASK_UNINTERRUPTIBLE vəziyyətində bloklanır; pid-lər isə azad ola bilmir, çünki PID 1 yığıcıdır və o, rmdir-də ilişib qalmışdır, nəticədə sistem A-A deadlock vəziyyətinə düşür. Daxili kilid ardıcıllığı bunu düzəltmir; problemin özü gözləmənin olmasıdır. Lakin orijinal yenidən sıralamanı stimullaşdıran css öldürmə tərəfi təmiz şəkildə asinxron edilə bilər: ->css_offline() artıq asinxrondur və percpu_ref_kill_and_confirm() tərəfindən idarə olunan css_killed_work_fn()-dən işə salınır. Həlli yolu həmin zəncirin yalnız bütün tapşırıqlar cgroup-u tərk etdikdən sonra başlamasını təmin etməkdir. Beləliklə, rmdir-in istifadəçiyə görünən tərəfi cgroup.procs və digərləri boşalan kimi geri dönür, halbuki ->css_offline() yalnız cgroup tamamilə boşaldıldıqdan sonra işləyir. Bu, orijinal reproducer (pidns teardown + zombie reaper, vng altında işləyir) vasitəsilə təsdiqlənmişdir (vanilla versiyanı dondurur, burada isə uğurludur), həmçinin [2], [3], [4], [5] üçün hər commit üzrə deterministik repro-larla yoxlanılmışdır; burada post-exit_signals() pəncərəsini genişləndirən boot parametri istifadə olunmuşdur ki, hər bir vəziyyət etibarlı şəkildə əlçatan olsun. Bunun üzərində bəzi stres testləri də aparılmışdır. cgroup_apply_control_disable() funksiyasında da oxşar mövcud yarış (race) problemi var: kontroler subtree_control vasitəsilə söndürüldükdə, exit_signals() mərhələsini keçmiş tapşırıqlar hələ də cgroup-un cset-lərinə bağlı ola bildiyi halda kill_css() sinxron şəkildə işləyirdi və ->css_offline() onlar boşalmamışdan əvvəl tetiklene bilirdi. Bu patch həmin çağırış nöqtəsində mövcud sinxron davranışı (ardıcıl kill_css_sync() + kill_css_finish()) qoruyub saxlayır və növbəti patch per-css trigger istifadə edərək orada kill_css_finish()-i təxirə salacaqdır. Bu, doğru yanaşma kimi görünür və mən bunda heç bir problem görmürəm. Dəyişikliklər müəyyən dərəcədə invazivdir, lakin həddindən artıq deyil, buna görə də -stable versiyalarına backport edilməsi uyğun olmalıdır. Əgər nəsə yanlış çıxarsa, alternativ variant bütün zənciri ([1]-[5]) geri qaytarmaq və bunun əvəzinə development budaqda yenidən işləməkdir. v2: queue_work() və work_fn ətrafında açıq cgroup_get()/cgroup_put() istifadə edərək təxirə salınmış məhv etmə işi boyunca cgrp pin edilmişdir. v1 əslində xarab deyildi (cgroup_task_dead()-dəki ordered cgroup_offline_wq + queue_work ardıcıllığı onu xilas edirdi), lakin açıq referans həmin qeyri-aşkar invariantlara asılılığı aradan qaldırır. Həmçinin təsvirdə mövcud olan cgroup_apply_control_disable() yarışına diqqət yetirin; növbəti patch orada kill_css_finish()-i təxirə salacaqdır.
Necə düzəltmək olar
- linux linux_kernel7.0, 7.0.9 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.19.12 ≤ v < 7.0, 7.0.1 ≤ v < 7.0.9, 7.0, 7.1 | 7.0, 7.0.9 |
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.