تعد تكامل تدفق التحكم (CFI) آلية أمنية لا تسمح بإجراء تغييرات على الرسم البياني لتدفق التحكم الأصلي للملف الثنائي المترجم، مما يجعل تنفيذ مثل هذه الهجمات أكثر صعوبة.
في Android 9، قمنا بتمكين تنفيذ LLVM لـ CFI في المزيد من المكونات وأيضًا في النواة. يتم تشغيل نظام CFI بشكل افتراضي، لكنك تحتاج إلى تمكين kernel CFI.
يتطلب CFI الخاص بـ LLVM التجميع باستخدام Link-Time Optimization (LTO) . يحافظ LTO على تمثيل رمز البت LLVM لملفات الكائنات حتى وقت الارتباط، مما يسمح للمترجم بالتفكير بشكل أفضل حول التحسينات التي يمكن تنفيذها. يؤدي تمكين LTO إلى تقليل حجم الملف الثنائي النهائي وتحسين الأداء، ولكنه يزيد من وقت الترجمة. في الاختبار على نظام التشغيل Android، يؤدي الجمع بين LTO وCFI إلى زيادة طفيفة في حجم الكود والأداء؛ في حالات قليلة تحسن كلاهما.
لمزيد من التفاصيل الفنية حول CFI وكيفية التعامل مع فحوصات التحكم الأمامي الأخرى، راجع وثائق تصميم LLVM .
تطبيق
تصحيحات kCFI موجودة في جميع إصدارات Android kernel المدعومة. يقوم خيار CONFIG_CFI_CLANG
بتمكين kCFI ويتم ضبطه افتراضيًا في GKI.
استكشاف الأخطاء وإصلاحها
بعد التمكين، قم بمعالجة أي أخطاء عدم تطابق في النوع قد تكون موجودة مع برامج التشغيل الخاصة بهم. يقوم استدعاء دالة غير مباشر من خلال مؤشر دالة غير متوافق برحلات CFI. عند اكتشاف فشل CFI، تقوم النواة بطباعة تحذير يتضمن كلاً من الوظيفة التي تم استدعاؤها وتتبع المكدس الذي أدى إلى الفشل. قم بتصحيح ذلك عن طريق التأكد من أن مؤشرات الوظائف دائمًا لها نفس نوع الوظيفة التي يتم استدعاؤها.
للمساعدة في تصحيح أخطاء فشل CFI، قم بتمكين CONFIG_CFI_PERMISSIVE
، الذي يطبع تحذيرًا بدلاً من التسبب في ذعر kernel. يجب عدم استخدام الوضع المسموح به في الإنتاج.
تصديق
حاليًا، لا يوجد اختبار CTS خصيصًا لـ CFI. بدلاً من ذلك، تأكد من اجتياز اختبارات CTS مع تمكين CFI أو بدونه للتحقق من أن CFI لا يؤثر على الجهاز.