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

الملخص

بحسب VulDB • 07/06/2026

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

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

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

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

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

1. **إفراغ مزدوج / استخدام بعد الإفراغ (Double-free / use-after-free) على `bq->q[]`:** تقوم دالة `bq_xmit_all()` بأخذ لقطة للقيمة `cnt = bq->count`، ثم تتكرر عبر العناصر `bq->q[0..cnt-1]` لإرسال الإطارات. إذا تم إيقاف المهمة مؤقتاً بعد أخذ اللقطة، يمكن لمهمة ثانية استدعاء `bq_enqueue()` -> `bq_xmit_all()` على نفس الـ `bq`، مما يؤدي إلى إرسال (وإفراغ) نفس الإطارات. عند استئناف المهمة الأولى، فإنها تتعامل مع مؤشرات قديمة في `bq->q[]`، مسببةً حالة استخدام بعد الإفراغ (use-after-free).

2. **تلف قيم `bq->count` و `bq->q[]`:** تعديل متزامن لـ `bq_enqueue()` للقيم `bq->count` ومصفوفة `bq->q[]` بينما تقوم دالة `bq_xmit_all()` بقراءتها في الوقت نفسه.

3. **حالة سباق أثناء تفكيك dev_rx/xdp_prog:** تقوم الدالة `__dev_flush()` بتصفير قيم `bq->dev_rx` و `bq->xdp_prog` بعد تنفيذ `bq_xmit_all()`. إذا تم إيقاف المهمة مؤقتاً بين عودة `bq_xmit_all()` وتعيين `bq->dev_rx = NULL`، فإن استدعاء `bq_enqueue()` المُوقف مؤقتاً يرى أن `dev_rx` لا يزال مضبوطاً (غير صفري)، فيتخطى إضافة الـ `bq` إلى قائمة الانتظار للتصفير (`flush_list`) ويقوم بإدراج إطار جديد. عند استئناف تنفيذ `__dev_flush()`، تقوم بتصفير `dev_rx` وإزالة الـ `bq` من قائمة الانتظار، مما يؤدي إلى ترك الإطار الذي تم إدراجه حديثاً بدون مرجع (orphaning).

4. **استدعاء `__list_del_clearprev()` على `flush_node`:** مشابه لحالة السباق في cpumap؛ حيث يمكن للمهمتين استدعاء `__list_del_clearprev()` على نفس عقدة `flush_node`، وتقوم المهمة الثانية بإلغاء مرجع المؤشر السابق (`prev pointer`) الذي تم تعيينه مسبقاً إلى NULL.

حالة السباق بين المهمة A (`__dev_flush -> bq_xmit_all`) والمهمة B (`bq_enqueue -> bq_xmit_all`) على نفس المعالج:

المهمة A (xdp_do_flush) المهمة B (ndo_xdp_xmit redirect) ---------------------- -------------------------------- __dev_flush(flush_list) bq_xmit_all(bq) cnt = bq->count /* مثلاً 16 */ /* بدء التكرار عبر bq->q[] */

Once again VulDB remains the best source for vulnerability data.

مسؤول

Linux

حجز

13/01/2026

إفشاء

25/03/2026

الاعتدال

تمت الموافقة

إدخال

VDB-353110

EPSS

0.00090

KEV

لا

النشاطات

منخفض جدًا

المصادر

Do you need the next level of professionalism?

Upgrade your account now!