CVE-2026-23294

Yüksək

Təsvir

Linux kernel-də aşağıdakı zəiflik aradan qaldırılıb: bpf: PREEMPT_RT-də devmap-dəki yarış vəziyyətinin (race condition) düzəldilməsi PREEMPT_RT nüvələrində, hər bir CPU üçün ayrılmış xdp_dev_bulk_queue (bq)-ya eyni CPU-da çox sayda preemtiv tapşırıq tərəfindən eyni vaxtda daxil oluna bilər. Orijinal kod, preempsiyanın qarşısını almaq üçün local_bh_disable()-dan istifadə edərək, bq_enqueue() və __dev_flush() funksiyalarının eyni CPU-da bir-birinə nisbəten atomar şəkildə işlədiyini fərz edir. Lakin, PREEMPT_RT-də local_bh_disable() yalnız migrate_disable()-i çağırır (PREEMPT_RT_NEEDS_BH_LOCK təyin edilmədikdə) və preempsiyanı deaktiv etmir. Bu isə CFS planlaşdırıcısının bq_xmit_all() zamanı tapşırığı preempt etməsinə şərait yaradır və eyni CPU-dakı digər tapşırığın bq_enqueue()-a daxil 되어 eyni per-CPU bq üzərində eyni vaxtda əməliyyat aparmasına imkan verir. Bu, bir neçə yarış vəziyyətinə səbəb olur: 1. bq->q[] üzərində double-free / use-after-free: bq_xmit_all() cnt = bq->count kadrını götürür, sonra freymləri ötürmək üçün bq->q[0..cnt-1] massivini dövr edir. Əgər kadr götürüldükdən sonra preempsiya baş verərsə, ikinci tapşırıq eyni bq üzərində bq_enqueue() -> bq_xmit_all() çağıra və eyni freymləri ötürə (və azad edə) bilər. Birinci tapşırıq bərpa olunduqda, o, bq->q[]-dakı köhnəlmiş göstəricilərlə əməliyyat aparır ki, bu da use-after-free-yə səbəb olur. 2. bq->count və bq->q[] korrupsiyası: bq_xmit_all() onları oxuyarkən, paralel işləyən bq_enqueue() bq->count və bq->q[] dəyişiklikləri edir. 3. dev_rx/xdp_prog sökülməsi yarış vəziyyəti: __dev_flush() bq_xmit_all()-dən sonra bq->dev_rx və bq->xdp_prog-u təmizləyir. Əgər bq_xmit_all() geri döndükdən sonra və bq->dev_rx = NULL təyin edilməzdən əvvəl preempsiya baş verərsə, preemt edən bq_enqueue() dev_rx-in hələ də təyin edildiyini (non-NULL) görür, bq-ni flush_list-ə əlavə etməkdən imtina edir və freymi növbəyə əlavə edir. __dev_flush() bərpa olunduqda, o, dev_rx-i təmizləyir və bq-ni flush_list-dən çıxarır, nəticədə yeni əlavə edilmiş freym yetim qalır. 4. flush_node üzərində __list_del_clearprev(): cpumap yarışına bənzər şəkildə, hər iki tapşırıq eyni flush_node üzərində __list_del_clearprev()-i çağıra bilər və ikincisi artıq NULL təyin edilmiş prev göstəricisini dereference edir. Eyni CPU-da tapşırıq A (__dev_flush -> bq_xmit_all) və tapşırıq B (bq_enqueue -> bq_xmit_all) arasındakı yarış: Tapşırıq A (xdp_do_flush) Tapşırıq B (ndo_xdp_xmit redirect) ---------------------- -------------------------------- __dev_flush(flush_list) bq_xmit_all(bq) cnt = bq->count /* məsələn, 16 */ /* bq->q[] dövrü başlayır */ <-- CFS Tapşırıq A-nı preempt edir --> bq_enqueue(dev, xdpf) bq->count == DEV_MAP_BULK_SIZE bq_xmit_all(bq, 0) cnt = bq->count /* eyni 16! */ ndo_xdp_xmit(bq->q[]) /* freymlər drayver tərəfindən azad edildi */ bq->count = 0 <-- Tapşırıq A bərpa olunur --> ndo_xdp_xmit(bq->q[]) /* use-after-free: freymlər artıq azad edilib! */ Bu problem xdp_dev_bulk_queue-ya local_lock_t əlavə etməklə və onu bq_enqueue() və __dev_flush() funksiyalarında əldə etməklə həll edilir. Bu yollar artıq local_bh_disable() altında işləyir, buna görə də local_lock_nested_bh() istifadə olunur; bu, qeyri-RT sistemlərdə heç bir yük yaratmayan sadə annotasiyadır, PREEMPT_RT-də isə bq-ye girişi ardıcıllığa salan per-CPU yuxulma kilidi (sleeping lock) təmin edir.

CiddilikYüksək
CVSS7.0
İstismar ehtimalı—
MəhsulLinux Kernel
Dərc25 mar 2026
İlk görülmə25 mar 2026

Necə düzəltmək olar

Yeniləyin
  • linux linux_kernel6.18.17, 6.19.7 və ya daha yeni versiya

Təsirlənən məhsullar

MəhsulTəsirlənən versiyalarDüzəldildiyi versiya
linux linux_kernel6.18 ≤ v < 6.18.17, 6.19 ≤ v < 6.19.7, 7.06.18.17, 6.19.7

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-2026-23294 · Linux Kernel · Dark Radar