یکپارچگی جریان کنترل (CFI) یک مکانیسم امنیتی است که تغییرات در نمودار جریان کنترل اصلی یک باینری کامپایل شده را مجاز نمیداند و انجام چنین حملاتی را بهطور قابل توجهی سختتر میکند.
در اندروید 9، پیاده سازی CFI توسط LLVM را در اجزای بیشتر و همچنین در هسته فعال کردیم. سیستم CFI به طور پیش فرض روشن است، اما باید CFI هسته را فعال کنید.
CFI LLVM نیاز به کامپایل با بهینه سازی زمان لینک (LTO) دارد. LTO نمایش بیتکد LLVM فایلهای شی را تا زمان پیوند حفظ میکند، که به کامپایلر اجازه میدهد تا در مورد بهینهسازیهایی که میتوان انجام داد، استدلال بهتری داشته باشد. فعال کردن LTO اندازه باینری نهایی را کاهش می دهد و عملکرد را بهبود می بخشد، اما زمان کامپایل را افزایش می دهد. در آزمایش روی اندروید، ترکیب LTO و CFI منجر به سربار ناچیزی نسبت به اندازه و عملکرد کد می شود. در چند مورد هر دو بهبود یافتند.
برای جزئیات فنی بیشتر در مورد CFI و نحوه رسیدگی به سایر بررسیهای کنترل جلو، به مستندات طراحی LLVM مراجعه کنید.
پیاده سازی
وصلههای kCFI در تمام نسخههای هسته اندروید پشتیبانی میشوند. گزینه CONFIG_CFI_CLANG
kCFI را فعال می کند و به طور پیش فرض در GKI تنظیم شده است.
عیب یابی
پس از فعال کردن، هر نوع خطای عدم تطابق را که ممکن است با درایورهای آنها وجود داشته باشد، بررسی کنید. یک فراخوانی غیرمستقیم تابع از طریق یک نشانگر تابع ناسازگار، CFI را خاموش می کند. هنگامی که یک خرابی CFI شناسایی می شود، هسته یک هشدار چاپ می کند که هم تابعی را که فراخوانی شده و هم stacktrace را که منجر به شکست شده است، چاپ می کند. با اطمینان از اینکه نشانگرهای تابع همیشه از نوع تابعی هستند که فراخوانی می شود، این را تصحیح کنید.
برای کمک به اشکالزدایی خرابیهای CFI، CONFIG_CFI_PERMISSIVE
را فعال کنید، که به جای ایجاد وحشت در هسته، یک هشدار چاپ میکند. حالت مجاز نباید در تولید استفاده شود.
اعتبار سنجی
در حال حاضر، هیچ آزمایش CTS به طور خاص برای CFI وجود ندارد. در عوض، مطمئن شوید که تستهای CTS با یا بدون فعال بودن CFI انجام میشوند تا تأیید شود که CFI روی دستگاه تأثیر نمیگذارد.