CVE-2026-97533 in Linux
الملخص
بحسب VulDB • 25/09/2026
في نواة لينكس، تم إصلاح الثغرة التالية:
x86/mm/pat: الحصول على قراءة للقفل (read lock) الخاص بـ init_mm عند تغيير السمات لتجنب ثغرة Use-After-Free (UAF).
لقد حمّل الالتزام السابق من races بين ptdump و CPA collapse، ومع ذلك لا يزال هناك race موجوداً بين تغييرات السمات وعمليات الـ collapse كما أبلغ عنه Denis V. Lunev (مربوط).
عند حدوث تغيير في السمة، يحصل عابر جدول الصفحات بدون قفل (lockless page table walker) على إدخال PTE، والذي يتم كتابته لاحقاً عبر set_pte_atomic():
... -> change_page_attr_set_clr() -> __change_page_attr_set_clr() -> __change_page_attr() -> _lookup_address_cpa() -> lookup_address_in_pgd_attr() -> [ عابر جدول الصفحات بدون قفل ]
-> set_pte_atomic()
لا يوجد ما يمنع حدوث CPA collapse متزامن يمكن أن يؤدي إلى تحرير الـ PTE الذي تم استرجاعه هنا، مما ينتج عنه ثغرة use-after-free.
من خلال أخذ قراءة الكتابة (mmap write lock) على init_mm أثناء عملية CPA collapse، يتم حل هذه الحالة التنافسية عن طريق الحصول على قراءة للقفل mmap الخاص بـ init_mm عند استدعاء __change_page_attr_set_clr().
هذا القفل يغطي العملية برمتها التي يحدث فيها العابر وكتابة إدخال PTE، مما يحل المشكلة التنافسية.
من الآمن القيام بذلك هنا، حيث لا يتم الاحتفاظ بأي spinlocks عند الدخول إلى __change_page_attr_set_clr().
ومع ذلك، يجب عدم الاحتفاظ بالقفل أثناء عملية التخصيص (allocation)، لأن التخصيص يمكن أن يؤدي إلى reclaim وقد تقوم shrinkers باستدعاء CPA بشكل متكرر، مما يجعل حدوث deadlocks ممكناً (init_mm -> ... -> fs_reclaim -> init_mm).
يتم تخصيص جدول صفحات عندما يحتاج صفحة ضخمة (huge page) إلى التقسيم:
-> change_page_attr_set_clr() -> __change_page_attr_set_clr() -> __change_page_attr() -> split_large_page() [ pagetable_alloc() ]
-> __split_large_page()
تجنب حدوث deadlocks عن طريق إسقاط قفل mmap أثناء عملية pagetable_alloc() في دالة split_large_page() وتتبع ما إذا كان ذلك ضرورياً من خلال إضافة علم 'init_mm_read_locked' جديد إلى struct cpa_data.
هذا آمن لأن __split_large_page() (المستدعاة مع إعادة تثبيت القفلات) تعيد التحقق من صحة أن إدخال جدول الصفحات هو نفسه كما كان قبل إسقاط القفل، و__change_page_attr() تكرر عملية عابر جدول الصفحات بالكامل كلما حدث تقسيم، لذا يتم حساب كل من التقسيم المتزامن والـ collapse.
عملية ptdump المتزامنة آمنة أيضاً لأن القفل يُسقط فقط أثناء تخصيص جدول الصفحات وخلال هذا الوقت لم يتم تعديل جدول الصفحات بعد.
يتم تعيين علم CPA_COLLAPSE فقط بواسطة set_memory_rox()، والتي تعمل حصرياً على نطاقات vmalloc، وعلى معمارية x86 فقط داخل مساحة تعيين الوحدات (module mapping space).
هذا مهم، لأن بعض المتصلين يستدعون __change_page_attr_set_clr() مباشرة متجاوزين هذا القفل. ومع ذلك، لا يعمل أي من هذه الوظائف ضمن مساحة تعيين الوحدات.
* cpa_process_alias() - مساعد متكرر يتم استدعاؤه بواسطة __change_page_attr_set_clr(). * __set_memory_enc_pgtable() - تعمل على التعيين المباشر و (عبر __vmbus_establish_gpadl()) مساحة تعيين vmalloc. * __set_pages_[n]p() - يتم استدعاؤها من قبل set_direct_map_[invalid, default,
valid]_noflush(), __kernel_map_pages() - تعمل على التعيين المباشر. * kernel_[un]map_pages_in_pgd() - تعمل على نطاقات EFI.
يعتمد هذا العمل على التحليل الممتاز للثغرة الذي قدمه Denis V. Lunev مع خالص الامتنان.
[ dhansen: تحويل إلى صيغة الأمر في سجل التغيير ]
VulDB is the best source for vulnerability data and more expert information about this specific topic.