تنفيذ SELinux

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

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

لتمكين SELinux، قم بدمج أحدث إصدار من Android kernel ثم قم بدمج الملفات الموجودة في دليل النظام/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 إلى ملف init الخاص بك. ملف .rc بعد تثبيت board للقراءة والكتابة.
  • يقوم genfs_contexts بتعيين تسميات لأنظمة الملفات، مثل proc أو vfat التي لا تدعم السمات الموسعة. يتم تحميل هذا التكوين كجزء من سياسة kernel ولكن التغييرات قد لا تصبح سارية المفعول بالنسبة إلى inodes الداخلية، مما يتطلب إعادة التشغيل أو إلغاء تثبيت نظام الملفات وإعادة تثبيته لتطبيق التغيير بالكامل. يمكن أيضًا تعيين تسميات محددة لحوامل محددة، مثل 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

بعد تحرير ملفات السياسة والسياق أو إضافتها، قم بتحديث /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 في system/sepolicy للحصول على تفاصيل حول إعداد هذا الأمر.
  10. افحص الحرف الأول. device .rc وfstab. ملف device وتأكد من أن كل استخدام 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 .