تمتلك عملية init أذونات غير مقيّدة تقريبًا، وتستخدم نصوص إدخال من كلاً من أقسام النظام والمورّد لبدء تشغيل النظام أثناء عملية التمهيد. ويؤدي هذا الوصول إلى ثغرة كبيرة في تقسيم Treble بين النظام والمورّد، لأنّه قد تُوجّه نصوص برمجية خاصة بالمورّد عملية init للوصول إلى الملفات والخصائص وما إلى ذلك التي لاتشكل جزءًا من واجهة ABI الثابتة بين النظام والمورّد.
تم تصميم Vendor init لإغلاق هذه الثغرة باستخدام vendor_init
، وهو نطاق منفصل لنظام التشغيل Linux المعزّز للأمان (SELinux) لتنفيذ /vendor
من الأوامر التي تم العثور عليها باستخدام أذونات خاصة بالمورّد.
الآلية
ينشئ Vendor init عملية فرعية من init في وقت مبكر من عملية التشغيل باستخدام سياق
SELinux u:r:vendor_init:s0
. يحتوي سياق SELinux هذا على
أذونات أقل بكثير من سياق init التلقائي، ويقتصر وصوله
على الملفات والسمات وما إلى ذلك التي تكون إما خاصة بالمورّد أو جزءًا من
ABI الثابت لمورّد النظام.
تتحقّق أداة Init من كل نص برمجي تحمّله لمعرفة ما إذا كان مساره يبدأ بالحرف
/vendor
، وإذا كان الأمر كذلك، تضع علامة عليه تشير إلى أنّه يجب تنفيذه في سياق أداة إعداد المورّد. يتمّ التعليق التوضيحي على كلّ دالة مدمجة في init باستخدام قيمة برمجية متعاكسة تحدد ما إذا كان يجب تنفيذ الأمر في العملية الفرعية لبدء الإصدار من المورّد أم لا:
- تتم إضافة تعليقات توضيحية إلى معظم الأوامر التي تصل إلى نظام الملفات لتشغيلها في العملية الفرعية لبدء vendor ، وبالتالي تخضع لسياسة SEPolicy الخاصة ببدء vendor.
- يتم تنفيذ معظم الأوامر التي تؤثّر في حالة الإعداد الداخلي (مثل بدء الخدمات وإيقافها أو إيقافها) ضمن عملية الإعداد العادية. يتم إعلام هذه الأوامر بأنّ نصًا برمجيًا خاصًا بالمورّد يستدعيها لتنفيذ معالجة أذونات غير SELinux.
تحتوي حلقة المعالجة الرئيسية لـ init على عملية تحقّق من أنّه إذا تمّت إضافة تعليق توضيحي لتشغيل الأمر في العملية الفرعية الخاصة بالمورّد وكان مصدره نصًا برمجيًا خاصًا بالمورّد، يتم إرسال هذا الأمر من خلال تقنية "التواصل بين العمليات" (IPC) إلى العملية الفرعية الخاصة بالمورّد لبدء المعالجة ، والتي تُنفِّذ الأمر وتُرسِل النتيجة مرة أخرى إلى init.
استخدام ميزة vendor init
يكون خيار Vendor init مفعَّلاً تلقائيًا وتنطبق قيوده على جميع نصوص التشغيل
المتوفّرة في قسم /vendor
. يجب أن تكون عملية إعداد المورّد شفافة
بالنسبة إلى المورّدين الذين لا تحصل نصوصهم البرمجية على إذن الوصول إلى ملفات النظام فقط،
والخصائص، وما إلى ذلك.
ومع ذلك، إذا كانت الأوامر في نص برمجي لمورّد معيّن تنتهك قيود بدء معالجة المورّد، يتعذّر تنفيذ الأوامر. تحتوي الأوامر التي يتعذّر تنفيذها على سطر في سجلّ kernel log (يظهر باستخدام dmesg) من init يشير إلى حدوث خطأ. يصاحب تدقيق SELinux أي أمر تعذّر تنفيذه بسبب سياسة SELinux. مثال على خطأ يتضمّن تدقيق SELinux:
type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0 init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied
إذا تعذّر تنفيذ أمر، يتوفّر خياران:
- إذا تعذّر تنفيذ الأمر بسبب قيود مقصودة (مثل إذا كان الأمر يصل إلى ملف نظام أو سمة)، يجب مجددًا تنفيذه بطريقة متوافقة مع Treble، مع المرور عبر واجهات مستقرة فقط. تمنع قواعد "عدم السماح مطلقًا" إضافة أذونات للوصول إلى ملفات النظام التي ليست جزءًا من ABI الثابت لنظام المورّد.
- إذا كان تصنيف SELinux جديدًا ولم يتم منحه أذونات في
vendor_init.te
النظام أو أذونات مستبعدة من خلال قواعد neverallow ، قد يتم منح التصنيف الجديد أذونات فيvendor_init.te
الخاصة بالجهاز.
بالنسبة إلى الأجهزة التي تعمل بإصدار أقدم من Android 9، يمكن تجاوز قواعد neverallows من خلال
إضافة سمة data_between_core_and_vendor_violators
typeإلى
ملف vendor_init.te
الخاص بالجهاز.
مواقع الرموز
يتوفّر الجزء الأكبر من منطق واجهة برمجة التطبيقات لبدء تشغيل المورّد في system/core/init/subcontext.cpp.
يتوفّر جدول الأوامر في فئة BuiltinFunctionMap
في system/core/init/builtins.cpp
ويتضمّن تعليقات توضيحية تشير إلى ما إذا كان يجب تنفيذ الأمر في عملية subprocess الخاصة بـ
init الخاصة بالبائع.
يتم تقسيم سياسة SEPolicy لبرنامج vendor init على مستوى الدليلَين الخاص (system/sepolicy/private/vendor_init.te) والعام (system/sepolicy/public/vendor_init.te) في system/sepolicy.