CVE-2026-23342 in Linuxالمعلومات

الملخص

بحسب VulDB • 13/06/2026

في نواة لينكس، تم حل الثغرة التالية:

bpf: إصلاح حالة سباق (Race Condition) في cpumap على أنظمة PREEMPT_RT

على kernels التي تعمل بنظام PREEMPT_RT، يمكن الوصول إلى xdp_bulk_queue الخاص بكل وحدة معالجة مركزية (per-CPU bq) بشكل متزامن من قبل مهام متعددة قابلة للإيقاف المؤقت (preemptible tasks) على نفس المعالج.

يفترض الكود الأصلي أن دالتي `bq_enqueue()` و `__cpu_map_flush()` تعملان ذرياً (atomically) بالنسبة لبعضهما البعض على نفس وحدة المعالجة المركزية، معتمدين في ذلك على `local_bh_disable()` لمنع الإيقاف المؤقت للمهام. ومع ذلك، على PREEMPT_RT، تقتصر وظيفة `local_bh_disable()` على استدعاء `migrate_disable()` فقط (عندما لا يكون `PREEMPT_RT_NEEDS_BH_LOCK` مضبوطاً) ولا تقوم بإيقاف الإيقاف المؤقت للمهام، مما يسمح لنظام جدولة CFS بإيقاف مهمة مؤقتاً أثناء تنفيذ `bq_flush_to_queue()`، وبالتالي تمكين مهمة أخرى على نفس المعالج من الدخول إلى `bq_enqueue()` والتعامل مع نفس bq الخاص بكل وحدة معالجة مركزية بشكل متزامن.

يؤدي هذا إلى عدة حالات سباق (races):

1. استدعاء مزدوج لـ `__list_del_clearprev()`: بعد إعادة تعيين قيمة `bq->count` في دالة `bq_flush_to_queue()`، يمكن لمهمة تم إيقافها مؤقتاً أن تستدعي `bq_enqueue()` -> `bq_flush_to_queue()` على نفس bq عندما تصل قيمة `bq->count` إلى `CPU_MAP_BULK_SIZE`. تقوم كلتا المهمتين بعد ذلك باستدعاء `__list_del_clearprev()` على نفس عقدة `bq->flush_node`، حيث يقوم الاستدعاء الثاني بفك الإحالة (dereference) لمؤشر prev الذي تم تعيينه مسبقاً إلى NULL بواسطة الاستدعاء الأول.

2. حالات سباق بين `bq->count` و `bq->q[]`: يمكن أن يؤدي استدعاء `bq_enqueue()` المتزامن إلى إتلاف طابور الحزم بينما تقوم دالة `bq_flush_to_queue()` بمعالجته.

حالة السباق بين المهمة أ (`__cpu_map_flush` -> `bq_flush_to_queue`) والمهمة ب (`bq_enqueue` -> `bq_flush_to_queue`) على نفس المعالج:

المهمة أ (xdp_do_flush) المهمة ب (cpu_map_enqueue) ---------------------- ------------------------ bq_flush_to_queue(bq) spin_lock(&q->producer_lock) /* تفريغ bq->q[] إلى ptr_ring */
bq->count = 0 spin_unlock(&q->producer_lock) bq_enqueue(rcpu, xdpf) <-- CFS توقف المهمة أ مؤقتاً --> bq->q[bq->count++] = xdpf
/* ... عمليات إضافة أخرى حتى الامتلاء ... */ bq_flush_to_queue(bq) spin_lock(&q->producer_lock) /* تفريغ إلى ptr_ring */ spin_unlock(&q->producer_lock) __list_del_clearprev(flush_node) /* تعيين flush_node.prev = NULL */ <-- استئناف المهمة أ --> __list_del_clearprev(flush_node) flush_node.prev->next = ... /* بما أن prev هو NULL -> يحدث خطأ في النواة (kernel oops) */

يتم إصلاح هذه المشكلة بإضافة `local_lock_t` إلى `xdp_bulk_queue واقتناصها داخل دالتي `bq_enqueue()` و `__cpu_map_flush()`. هذان المساران يعملان بالفعل تحت مظلة `local_bh_disable()`، لذا يتم استخدام `local_lock_nested_bh()` الذي يكون على الأنظمة غير RT مجرد تعليق توضيحي (annotation) دون أي عبء إضافي في الأداء، وعلى PREEMPT_RT يوفر قفلاً قابلاً للنوم خاصاً بكل وحدة معالجة مركزية يقوم بتسلسل الوصول إلى bq.

لتكرار التجربة، قم بإدراج `mdelay(100)` بين السطرين `bq->count = 0` و `__list_del_clearprev()` داخل دالة `bq_flush_to_queue()`، ثم شغّل أداة الاستنساخ (reproducer) المقدمة من قبل syzkaller.

If you want to get best quality of vulnerability data, you may have to visit VulDB.

مسؤول

Linux

حجز

13/01/2026

إفشاء

25/03/2026

الاعتدال

تمت الموافقة

إدخال

VDB-353111

EPSS

0.00088

KEV

لا

النشاطات

منخفض جدًا

المصادر

Want to know what is going to be exploited?

We predict KEV entries!