تنفيذ SELinux

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

الملفات الرئيسية

لتمكين SELinux ، قم بدمج أحدث إصدار من Android kernel ثم قم بدمج الملفات الموجودة في دليل system / sepolicy . عند تجميع هذه الملفات ، تشتمل على سياسة أمان SELinux kernel وتغطي نظام تشغيل Android الرئيسي.

بشكل عام ، لا يجب عليك تعديل ملفات system/sepolicy مباشرة. بدلاً من ذلك ، قم بإضافة أو تحرير ملفات السياسة الخاصة بالجهاز في الدليل /device/ manufacturer / device-name /sepolicy . في Android 8.0 والإصدارات الأحدث ، يجب أن تؤثر التغييرات التي تجريها على هذه الملفات فقط على السياسة في دليل البائع. لمزيد من التفاصيل حول فصل السياسة العامة في Android 8.0 والإصدارات الأحدث ، راجع تخصيص SEPolicy في Android 8.0+ . بغض النظر عن إصدار Android ، ما زلت تعدل هذه الملفات:

ملفات السياسة

الملفات التي تنتهي بـ *.te هي ملفات مصدر لسياسة SELinux ، والتي تحدد المجالات وتسمياتها. قد تحتاج إلى إنشاء ملفات سياسة جديدة في /device/ manufacturer / device-name /sepolicy ، ولكن يجب أن تحاول تحديث الملفات الموجودة حيثما أمكن ذلك.

ملفات السياق

ملفات السياق هي المكان الذي تحدد فيه تسميات للعناصر الخاصة بك.

  • file_contexts يعين تسميات للملفات ويستخدمه العديد من مكونات مساحة المستخدمين. أثناء إنشاء سياسات جديدة ، قم بإنشاء هذا الملف أو تحديثه لتعيين تصنيفات جديدة للملفات. لتطبيق file_contexts جديد ، أعد بناء صورة نظام الملفات أو شغّل restorecon على الملف المراد إعادة تسميته. في عمليات الترقية ، يتم تطبيق التغييرات التي تم إجراؤها على file_contexts تلقائيًا على أقسام النظام وبيانات المستخدم كجزء من الترقية. يمكن أيضًا تطبيق التغييرات تلقائيًا عند الترقية إلى أقسام أخرى عن طريق إضافة استدعاءات restorecon_recursive إلى البادئة الخاصة بك. board .rc بعد تحميل القسم للقراءة والكتابة.
  • genfs_contexts بتعيين تسميات لأنظمة الملفات ، مثل proc أو vfat التي لا تدعم السمات الموسعة. يتم تحميل هذا التكوين كجزء من سياسة kernel ولكن التغييرات قد لا تصبح سارية المفعول في in-core ، مما يتطلب إعادة التشغيل أو إلغاء التثبيت وإعادة تركيب نظام الملفات لتطبيق التغيير بالكامل. يمكن أيضًا تعيين تسميات محددة إلى حوامل معينة ، مثل vfat باستخدام context=mount .
  • تعيّن property_contexts التصنيفات إلى خصائص نظام Android للتحكم في العمليات التي يمكنها تعيينها. تتم قراءة هذا التكوين من خلال عملية init أثناء بدء التشغيل.
  • تعيّن service_contexts تسميات لخدمات Android Binder للتحكم في العمليات التي يمكنها إضافة (تسجيل) والعثور على (بحث) مرجع رابط للخدمة. تتم قراءة هذا التكوين من خلال عملية مدير servicemanager أثناء بدء التشغيل.
  • seapp_contexts بتعيين تسميات لعمليات التطبيق و /data/data أدلة البيانات. تتم قراءة هذا التكوين من خلال عملية zygote عند كل تشغيل للتطبيق وعن طريق installd أثناء بدء التشغيل.
  • mac_permissions.xml بتعيين علامة seinfo للتطبيقات بناءً على توقيعها واختيار اسم الحزمة الخاصة بها. يمكن بعد ذلك استخدام علامة seinfo كمفتاح في ملف seapp_contexts لتعيين تسمية محددة لجميع التطبيقات التي تحمل علامة seinfo هذه. تتم قراءة هذا التكوين بواسطة system_server أثناء بدء التشغيل.
  • keystore2_key_contexts يعين التسميات لمساحات أسماء Keystore 2.0. يتم فرض مساحة الاسم هذه بواسطة البرنامج الخفي keystore2. يوفر Keystore دائمًا مساحات الأسماء المستندة إلى UID / AID. يقوم Keystore 2.0 أيضًا بفرض مساحات أسماء محددة بشكل منفصل. يمكن العثور على وصف تفصيلي لتنسيق واصطلاحات هذا الملف هنا .

BoardConfig.mk makefile

بعد تحرير ملفات السياسة والسياق أو إضافتها ، قم بتحديث ملف /device/ manufacturer / device-name /BoardConfig.mk makefile للإشارة إلى الدليل الفرعي sepolicy وكل ملف سياسة جديد. لمزيد من المعلومات حول متغيرات BOARD_SEPOLICY ، راجع ملف system/sepolicy/README .

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

بعد إعادة البناء ، يتم تمكين جهازك مع SELinux. يمكنك الآن إما تخصيص سياسات SELinux الخاصة بك لاستيعاب الإضافات الخاصة بك إلى نظام التشغيل Android كما هو موضح في التخصيص أو التحقق من الإعداد الحالي كما هو مغطى في التحقق من الصحة.

عندما تكون ملفات السياسة الجديدة وتحديثات BoardConfig.mk في مكانها ، فإن إعدادات السياسة الجديدة يتم تضمينها تلقائيًا في ملف نهج kernel النهائي. لمزيد من المعلومات حول كيفية إنشاء السياسة على الجهاز ، راجع بناء الانقطاع .

تطبيق

لبدء استخدام SELinux:

  1. تفعيل SELinux في النواة: CONFIG_SECURITY_SELINUX=y
  2. قم بتغيير معلمة kernel_cmdline أو bootconfig بحيث:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    أو
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    هذا فقط للتطوير الأولي لسياسة الجهاز. بعد أن يكون لديك سياسة تمهيد أولية ، قم بإزالة هذه المعلمة حتى يتم فرض جهازك أو سيفشل CTS.
  3. قم بتشغيل النظام بشكل متساهل وانظر إلى حالات الرفض التي تتم مواجهتها في التمهيد:
    على Ubuntu 14.04 أو أحدث:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    على Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. قم بتقييم مخرجات التحذيرات التي تشبه init: Warning! Service name needs a SELinux domain defined; please fix! انظر التحقق من الصحة للحصول على الإرشادات والأدوات.
  5. حدد الأجهزة والملفات الجديدة الأخرى التي تحتاج إلى تصنيف.
  6. استخدم التسميات الموجودة أو الجديدة للعناصر الخاصة بك. انظر إلى ملفات *_contexts لترى كيف تم تصنيف الأشياء مسبقًا واستخدم معرفة معاني التسمية لتعيين معاني جديدة. من الناحية المثالية ، سيكون هذا تصنيفًا موجودًا يتناسب مع السياسة ، ولكن في بعض الأحيان ستكون هناك حاجة إلى تسمية جديدة ، وستكون هناك حاجة إلى قواعد للوصول إلى هذا التصنيف. أضف تسمياتك إلى ملفات السياق المناسبة.
  7. تحديد المجالات / العمليات التي يجب أن يكون لها مجالات الأمان الخاصة بها. ستحتاج على الأرجح إلى كتابة سياسة جديدة تمامًا لكل منها. يجب أن يكون لجميع الخدمات الناشئة من init ، خدمات خاصة بها. تساعد الأوامر التالية في الكشف عن الأوامر التي لا تزال قيد التشغيل (لكن جميع الخدمات تحتاج إلى مثل هذا العلاج):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. مراجعة init. device .rc لتحديد أي مجالات ليس لها نوع المجال. امنحهم مجالًا في وقت مبكر من عملية التطوير لتجنب إضافة قواعد إلى init أو init عمليات الوصول الأولية مع تلك الموجودة في سياستهم الخاصة.
  9. قم بإعداد BOARD_CONFIG.mk لاستخدام متغيرات BOARD_SEPOLICY_* . راجع README in system/sepolicy للحصول على تفاصيل حول إعداد هذا.
  10. افحص الحرف الأول. device . RC و fstab. device file وتأكد من أن كل استخدام لـ mount يتوافق مع نظام ملفات مصنف بشكل صحيح أو أنه تم تحديد خيار context= mount .
  11. راجع كل رفض وقم بإنشاء سياسة SELinux للتعامل مع كل منها بشكل صحيح. اطلع على الأمثلة في التخصيص .

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

استخدم حالات

فيما يلي أمثلة محددة على عمليات استغلال الثغرات التي يجب مراعاتها عند صياغة برنامجك الخاص وسياسات SELinux المرتبطة بها:

الارتباطات الرمزية - نظرًا لأن الارتباطات الرمزية تظهر كملفات ، فغالبًا ما تتم قراءتها كملفات ، مما قد يؤدي إلى حدوث عمليات استغلال. على سبيل المثال ، تقوم بعض المكونات المميزة ، مثل init ، بتغيير أذونات بعض الملفات ، أحيانًا لتكون مفتوحة بشكل مفرط.

قد يستبدل المهاجمون بعد ذلك هذه الملفات بروابط رمزية للتعليمات البرمجية التي يتحكمون فيها ، مما يسمح للمهاجم بالكتابة فوق الملفات العشوائية. ولكن إذا كنت تعلم أن تطبيقك لن يتجاوز ارتباطًا رمزيًا أبدًا ، فيمكنك منعه من القيام بذلك باستخدام SELinux.

ملفات النظام - ضع في اعتبارك فئة ملفات النظام التي يجب تعديلها بواسطة خادم النظام فقط. ومع ذلك ، منذ netd و init و vold كجذر ، يمكنهم الوصول إلى ملفات النظام هذه. لذلك إذا netd ، فقد يعرض هذه الملفات للخطر وربما خادم النظام نفسه.

باستخدام SELinux ، يمكنك تحديد هذه الملفات كملفات بيانات خادم النظام. لذلك ، فإن المجال الوحيد الذي لديه حق الوصول للقراءة / الكتابة إليها هو خادم النظام. حتى إذا netd ، فلن يتمكن من تبديل المجالات إلى مجال خادم النظام والوصول إلى ملفات النظام هذه على الرغم من أنه يعمل كجذر.

بيانات التطبيق - مثال آخر هو فئة الوظائف التي يجب تشغيلها كجذر ولكن لا يجب الوصول إلى بيانات التطبيق. يعد هذا مفيدًا بشكل لا يصدق حيث يمكن إجراء تأكيدات واسعة النطاق ، مثل بعض المجالات غير المرتبطة ببيانات التطبيق التي تم حظرها من الوصول إلى الإنترنت.

setattr - لأوامر مثل chmod و chown ، يمكنك تحديد مجموعة الملفات حيث يمكن للمجال المرتبط إجراء setattr . يمكن حظر أي شيء خارج ذلك من هذه التغييرات ، حتى من خلال الجذر. لذلك قد يقوم أحد التطبيقات بتشغيل chmod و chown مقابل تلك المسماة app_data_files ولكن ليس shell_data_files أو system_data_files .