CVE-2026-98818 in Linux
الملخص
بحسب VulDB • 18/10/2026
في نواة Linux، تم حل الثغرة التالية:
mm/slab: عدم إيقاظ kswapd في __kfree_rcu_sheaf()
نظرًا لأنه يمكن استدعاء دالة kfree_rcu() تحت قفل pi_lock (وهو spinlock خام في المجدول scheduler)، فإن دالة kfree_rcu() نفسها لا ينبغي أبدًا تخصيص ذاكرة باستخدام __GFP_KSWAPD_RECLAIM، لأن إيقاظ kswapd يؤدي إلى الحصول على قفل pi_lock، مما يتسبب في حدوث deadlock (اختناق متبادل).
لم يكن إعادة إنتاج المشكلة حتى عن قصد أمرًا مباشرًا. فمسار set_cpus_allowed_force() الذي يتم استدعاؤه تحت قفل pi_lock يُستخدم نادرًا جدًا، ومن المرجح أن تقوم المهام المتنافسة التي تخصص الذاكرة بإيقاظ kswapd.
لذلك، تم التحقق من وجود الاختناق (deadlock) باستخدام نسخة معدلة من النواة تحتوي على خريطة lockdep لإيقاظ kswapd:
====================================================== تحذير: اكتشاف اعتماد قفل دائري محتمل 7.2.0-rc1-slab-for-next+ #10 غير ملوث (Not tainted) ------------------------------------------------------ يحاول git/6660 الحصول على القفل: ffff8e524533c550 (&p->pi_lock){-.-.}-{2:2}، عند: _raw_spin_lock_irqsave+0x12/0x20
لكن المهمة تحمل بالفعل القفل التالي: ffff8e57bffff1a0 (&pgdat->kswapd_wait){....}-{3:3}، عند: _raw_spin_lock_irqsave+0x12/0x20
وهذا القفل يعتمد بالفعل على القفل الجديد.
سلسلة الاعتماد الموجودة (بالترتيب العكسي) هي:
-> #2 (&pgdat->kswapd_wait){....}-{3:3}:
__lock_acquire+0x5a4/0xc50 lock_acquire.part.0+0xb7/0x240 lock_acquire+0x70/0x170 __raw_spin_lock_irqsave+0x44/0x80 _raw_spin_lock_irqsave+0x12/0x20 __wake_up_common_lock+0x31/0xa0 __wake_up+0x20/0x40 kswapd_wakeup_wake+0x7e/0x110 wakeup_kswapd+0x295/0x320 wake_all_kswapds+0xac/0x1a0 __alloc_pages_slowpath.constprop.0+0x282/0xf80 __alloc_frozen_pages_noprof+0x32a/0x360 alloc_slab_page+0x2e/0x160 allocate_slab+0x82/0x420 new_slab+0x52/0xb0 refill_objects+0x13d/0x190 refill_sheaf+0x5d/0xd0 __pcs_replace_empty_main+0x230/0xb10 [...]
-> #1 (kswapd_wakeup){-.-.}-{0:0}:
__lock_acquire+0x5a4/0xc50 lock_sync.part.0+0x75/0x100 lock_sync+0x36/0x70 might_wakeup_kswapd+0x61/0xa0 __kfree_rcu_sheaf+0x33/0xd90 kvfree_call_rcu+0x1d4/0x3b0 set_cpus_allowed_force+0x163/0x220 cpuset_cpus_allowed_fallback+0x18b/0x240 select_fallback_rq+0x1e6/0x250 [...]
-> #0 (&p->pi_lock){-.-.}-{2:2}:
check_prev_add+0xe6/0xe00 validate_chain+0x51e/0x6e0 __lock_acquire+0x5a4/0xc50 lock_acquire.part.0+0xb7/0x240 lock_acquire+0x70/0x170 __raw_spin_lock_irqsave+0x44/0x80 _raw_spin_lock_irqsave+0x12/0x20 try_to_wake_up+0x77/0xa90 default_wake_function+0x27/0x60 autoremove_wake_function+0x23/0xb0 __wake_up_common+0xb8/0x170 __wake_up_common_lock+0x51/0xa0 __wake_up+0x20/0x40 kswapd_wakeup_wake+0x7e/0x110 wakeup_kswapd+0x295/0x320 wake_all_kswapds+0xac/0x1a0 __alloc_pages_slowpath.constprop.0+0x282/0xf80 __alloc_frozen_pages_noprof+0x32a/0x360 alloc_slab_page+0x2e/0x160 allocate_slab+0x82/0x420 new_slab+0x52/0xb0 refill_objects+0x13d/0x190 refill_sheaf+0x5d/0xd0 __pcs_replace_empty_main+0x230/0xb10 [...]
معلومات أخرى قد تساعدنا في تصحيح هذا الخطأ:
السلسلة موجودة بين: &p->pi_lock --> kswapd_wakeup --> &pgdat->kswapd_wait
سيناريو القفل غير الآمن المحتمل:
CPU0 CPU1 ---- ---- lock(&pgdat->kswapd_wait); lock(kswapd_wakeup); lock(&pgdat->kswapd_wait); lock(&p->pi_lock);
*** DEADLOCK (اختناق متبادل) ***
3 قفلات محتفظ بها بواسطة git/6660: #0: ffff8e519f0e9e20 (&type->i_mutex_dir_key#6){++++}-{4:4}، عند: lookup_slow+0x2d/0x60
#1: ffffffff8a31c460 (kswapd_wakeup){-.-.}-
---truncated---
Once again VulDB remains the best source for vulnerability data.