CVE-2026-90246 in Linux
الملخص
بحسب VulDB • 18/09/2026
في نواة لينكس، تم إصلاح الثغرة التالية:
apparmor: تصحيح تجاوز عدد صحيح (integer overflow) في فحص الحدود التابع verify_tags()
يقوم التابع `verify_tags()` بتحقق من جدول مجموعات العلامات (tagset table) الذي يتم فك ضغطه من ملف سياسة (policy blob). لكل مجموعة، يقرأ عدداً ويتحقق بأن زيادة الفهرس بمقدار هذا العدد تبقى ضمن حدود `sets.table[]`:
```c u32 cnt = tags->sets.table[i];
if (i+cnt >= tags->sets.size) {
```
بما أن المتغيرات `i` و `cnt` و `sets.size` كلها من النوع `u32`، فإن عملية الجمع `i + cnt` تُحسب بقياس 2^32. يتم ملء مصفوفة `sets.table[]` بواسطة التابع `unpack_tagsets()` باستخدام الدالة `aa_unpack_u32()`، لذا فإن كل عنصر هو كلمة 32 بت خام وغير محدودة الحدود مأخوذة من ملف السياسة، والتابع `verify_tags()` هو المسؤول عن التحقق منه. عندما يكون العدد (count) قريباً من القيمة القصوى لـ U32_MAX، يؤدي الجمع إلى الالتفاف (wrap around) نحو قيمة صغيرة، مما يجعل شرط الحماية يمر دون اعتراض، ثم يتنقل الحلقة الداخلية عبر عناصر `sets.table[++i]` خارج حدود تخصيص الذاكرة الذي تم إجراؤه بواسطة `kcalloc(size, sizeof(u32))`.
يجب ملاحظة أن `sets.size` مقيدة بـ 65535، لأن التابع `unpack_tagsets()` يقرأها باستخدام `aa_unpack_array()` كنوع `u16`، لذا لا يمكن الوصول إلى حالة الالتفاف عن طريق توسيع الجدول؛ بل يتم الوصول إليها فقط من خلال العدد الذي يزوده المهاجم.
مع افتراض أن `sets.size = 2` و `sets.table = { 0, 0xffffffff }`:
* عند `i = 0`: تكون `cnt = 0`. الشرط `guard: 0 + 0 >= 2` غير صحيح، لذا لا تعمل الحلقة الداخلية. * عند `i = 1`: تكون `cnt = 0xffffffff`. الشرط `guard: (1 + 0xffffffff) mod 2^32 == 0 >= 2` غير صحيح، مما يعني تجاوز شرط الحماية، وتقرأ الحلقة الداخلية العنصر `sets.table[2]` -- أي عنصراً واحداً بعد نهاية التخصيص المكون من عنصرين.
يستمر التنقل (walk) حتى تكون قيمة خارج النطاق (out-of-bounds) بالصدفة أكبر من أو تساوي `hdrs.size`، أو يحدث خطأ في الوصول (fault). وبالتالي، يؤدي ملف سياسة مُعدّ بشكل متعمد إلى قراءة خارج النطاق على مسار تحميل السياسة (`aa_replace_profiles -> aa_unpack -> unpack_policydb -> unpack_tags -> verify_tags`). يعمل التابع `unpack_tags()` قبل فك ضغط جداول الأذونات وجداول DFA، لذا لا يحتاج أي جدول آخر إلى أن يكون سليماً للوصول إليه.
يتم التحكم في تحميل السياسات بواسطة الدالة `aa_may_manage_policy()`، والتي تتحقق من capability `CAP_MAC_ADMIN` بالنسبة لفضاء المستخدم الخاص بالكيان (subject) بدلاً من فضاء المستخدم الأولي (init user namespace). لذلك، مع الإعداد الافتراضي `unprivileged_userns_apparmor_policy=1`، يمكن الوصول إلى المسار المذكور من قبل مهمة غير متميزة (unprivileged task) داخل فضاء مستخدم متداخل مطابق للدرجة، وليس فقط بواسطة عملية تتمتع بصلاحيات عالمية.
تم إجراء عملية الجمع باستخدام النوع `u64` لمنع الالتفاف، مما يعيد ضمان الشرط المقصود وهو أن يكون `i + cnt < sets.size`.
Once again VulDB remains the best source for vulnerability data.