
مستودع بحثي لـ CVE-2025-38502، وهو وصول خارج الحدود في التخزين المحلي لمجموعة BPF cgroup في نواة Linux عبر الاستدعاءات الخلفية (tail calls) مما يتيح تصعيد الصلاحيات محليًا.

Abraxas Labs · abraxaslabs.tech · github.com/abraxas · @abraxas_null
وصول خارج الحدود إلى التخزين المحلي لـ cgroup في نواة Linux عبر BPF باستخدام tail calls
| CVE | CVE-2025-38502 |
| CWE | CWE-125 — قراءة خارج الحدود |
| المورّد | Linux kernel |
| المكوّن | kernel/bpf/core.c, include/linux/bpf.h (التخزين المحلي لـ cgroup + tail calls) |
| التأثير | تلف في ذاكرة النواة المحلية؛ تصعيد الصلاحيات وارد على الأنوية غير المُرقّعة |
| ناقل الهجوم | محلي (AV:L) |
| الصلاحيات | منخفضة (PR:L) — عملية قادرة على تحميل برامج BPF من النوع CGROUP_SKB (أو برامج مكافئة مرتبطة بـ cgroup) |
| تفاعل المستخدم | لا يوجد |
| CVSS 3.1 (kernel.org CNA) | 7.8 HIGH — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CVSS 3.1 (NVD) | 7.1 HIGH — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H |
| الإفصاح العام | 16 أغسطس 2025 |
| الإصلاح في المنبع | abad3d0 في 6.17-rc1؛ تم نقله إلى 6.16.1، 6.12.46، 6.6.105، 6.1.151، 5.15.192 |
للبحث / الاستخدام التعليمي فقط. لا تقم بتشغيل أو نشر أو استخدام المواد الموجودة في هذا المستودع ضد أي مضيف ما لم يكن لديك إذن كتابي صريح من كلٍّ من الجهة المستضيفة لهذا المستودع ومالك الأنظمة المستهدفة. تم العثور عليه في البرية.
اسم الملف المصدري CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c يقتطع المعرّف. السجل المنشور هو CVE-2025-38502. لا يوجد CVE في Linux بالمعرّف CVE-2025-3850.
أبلغ Lonial أن التخزين المحلي لـ cgroup BPF يمكن الوصول إليه خارج الحدود عبر tail call.
يتحقق مُدقّق eBPF من نوع كل برنامج على حدة. في وقت التشغيل، لا تبحث bpf_get_local_storage() عن خريطة البرنامج قيد التنفيذ. بل تقرأ مؤشر تخزين cgroup من current->bpf_ctx → bpf_cg_run_ctx → prog_item->cgroup_storage[]. تُملأ هذه الخانة من البرنامج المرتبط أصلاً، وليس من البرنامج الذي تم استدعاؤه عبر tail call.
إذا استدعى البرنامج A (بحجم قيمة صغير لـ BPF_MAP_TYPE_CGROUP_STORAGE) البرنامج B (بحجم قيمة كبير) عبر tail call، فإن bpf_get_local_storage() في B لا تزال تُعيد مخزن A الأصغر. عندئذٍ تتجاوز عمليات الوصول التي سمح بها المُدقّق مقابل خريطة B نهاية تخصيص A.
أُدخل هذا العيب في Linux 5.9 عبر 7d9c342 (bpf: Make cgroup storages shared between programs on the same cgroup). وتم إصلاحه بتوسيع bpf_map_owner بحقل storage_cookie[] بحيث لا تُقبل تركيبات tail-call إلا عندما يستخدم البرنامج المُستدعى نفس خرائط تخزين cgroup التي يستخدمها المُستدعي، أو لا يستخدم أيًّا منها.
هذا وصول خارج الحدود إلى كومة النواة محليًا. تتفاوت درجات الخطورة حسب المورّد لأنهم يختلفون حول ما إذا كانت البدائية "حجب خدمة للقراءة فقط" أم تلف كامل للذاكرة:
| المصدر | الدرجة | السلامة | ملاحظات |
|---|---|---|---|
| kernel.org CNA / cve.org | 7.8 HIGH | عالية | C:H/I:H/A:H — يعامل العلّة كتأثير محلي كامل |
| NVD | 7.1 HIGH | لا يوجد | C:H/I:N/A:H — السرية + التوافر |
| Ubuntu | متوسط (7.1) | — | USN-7909 |
| Red Hat | 4.0 LOW | لا يوجد | C:N/I:N/A:L — مُقيَّم كتوافر محدود |
| Amazon Linux | 4.0 متوسط | لا يوجد | نفس متجه Red Hat |
| SUSE | 6.1 معتدل | لا يوجد | بعض إصدارات SLE 15 مُعلَّمة WONTFIX |
ما يعنيه ذلك عمليًا:
struct bpf_array المرشوش في نفس الـ slab/order).map->ops، اختطاف helper، commit_creds / تبديل namespace). لهذا تُصنّف هذه الشجرة المشكلة كـ LPE. تعكس درجة Red Hat الأدنى تقييمهم الخاص بمنتجاتهم، وليس غياب العلّة.لا تتطلب العلّة خدمة مواجهة للشبكة. إنها محلية. ولا تتطلب TTY، ولا مساعد setuid، ولا تفاعل مستخدم.
برنامجان لـ cgroup BPF، لكلٍّ منهما BPF_MAP_TYPE_CGROUP_STORAGE خاص به (النوع المشترك، BPF_CGROUP_STORAGE_SHARED):
| البرنامج | الدور | حجم قيمة التخزين |
|---|---|---|
| A | مرتبط / مُستدعي tail-call | صغير (مثلاً يناسب رتبة kmalloc معينة) |
| B | هدف tail-call | كبير (يسمح المُدقّق بعمليات وصول حتى هذا الحجم) |
يتحقق المُدقّق من A مقابل خريطة A ومن B مقابل خريطة B. كلاهما يمر.
في وقت التشغيل يقوم الـ helper بما يلي:
ctx = container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);
storage = ctx->prog_item->cgroup_storage[stype];
if (stype == BPF_CGROUP_STORAGE_SHARED)
ptr = &READ_ONCE(storage->buf)->data[0];
else
ptr = this_cpu_ptr(storage->percpu_buf);
prog_item هو مدخل المصفوفة الخاص بالبرنامج الذي بدأ تشغيل cgroup، وليس البرنامج قيد التنفيذ حاليًا بعد bpf_tail_call. لذلك يعمل B على كائن تخزين A.
يحدد bpf_cgroup_storage_alloc() حجم المخزن الداعم من value_size الخاص بالخريطة. مخزن A أصغر من أن يستوعب عمليات الوصول المُتحقَّق منها في B. النتيجة هي التباس نوعي لهوية الخريطة عبر نقل التحكم — نفس عائلة العلل الأخرى في BPF من نوع "الـ helper يرى خريطة مختلفة عن التي رآها المُدقّق".
جعل الـ commit 7d9c342 تخزينات cgroup مشتركة بين البرامج المرتبطة بنفس cgroup. هذا التشارك هو ما يجعل خانة سياق التشغيل مؤشرًا واحدًا بدلاً من بحث لكل برنامج، وهو السبب في أن الأنوية قبل 5.9 غير متأثرة.
BPF_PROG_TEST_RUN على برنامج من النوع BPF_PROG_TYPE_CGROUP_SKB يخصص تخزين cgroup طوال مدة الاختبار. يقع هذا التخصيص على كومة النواة بجوار أي شيء آخر تم تحريره مؤخرًا في نفس فئة الحجم — بما في ذلك خرائط struct bpf_array التي اختير value_size الخاص بها ليقع في نفس رتبة kmalloc. لذلك يمكن لتجاوز خارج الحدود من مخزن التخزين أن يصل إلى حقول bpf_map (ops، قائمة RCU، value[]) الخاصة بخريطة مصفوفة مجاورة.
هذه التفصيلة في تخطيط الكومة هي السبب في أن تحذيرًا بـ "مجرد قراءة خارج الحدود" وكتابة عن LPE يمكن أن يصفا نفس الـ CVE.
أُدخلت في: Linux 5.9 (7d9c3427894fe70d1347b4820476bf37736d2ff0)
غير متأثرة: جميع الأنوية قبل 5.9
| السلسلة | متأثرة | أول إصلاح |
|---|---|---|
| 5.9 – 5.15 | 5.9 حتى 5.15.191 | 5.15.192 (c1c74584…) |
| 5.16 – 6.1 | 5.16 حتى 6.1.150 | 6.1.151 (66da7cee…) |
| 6.2 – 6.6 | 6.2 حتى 6.6.104 | 6.6.105 (7acfa07c…) |
| 6.7 – 6.12 | 6.7 حتى 6.12.45 | 6.12.46 (41688d1f…) |
| 6.13 – 6.16 | 6.13 حتى 6.16.0 | 6.16.1 (19341d5c…) |
| mainline | حتى وصول الإصلاح | 6.17-rc1 (abad3d0b…) |
سطر واحد:
/* CVE-2025-38502: affected 5.9–5.15.191, 5.16–6.1.150, 6.2–6.6.104, 6.7–6.12.45, 6.13–6.16.0; fixed in 5.15.192, 6.1.151, 6.6.105, 6.12.46, 6.16.1, 6.17-rc1 */
لا تزال مفتوحة في بعض الفروع المستقرة: أدرج متتبع نواة Debian الإصدار 5.10 upstream-stable / bullseye 5.10 كـ needed. لا تفترض أن كل إصدار 5.10.y مُرقّع.