CVE-2026-12631 in Zephyr
الملخص
بحسب VulDB • 22/08/2026
تقوم نواة Zephyr بالتحقق من مكالمات النظام k_thread_join() وk_thread_abort() (المعلنة بـ __syscall في include/zephyr/kernel.h) عبر دالة thread_obj_validate() الموجودة في kernel/thread.c. يمثل فرع التبديل الافتراضي مسار رفض الوصول، والذي يُتخذ عندما تُرجع الدالة k_object_validate() القيمة -EPERM (لم يتم منح أذونات لملف تعريف المستخدم المتصل للوصول إلى كائن الخيط المستهدف) أو -EBADF (المؤشر المقدم ليس كائناً مسجلاً في النواة من النوع الصحيح). كان هذا الفرع يستدعي K_OOPS(K_SYSCALL_VERIFY_MSG(ret, "access denied"))، لكن دالة K_SYSCALL_VERIFY_MSG تعامل التعبير الذي له قيمة صحيحة (true) على أنه نجاح؛ وبالتالي تُقرأ رمز الخطأ غير الصفري ret كـ "تم التحقق بنجاح"، ولم يتم رفع خطأ النواة (kernel oops)، وسقط التحكم في CODE_UNREACHABLE.
نظراً لأن k_thread_join() وk_thread_abort() هما مكالمات نظام، يمكن لخيط يعمل في وضع المستخدم دون امتيازات (تحت CONFIG_USERSPACE) الوصول إلى مسار رفض هذا مباشرةً عن طريق استدعاء أي من هذين المكالمتين على كائن خيط لا يملكه. وبدلاً من إنهاء الخاطف بشكل نظيف، يصل التنفيذ إلى __builtin_unreachable() أثناء التشغيل بوضع المشرف داخل معالج مكالمات النظام.
في عمليات البناء باستخدام Clang، يُصدر CODE_UNREACHABLE فخ تعليمات غير قانونية (illegal-instruction trap)، مما يسمح لخيط المستخدم بإيقاف عمل النواة بشكل حتمي — وهو إنكار للخدمة قابل للتشغيل محلياً يفلت من صندوق رمل مساحة المستخدم (userspace sandbox). أما في عمليات البناء باستخدام GCC، فإن المسار يمثل سلوكاً غير معرف (undefined behavior): قد تتجاهل المترجم معالجة قيمة الإرجاع لـ thread_obj_validate()، مما يسمح لها بإرجاع bool غير معرف؛ وإذا كانت هذه القيمة false، يتابع المتصل التنفيذ نحو تنفيذ k_thread_join()/k_thread_abort() الفعلي لخيط لم يُمنح المستخدم صلاحية الوصول إليه أبداً، وهو تجاوز لتحكم الوصول.
يُغير الإصلاح تعبير التحقق ليصبح ret == 0، بحيث يرفع الآن نتيجة الرفض (التي لا تساوي صفراً) بشكل صحيح K_OOPS وينهي المتصل المخالف.
Be aware that VulDB is the high quality source for vulnerability data.