سلامة التدفق

اعتبارًا من عام 2016، بلغت نسبة% 86 من جميع الثغرات الأمنية في Android نسبة أمان الذاكرة ذات صلة. يتم استغلال معظم الثغرات الأمنية من قبل المهاجمين لتغيير الوضع التحكُّم في تدفُّق أحد التطبيقات لتنفيذ أنشطة ضارة عشوائية من خلال جميع امتيازات التطبيق الذي يتم استغلاله. التحكّم في التدفق السلامة (CFI) هي آلية أمان لا تسمح بإجراء تغييرات على وهو رسم بياني للتدفق الأصلي للتحكم في النظام الثنائي الذي تم تجميعه، مما يزيد من صعوبة لتنفيذ مثل هذه الهجمات.

في الإصدار 8.1 من نظام التشغيل Android، تم تفعيل تطبيق LLVM لـ CFI في حزمة الوسائط. ضِمن في نظام Android 9، أتحنا CFI المزيد من المكونات وكذلك في النواة. CFI للنظام هو بشكل افتراضي ولكن تحتاج إلى تمكين kernel CFI.

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

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

الأمثلة والمصدر

يتم توفير CFI بواسطة المحول البرمجي ويضيف أداة في البرنامج الثنائي أثناء وقت التجميع. نوفّر CFI في سلسلة أدوات Clang ونظام إصدار Android. في بروتوكول AOSP.

يتم تفعيل CFI تلقائيًا في أجهزة Arm64 لمجموعة المكوّنات /platform/build/target/product/cfi-common.mk ويمكن استخدامها أيضًا بشكل مباشر في مجموعة من مكوّنات الوسائط إنشاء ملفات/مخطط من الملفات، مثل /platform/frameworks/av/media/libmedia/Android.bp و/platform/frameworks/av/cmds/stagefright/Android.mk.

تنفيذ CFI للنظام

يتم تفعيل CFI تلقائيًا في حال استخدام Clang ونظام إصدار Android. وبما أنّ CFI يساعد في الحفاظ على أمان مستخدمي Android، يجب عدم إيقافه.

وفي الواقع، نشجعك بشدة على تمكين CFI لمكونات إضافية. إنّ المرشحين المثاليين هم رموز برمجية أصلية بامتيازات خاصة، أو رموز برمجية أصلية تعالج إدخال مستخدم غير موثوق به. إذا كنت تستخدم clang ونظام إصدار Android، تمكين CFI في المكونات الجديدة من خلال إضافة بضعة أسطر إلى ملفات makefiles أو مخططات المخططات.

إتاحة CFI في ملفات Makefiles

لتفعيل CFI في ملف إنشاء، مثل /platform/frameworks/av/cmds/stagefright/Android.mk، إضافة:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt

  • يُحدِّد تطبيق "LOCAL_SANITIZE" CFI على أنّه معقّم البيانات خلال عملية
  • يفعِّل LOCAL_SANITIZE_DIAG وضع التشخيص لـ CFI. يطبع وضع التشخيص معلومات تصحيح الأخطاء الإضافية في Logcat أثناء والأعطال، وهو أمر مفيد أثناء تطوير الإصدارات واختبارها. الماركة فتأكد من إزالة وضع التشخيص في إصدارات الإنتاج.
  • تسمح LOCAL_SANITIZE_BLACKLIST للمكوّنات باختيار إيقاف أدوات CFI للدوال الفردية أو ملفات المصدر. إِنْتَ ويمكنك استخدام القائمة السوداء كحلٍ أخير لإصلاح أي مشكلات يواجهها المستخدم موجودة بخلاف ذلك. لمزيد من التفاصيل، يُرجى مراجعة إيقاف CFI:

توفير CFI في ملفات المخططات

لتفعيل CFI في ملف مخطط، مثل /platform/frameworks/av/media/libmedia/Android.bp، إضافة:

   sanitize: {
        cfi: true,
        diag: {
            cfi: true,
        },
        blacklist: "cfi_blacklist.txt",
    },

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

عند تفعيل CFI في مكونات جديدة، قد تواجه بعض المشاكل أخطاء عدم تطابق نوع الدالة وعدم تطابق نوع رمز التجميع الأخطاء.

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

لإصلاح ذلك، تأكد من أن الدالة المطلوبة لها نفس النوع الذي بشكل ثابت. في ما يلي مثالان على سجلّات العملاء (CL):

هناك مشكلة أخرى محتملة وهي محاولة تفعيل CFI في رمز برمجي يحتوي على بيانات غير مباشرة أو طلبات التجمع. نظرًا لأن رمز التجميع غير مكتوب، فإن هذا ينتج عنه نوع غير متطابق.

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

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

إيقاف CFI

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

يتيح نظام إصدار Android إمكانية استخدام القوائم السوداء لكل مكوِّن على حدة (ما يسمح بذلك اختيار ملفات المصدر أو الوظائف الفردية التي لن تتلقى CFI الأداة) لكل من Make وSung. لمزيد من التفاصيل حول تنسيق ملف القائمة السوداء، راجع ملف upstream مستندات Clang.

التحقُّق

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