سلامة تدفق التحكم في النواة

سلامة تدفق التحكّم (CFI) هي آلية أمان لا تسمح بإجراء تغييرات على الرسم البياني الأصلي لتدفق التحكّم في ملف ثنائي مُجمَّع، ما يجعل من الصعب بشكلٍ كبير تنفيذ هذه الهجمات.

في Android 9، فعّلنا ميزة "التحقّق من سلامة الرمز البرمجي" (CFI) من LLVM في المزيد من المكوّنات وأيضاً في النواة. يكون نظام CFI مفعّلاً بشكلٍ تلقائي، ولكن عليك تفعيل CFI في kernel.

تتطلّب تقنية CFI في LLVM إجراء عملية الترجمة باستخدام ميزة التحسين في وقت الربط (LTO). تحافظ تقنية LTO على تمثيل LLVM لرمز البتات في ملفات العناصر إلى وقت الربط، ما يسمح للمجمِّع بتحديد التحسينات التي يمكن إجراؤها بشكل أفضل. يؤدي تفعيل LTO إلى تقليل حجم الملف الثنائي النهائي وتحسين الأداء، ولكنّه يزيد من وقت الترجمة. في الاختبارات على Android، يؤدي الجمع بين LTO وCFI إلى زيادة طفيفة في حجم الرمز البرمجي وأدائه، وفي حالات محدودة، يؤدي الجمع بينهما إلى تحسين كلاهما.

لمزيد من التفاصيل الفنية حول CFI وكيفية التعامل مع عمليات التحقّق الأخرى من التحكّم في التنفيذ، يُرجى الاطّلاع على مستندات تصميم LLVM.

التنفيذ

تتوفّر تصحيحات kCFI في جميع إصدارات نواة Android المتوافقة. يُفعِّل الخيار CONFIG_CFI_CLANG مقياس kCFI ويتم ضبطه تلقائيًا في GKI.

تحديد المشاكل وحلّها

بعد تفعيل هذه الميزة، عليك حلّ أي أخطاء عدم تطابق في النوع قد تظهر في برامج التشغيل. يؤدي استدعاء دالة غير مباشر من خلال مؤشر دالة غير متوافق إلى إيقاف ميزة CFI. عند رصد خطأ في CFI، يطبع kernel تحذيرًا يضمّ كلاً من الدالة التي تمّ استدعاؤها وتتبُّع تسلسل استدعاء الدوالّ الذي أدّى إلى الخطأ. يمكنك تصحيح ذلك من خلال التأكّد من أنّ مؤشرات الدوال لها دائمًا النوع نفسه كالدالة التي يتمّ استدعاؤها.

للمساعدة في تصحيح أخطاء CFI، يمكنك تفعيل CONFIG_CFI_PERMISSIVE، الذي يطبع تحذيرًا بدلاً من التسبب في حدوث عطل في نظام التشغيل. يجب عدم استخدام "الوضع المرخّص" في مرحلة الإنتاج.

التحقُّق

لا يتوفّر حاليًا اختبار CTS مخصّص لـ CFI. بدلاً من ذلك، تأكَّد من اجتياز اختبارات CTS مع تفعيل CFI أو بدونه للتحقّق من أنّ CFI لا يؤثر في الجهاز.