
ملاحظات بحثية وتطوير إثبات مفهوم (PoC) للثغرة CVE-2026-43499 (GhostLock) من نوع UAF في نواة vivo Y200i بنظام Android 14، وتغطي بدائيات استعادة مكدس سلسلة PI الخاصة بـ futex وحدود تخطيط الإطار.
الجهاز: vivo Y200i (PD2354C)، Snapdragon 4 Gen 2 (SM4450)، Android 14 / OriginOS 4 النواة: 5.10.218-gki-g3a51ea9d5834 (39-bit VA، صفحات 4K، KASLR مفعّل، STACKLEAK=y، لا SVE)
الهدف: صلاحية root مؤقتة عبر CVE-2026-43499 (GhostLock).
ما يعمل حتى الآن:
العائق: بدائية استرجاع المكدس (stack-reclaim) لا تستطيع الوصول إلى rb_node الخاص بـ rt_mutex_waiter.
الأرقام الأساسية (متطابقة عبر حزمتي firmware مستقلتين):
__arm64_sys_futex 0xe0
do_futex 0xc0 (غير مُضمَّن - يوجد bl do_futex)
futex_wait_requeue_pi 0x1b0 (waiter عند sp+0x20)
=> عمق سلسلة futex T0-0x330
__arm64_sys_pselect6 0xa0 core_sys_select 0x1c0 (fd_set عند sp+0x50) => عمق سلسلة pselect T0-0x210، النافذة القابلة للتحكم 120 بايت فقط => فجوة 0x120، غير متداخلة معمارياً
تخطيط waiter (5.10 المدمج، يطابق PFEM10): +0x18 pi_tree_entry.__rb_parent_color <- ما يمشيه rt_mutex_adjust_prio_chain +0x20 pi_tree_entry.rb_right +0x28 pi_tree_entry.rb_left +0x30 task +0x38 lock +0x40 prio +0x48 deadline
دليل من rt_mutex_adjust_prio_chain: ldr x8, [task, #0x888] ; task->pi_waiters.rb_leftmost sub x8, x8, #0x18 ; rb_entry(node, rt_mutex_waiter, pi_tree_entry)
بما أن copy_from_user يكتب باتجاه العناوين الأعلى، فإن تغطية pi_tree_entry تتطلب أن تكون قاعدة النسخ <= T0-0x318.
المسارات المستنفدة: pselect6/core_sys_select T0-0x210 -> ناقص 0x120 poll/do_sys_poll النافذة تنتهي عند T0-0x344، الحد الأقصى 0xf0B (N_STACK_PPS=30) -> ناقص 0x14 rt_sigreturn (fpsimd) T0-0x300 -> يصل فقط إلى waiter+0x30 rt_sigreturn (SVE) T0-0x310 -> سيغطي waiter+0x10، لكن هذه المعالج لا يملك SVE؛ النواة ترفض سجلات sigframe الخاصة بـ SVE بـ -EINVAL compat rt_sigreturn / vfp T0-0x2c0 -> أقل عمقاً بعد
مسح كامل للنواة لجميع مواقع copy_from_user: 655 إجمالاً، 118 قابلة للوصول، أقصى عمق 0x300 (bpf_prog_get_info_by_fd، محكوم أيضاً بـ CAP_BPF). نحتاج 0x318.
الخلاصة: هندسة المكدس في هذه النواة محدودة عند 0x300 لـ copy_from_user المعتمد على المكدس؛ تغطية pi_tree_entry تتطلب 0x318. ليست مسألة ضبط - إنها اختلاف في تخطيط الإطار وقت الترجمة. do_futex غير مُضمَّن هنا، بخلاف PFEM10 (5.10.236، Clang 12.0.5)، على الأرجح نموذج تكلفة تضمين مختلف.
أبحث عن: