توضِّح هذه المقالة كيفية تعامل نظام التشغيل Android مع مشاكل التوافق مع السياسة في عمليات التحديث عبر الهواء للنظام الأساسي، حيث قد تختلف إعدادات SELinux الجديدة للنظام الأساسي عن إعدادات SELinux القديمة الخاصة بالمورّد.
يراعي تصميم سياسة SELinux المستندة إلى Treble التمييز الثنائي
بين سياسة النظام الأساسي وسياسة المورّد، ويصبح المخطّط
أكثر تعقيدًا إذا كانت أقسام المورّد تُنشئ تبعيات، مثل
platform
< vendor
< oem
.
في الإصدار 8.0 من نظام التشغيل Android والإصدارات الأحدث، يتم تقسيم السياسة العامة لنظام SELinux إلى مكوّنات خاصة ومكوّنات عامة. تتألف المكوّنات المتاحة للجميع من السياسة والبنية الأساسية المرتبطة بها، والتي نضمن توفّرها لإصدار المنصة. ستظهر هذه السياسة لكاتبي سياسات المورّدين لتمكينهم من إنشاء ملف سياسة مورّد، والذي يؤدي عند دمجه مع السياسة المقدَّمة من النظام الأساسي إلى إنشاء سياسة تعمل بشكل كامل على الجهاز.
- بالنسبة إلى الإصدارات، سيتم كتابة السياسة العامة للنظام الأساسي التي تم تصديرها على النحو التالي: سمات.
- لتسهيل كتابة السياسة، سيتم تحويل الأنواع التي تم تصديرها إلى سمات ذات إصدارات كجزء من عملية إنشاء السياسة. يمكن أيضًا استخدام الأنواع العامة مباشرةً في قرارات التصنيف المقدَّمة من ملفات السياقات الخاصة بالمورّد.
يحافظ نظام التشغيل Android على تعيين بين الأنواع المحدّدة التي تم تصديرها في سياسة النظام الأساسي والسمات ذات الإصدارات المقابلة لكل إصدار من النظام الأساسي. يضمن ذلك أنّه عند تصنيف العناصر بأحد الأنواع، لن يؤدي ذلك إلى إيقاف السلوك الذي تضمنته السياسة العامة للمنصة في إصدار سابق. ويتم الاحتفاظ بهذا التعيين من خلال إبقاء ملف الربط محدّثًا ل كل إصدار من النظام الأساسي، والذي يحتفظ بمعلومات عضوية السمة لكل نوع يتم تصديره في السياسة العامة.
ملكية العناصر وتصنيفها
عند تخصيص السياسة في Android 8.0 والإصدارات الأحدث، يجب تحديد الملكية بوضوح
لكل عنصر من أجل فصل سياسة المنصة عن سياسة المورّد. على سبيل المثال، إذا كان
يصنِّف المورّد /dev/foo
ثم تصنِّف المنصة
/dev/foo
في عملية OTA لاحقة، سيحدث سلوك غير محدّد. بالنسبة إلى
SELinux، يظهر ذلك على شكل تعارض في التصنيف. يمكن أن تحتوي عقدة الجهاز على
تصنيف واحد فقط يُحدّد التصنيف الذي تم تطبيقه أخيرًا. نتيجة لذلك:
- ستفقد العمليات التي تحتاج إلى الوصول إلى التصنيف الذي لم يتم تطبيقه بنجاح إمكانية الوصول إلى المورد.
- قد تتعطل العمليات التي تحصل على إذن الوصول إلى الملف بسبب إنشاء ملف خاطئ لعقدة الجهاز.
يمكن أن تؤدي خصائص النظام أيضًا إلى حدوث تعارضات في الأسماء قد تؤدي إلى سلوك غير محدّد في النظام (بالإضافة إلى تصنيف SELinux). يمكن أن تحدث تداخلات بين تصنيفات النظام الأساسي والمورّد لأي عنصر يتضمّن تصنيفًا لنظام التشغيل SELinux ، بما في ذلك المواقع والخدمات والعمليات والملفات والمنافذ. لتجنُّب هذه المشاكل، حدِّد ملكية هذه العناصر بوضوح.
بالإضافة إلى تعارض التصنيفات، قد تتعارض أيضًا أسماء أنواع/سمات SELinux. سيؤدي تعارض اسم النوع/السمة دائمًا إلى خطأ في مُجمِّع السياسات.
مساحة أسماء النوع/السمة
لا يسمح SELinux بإعلانات متعددة للنوع أو السمة نفسها. لن يتمّ تجميع السياسة
التي تحتوي على بيانات مكرّرة. لتجنُّب حدوث تعارضات في أسماء الأنواع
والسمات، يجب أن تكون جميع بيانات المورّدين مُحدَّدة النطاق
بدءًا من vendor_
.
type foo, domain; → type vendor_foo, domain;
ملكية تصنيف العمليات وخصائص النظام
وأفضل طريقة لتجنّب حدوث تعارضات في التصنيف هي استخدام مساحات أسماء الخصائص. لتحديد مواقع المنصات بسهولة وتجنُّب تعارض الأسماء عند إعادة تسمية مواقع المنصات التي تم تصديرها أو إضافتها، تأكَّد من أنّ جميع مواقع المورّدين تحتوي على بادئات خاصة بها:
نوع الموقع | البادئات المقبولة |
---|---|
التحكّم في الخصائص | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor.
|
read-writable | vendor. |
للقراءة فقط | ro.vendor. ro.boot. ro.hardware.
|
دائمة | persist.vendor. |
يمكن للمورّدين مواصلة استخدام ro.boot.*
(التي تأتي من kernel
cmdline) وro.hardware.*
(وهي سمة واضحة مرتبطة بالأجهزة).
يجب أن تحتوي جميع خدمات المورّدين في ملفات init rc على vendor.
للخدمات في ملفات init rc الخاصة بالأقسام غير النظامية. تُطبَّق قواعد مشابهة
على تصنيفات SELinux لمواقع المورّدين (vendor_
لمواقع المورّدين).
ملكية الملف
يشكّل منع تعارض الملفات تحديًا لأنّ سياسة كل من المنصة والمورّد توفّر عادةً تصنيفات لجميع أنظمة الملفات. على عكس تسمية الأنواع، لا يكون وضع مساحة اسم للملفات عمليًا لأنّه يتم إنشاء العديد منها من قِبل النواة. لمنع حدوث هذه التعارضات، اتّبِع إرشادات التسمية لأنظمة الملفات في هذا القسم. بالنسبة إلى نظام Android 8.0، هذه اقتراحات بدون تنفيذ فني. في المستقبل، سيتم فرض هذه الاقتراحات من خلال مجموعة اختبار المورّد (VTS).
النظام (/system)
يجب أن تقدّم صورة النظام فقط تصنيفات لمكوّنات /system
من خلال file_contexts
وservice_contexts
وما إلى ذلك. في حال إضافة تصنيفات
لمكوّنات /system
في سياسة /vendor
، قد لا يكون
تحديث OTA للإطار فقط ممكنًا.
المورّد (/vendor)
تُصنِّف سياسة SELinux في AOSP حاليًا أجزاء من vendor
التقسيم
التي تتفاعل معها المنصة، ما يتيح كتابة قواعد SELinux لعمليات
المنصة كي تتمكّن من التواصل و/أو الوصول إلى أجزاء من vendor
التقسيم. أمثلة:
مسار /vendor |
التصنيف المقدَّم من المنصة | عمليات النظام الأساسي حسب التصنيف |
---|---|---|
/vendor(/.*)?
|
vendor_file
|
جميع عملاء HAL في إطار العمل وueventd وما إلى ذلك
|
/vendor/framework(/.*)?
|
vendor_framework_file
|
dex2oat وappdomain وما إلى ذلك
|
/vendor/app(/.*)?
|
vendor_app_file
|
dex2oat وinstalld وidmap وما إلى ذلك
|
/vendor/overlay(/.*)
|
vendor_overlay_file
|
system_server وzygote وidmap وما إلى ذلك
|
نتيجةً لذلك، يجب اتّباع قواعد محدّدة (يتم فرضها من خلال
neverallows
) عند تصنيف ملفات إضافية في القسم vendor
:
- يجب أن يكون
vendor_file
هو التصنيف التلقائي لجميع الملفات في القسمvendor
. تتطلّب سياسة المنصة ذلك للوصول إلى عمليات تنفيذ HAL للمرور. - يجب أن تحتوي جميع
exec_types
الجديدة التي تمت إضافتها إلى قسمvendor
من خلال سياسة SEPolicy الخاصة بالمورّد على سمةvendor_file_type
. يتم فرض ذلك من خلال neverallows. - لتجنُّب حدوث تعارضات مع تحديثات المنصة أو الإطار في المستقبل، تجنَّب تصنيف
ملفات غير
exec_types
في قسمvendor
. - يجب أن تكون جميع متطلّبات المكتبة لواجهة برمجة التطبيقات (HAL) لعملية AOSP نفسها التي تم تحديدها في AOSP
مُصنَّفة على أنّها
same_process_hal_file.
.
Procfs (/proc)
يمكن تصنيف الملفات في /proc
باستخدام تصنيف genfscon
فقط. في Android 7.0، كانت كل من سياسة
النظام الأساسي
وسياسة المورّد
تستخدِم genfscon
لتصنيف الملفات في procfs
.
اقتراح: تصنيفات سياسات المنصة فقط /proc
.
إذا كانت عمليات vendor
تحتاج إلى الوصول إلى الملفات في /proc
التي
تم تصنيفها حاليًا باستخدام التصنيف التلقائي (proc
)، يجب ألا تحدّد سياسة المورّد
تصنيفًا صريحًا لها، بل يجب استخدام النوع العام
proc
بدلاً من ذلك لإضافة قواعد لنطاقات المورّدين. يتيح ذلك لتعديلات المنصة acomodate واجهات kernel المستقبلية التي يتم عرضها من خلال
procfs
وتصنيفها بوضوح حسب الحاجة.
Debugfs (/sys/kernel/debug)
يمكن تصنيف Debugfs
في كل من file_contexts
و
genfscon
. في الإصدارات من Android 7.0 إلى Android 10، يتم استخدام تصنيف كل من النظام الأساسي والمورّد
debugfs
.
في Android 11، لا يمكن
الوصول إلى debugfs
أو تثبيته على الأجهزة العلنية. على الشركات المصنّعة للأجهزة
إزالة debugfs
.
Tracefs (/sys/kernel/debug/tracing)
يمكن تصنيف Tracefs
في كل من file_contexts
و
genfscon
. في Android 7.0، تظهر تصنيفات المنصة فقط
tracefs
.
اقتراح: يمكن فقط للمنصة تصنيف tracefs
.
Sysfs (/sys)
يمكن تصنيف الملفات في /sys
باستخدام كل من file_contexts
وgenfscon
. في Android 7.0، يستخدم كلّ من النظام الأساسي والمورّد
genfscon
لتصنيف الملفات في sysfs
.
اقتراح: قد تصنّف المنصة sysfs
العقد التي لا تكون خاصة بالأجهزة. بخلاف ذلك، يمكن فقط للمورّد تصنيف الملفات.
tmpfs (/dev)
قد يتم تصنيف الملفات في /dev
ضمن file_contexts
. في
Android 7.0، يمكنك العثور على ملفَي تصنيف النظام الأساسي والمورّد هنا.
اقتراح: يمكن أن يصنّف المورّد الملفات فقط في
/dev/vendor
(على سبيل المثال، /dev/vendor/foo
،
/dev/vendor/socket/bar
).
Rootfs (/)
قد يتم تصنيف الملفات في /
ضمن file_contexts
. في الإصدار 7.0 من نظام التشغيل Android، يمكنك العثور على كل من ملفات تصنيف المورّد والمنصة هنا.
اقتراح: يمكن للنظام فقط تصنيف الملفات في /
.
البيانات (/data)
يتم تصنيف البيانات من خلال تركيبة من file_contexts
و
seapp_contexts
.
اقتراح: لا تسمح بتصنيف المورّد خارج
/data/vendor
. يمكن للمنصة فقط تصنيف الأجزاء الأخرى من
/data
.
إصدار تصنيفات Genfs
اعتبارًا من المستوى 202504 لواجهة برمجة التطبيقات الخاصة بالمطوّر، تكون تصنيفات SELinux
الأحدث التي تم تعيينها باستخدام genfscon
في
system/sepolicy/compat/plat_sepolicy_genfs_{ver}.cil
اختيارية لأقسام المطوّر
القديمة. يتيح ذلك لأقسام المورّدين القديمة الاحتفاظ بتنفيذ SEPolicy الحالي. يتم التحكّم في
هذا الإعداد من خلال المتغيّر BOARD_GENFS_LABELS_VERSION
في Makefile والذي يتم تخزينه في
/vendor/etc/selinux/genfs_labels_version.txt
.
مثال:
-
في مستوى واجهة برمجة التطبيقات الخاص بالمورّد 202404، يتم تصنيف عقدة
/sys/class/udc
على أنّهاsysfs
تلقائيًا. -
اعتبارًا من مستوى واجهة برمجة التطبيقات 202504 لدى المورّد، يتم تصنيف
/sys/class/udc
على أنّهsysfs_udc
.
ومع ذلك، قد تكون /sys/class/udc
قيد الاستخدام من قِبل أقسام المورّدين التي تستخدم مستوى واجهة برمجة التطبيقات 202404،
إما باستخدام التصنيف التلقائي sysfs
أو تصنيف خاص بالمورّد. قد يؤدي وضع تصنيف /sys/class/udc
على sysfs_udc
بدون قيد أو شرط إلى إيقاف التوافق مع أقسام
المورّدين هذه. من خلال وضع علامة في المربّع BOARD_GENFS_LABELS_VERSION
، تستمر المنصة في استخدام
التصنيفات والأذونات السابقة لأقسام المورّدين القديمة.
يمكن أن يكون BOARD_GENFS_LABELS_VERSION
أكبر من أو يساوي مستوى واجهة برمجة التطبيقات الخاصة بالمورّد. على سبيل المثال، يمكن أن تضبط أقسام المورّدين التي تستخدم المستوى 202404 من واجهة برمجة التطبيقات القيمة BOARD_GENFS_LABELS_VERSION
على 202504 لاعتماد التصنيفات الجديدة التي تم تقديمها في 202504. اطّلِع على قائمة
تصنيفات genfs الخاصة بـ 202504.
عند تصنيف عقد genfscon
، يجب أن تأخذ المنصة في الاعتبار أقسام المورّدين القديمة
وتطبّق آليات النسخ الاحتياطي للتوافق عند الحاجة. يمكن أن تستخدم المنصة مكتبات
مخصّصة للمنصة فقط لطلب معلومات عن إصدار تصنيفات genfs.
-
في الإعلانات المدمجة مع المحتوى، استخدِم
libgenfslabelsversion
. يُرجى الاطّلاع علىgenfslabelsversion.h
للحصول على ملف العنوان الخاص بـlibgenfslabelsversion
. -
في Java، استخدِم
android.os.SELinux.getGenfsLabelsVersion()
.
سمات التوافق
سياسة SELinux هي تفاعل بين نوعَي المصدر والهدف لفئَين محدّدتَين من فئات الكائنات والأذونات. قد يكون لكل عنصر (عمليات وملفات وما إلى ذلك) متأثر بسياسة SELinux نوع واحد فقط، ولكن قد يكون لهذا النوع سمات متعدّدة.
تم صياغة السياسة بشكل أساسي من حيث الأنواع الحالية:
allow source_type target_type:target_class permission(s);
ويعود ذلك إلى أنّ السياسة قد تمّ إعدادها مع الأخذ في الاعتبار جميع الأنواع. ومع ذلك، إذا كانت سياسة المورّد وسياسة المنصة تستخدمان أنواعًا معيّنة، وتغيّر تصنيف عنصر معيّن في إحدى هاتين السياستَين فقط، قد تحتوي السياسة الأخرى على سياسة اكتسبت إذن الوصول أو فقدته في السابق. مثلاً:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
يمكن تغييرها إلى:
File_contexts: /sys/A u:object_r:sysfs_A:s0
على الرغم من أنّ سياسة المورّد ستظلّ كما هي، سيفقد v_domain
إذن الوصول بسبب عدم توفّر سياسة لنوع sysfs_A
الجديد.
من خلال تحديد سياسة من حيث السمات، يمكننا منح الكائن الأساسي نوعًا يحتوي على سمة تتوافق مع السياسة لكل من المنصة ورمز المورّد. ويمكن إجراء ذلك لجميع الأنواع لإنشاء سياسة سمات بشكل فعّال لا يتم فيه استخدام أنواع محدّدة أبدًا. من الناحية العملية، لا يكون ذلك مطلوبًا إلا لأجزاء السياسة التي تتداخل بين النظام الأساسي والمورّد، والتي يتم تحديدها وتقديمها على أنّها سياسة عامة للنظام الأساسي يتم إنشاؤها كجزء من سياسة المورّد.
إنّ تحديد السياسة العامة كسمات لها إصدارات يحقق هدفين متعلّقين بالتوافق مع السياسة:
- تأكّد من أنّ رمز المورّد لا يزال يعمل بعد تحديث المنصة. يتم تحقيق ذلك من خلال إضافة سمات إلى أنواع محدّدة للكائنات التي تتوافق مع تلك التي يعتمد عليها رمز المورّد، مع الحفاظ على إمكانية الوصول.
- إمكانية إيقاف السياسة نهائيًا: ويتم ذلك من خلال تحديد مجموعات السياسات بوضوح إلى سمات يمكن إزالتها فور إيقاف الإصدار الذي تتوافق معه. يمكن مواصلة تطوير المنصة، مع العِلم أنّ السياسة القديمة لا تزال متوفّرة في سياسة المورّد، وسيتمّت إزالتها تلقائيًا عند الترقية أو في حال الترقية.
إمكانية كتابة السياسات
لتحقيق هدف عدم الحاجة إلى معرفة تغييرات إصدار معيّنة لأجل تطوير
السياسات، يتضمّن الإصدار 8.0 من Android تعيينًا بين أنواع
السياسات المتاحة للجميع على النظام الأساسي والسمات الخاصة بها. تمّ ربط النوع foo
بالسمة foo_vN
، حيث يكون N
هو
الإصدار المستهدَف. يتوافق العنصر vN
مع متغيّر الإنشاء
PLATFORM_SEPOLICY_VERSION
وهو من النوع
MM.NN
، حيث يتوافق MM
مع رقم حزمة SDK الخاصة بالنظام الأساسي
وNN
هو إصدار خاص بسياسات الأمان على النظام الأساسي.
لا يتم إصدار نُسخ من السمات في السياسة العامة، بل تكون متوفّرة كواجهة برمجة تطبيقات يمكن لسياسة المنصة والمورّد الاعتماد عليها للحفاظ على ثبات الواجهة بين القسمين. يمكن لكاتبي سياسات النظام الأساسي والبائعين مواصلة كتابة السياسة على النحو المكتوب حاليًا.
يتم تضمين السياسة العامة للمنصة التي تم تصديرها بتنسيق allow source_foo target_bar:class
perm;
كجزء من سياسة المورّد. أثناء عملية
التجميع (التي تتضمّن
الإصدار المقابل)، يتم تحويلها إلى السياسة التي ستنتقل إلى
جزء المورّد من الجهاز (المعروض في لغة CIL المُحوَّلة):
(allow source_foo_vN target_bar_vN (class (perm)))
وبما أنّ سياسة المورّد لا تسبق المنصة أبدًا، لا يجب أن تهتم بالإصدارات السابقة. ومع ذلك، ستحتاج سياسة المنصة إلى معرفة مدى قدم سياسة المورّد، ويجب أن تتضمّن السمات لأنواعها، وأن تحدّد السياسة المقابلة لسمات الإصدارات.
الاختلافات في السياسات
لا يؤدي إنشاء السمات تلقائيًا عن طريق إضافة _vN
إلى نهاية
كل نوع إلى أيّ إجراء بدون ربط السمات بالأنواع في اختلافات
الإصدارات. يحتفظ نظام التشغيل Android بربط بين إصدارات السمات و
ربط الأنواع بهذه السمات. ويتم ذلك في ملفات الربط
المذكورة أعلاه باستخدام عبارات، مثل (CIL):
(typeattributeset foo_vN (foo))
ترقيات المنصة
يوضّح القسم التالي سيناريوهات ترقيات المنصة.
الأنواع نفسها
يحدث هذا السيناريو عندما لا يغيّر عنصر التصنيفات في إصدارات السياسة.
وينطبق ذلك على نوعَي المصدر والهدف ويمكن الاطّلاع عليه باستخدام
/dev/binder
، الذي يحمل التصنيف binder_device
في جميع
الإصدارات. يتم تمثيلها في السياسة المحوَّلة على النحو التالي:
binder_device_v1 … binder_device_vN
عند الترقية من v1
إلى v2
، يجب أن تتضمن سياسة المنصة
ما يلي:
type binder_device; -> (type binder_device) (in CIL)
في ملف الربط بالإصدار 1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
في ملف الربط بالإصدار 2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
في سياسة المورّد من الإصدار 1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
في سياسة المورّد من الإصدار 2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
أنواع جديدة
يحدث هذا السيناريو عندما تضيف المنصة نوعًا جديدًا، ويمكن أن يحدث ذلك عند إضافة ميزات جديدة أو أثناء تشديد السياسة.
- ميزة جديدة: عندما يصنّف النوع عنصرًا لم يكن موجودًا من قبل (مثل عملية خدمة جديدة)، لا يتفاعل رمز المورّد معه مباشرةً في السابق، لذا لا تتوفّر سياسة مقابلة. لا تحتوي السمة الجديدة التي تتوافق مع النوع على سمة في الإصدار السابق من الملف، وبالتالي لن تحتاج إلى إدخال في ملف الربط الذي يستهدف هذا الإصدار من الملف.
- تعزيز السياسات: عندما يمثّل النوع تشديدًا
للسياسة، يجب أن ترتبط سمة النوع الجديدة بسلسلة من السمات
التي تتوافق مع السلسلة السابقة (على غرار المثال السابق الذي يغيّر
/sys/A
منsysfs
إلىsysfs_A
). يعتمد رمز المورّد على قاعدة تتيح الوصول إلىsysfs
، ويجب أن يتضمّن هذه القاعدة كسمة للنوع الجديد.
عند الترقية من v1
إلى v2
، يجب أن تتضمن سياسة المنصة
ما يلي:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
في ملف الربط بالإصدار 1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
في ملف الربط بالإصدار 2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
في سياسة المورّد من الإصدار 1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
في سياسة المورّد من الإصدار 2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
الأنواع التي تمت إزالتها
يحدث هذا السيناريو (النادر) عند إزالة نوع، ويمكن أن يحدث ذلك عندما يكون العنصر الأساسي:
- يبقى المحتوى معروضًا ولكن يتم تصنيفه بشكل مختلف.
- تمت إزالته من قِبل المنصة
أثناء تخفيف السياسة، تتم إزالة نوع معيّن ويتم منح العنصر الذي يحمل هذا النوع تصنيفًا مختلفًا متوفّرًا حاليًا. يمثّل ذلك دمجًا لعمليات ربط السمات: يجب أن يظلّ بإمكان رمز المورّد الوصول إلى العنصر الأساسي باستخدام السمة التي كان يمتلكها، ولكن يجب أن يتمكّن الآن باقي النظام من الوصول إليه باستخدام سمته الجديدة.
إذا كانت السمة التي تم التبديل إليها جديدة، تكون عملية إعادة التصنيف مماثلة لتلك التي تتم في حالة النوع الجديد، باستثناء أنّه عند استخدام تصنيف حالي، فإنّ إضافة النوع الجديد للسمة القديمة ستؤدي إلى إمكانية الوصول إلى عناصر أخرى تم تصنيفها أيضًا بهذا النوع. وهذا هو ما يفعله النظام الأساسي بشكل أساسي، ويُعدّ ذلك مفاضلة مقبولة للحفاظ على التوافق.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
المثال 1: تصغير الأنواع (إزالة sysfs_A)
عند الترقية من v1
إلى v2
، يجب أن تتضمن سياسة المنصة
ما يلي:
type sysfs; (type sysfs) (in CIL)
في ملف الربط بالإصدار 1 (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
في ملف الربط بالإصدار 2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
في سياسة المورّد من الإصدار 1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
في سياسة المورّد من الإصدار 2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
المثال 2: الإزالة بالكامل (نوع foo)
عند الترقية من v1
إلى v2
، يجب أن تتضمن سياسة المنصة
ما يلي:
# nothing - we got rid of the type
في ملف الربط بالإصدار 1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
في ملف الربط بالإصدار 2 (CIL):
# nothing - get rid of it
في سياسة المورّد من الإصدار 1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
في سياسة المورّد من الإصدار 2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
فئة/أذونات جديدة
يحدث هذا السيناريو عندما تُضيف ترقية المنصة مكوّنات سياسة جديدة
لم تكن متوفّرة في الإصدارات السابقة. على سبيل المثال، عندما أضاف نظام التشغيل Android أداة إدارة ملفّات
servicemanager
التي أنشأت أذونات الإضافة والبحث والعرض
، لم تحصل خدمات الجهاز التي تريد التسجيل في
servicemanager
على الأذونات التي كانت تحتاج إليها ولم تكن متوفرة. في الإصدار 8.0 من نظام التشغيل Android، لا يمكن إلا لسياسة المنصة إضافة فئات
وأذونات جديدة.
للسماح لجميع النطاقات التي كان من الممكن إنشاؤها أو تمديدها بموجب سياسة المورّد باستخدام الفئة الجديدة بدون عائق، يجب أن تتضمّن سياسة المنصة قاعدة مشابهة لما يلي:
allow {domain -coredomain} *:new_class perm;
وقد يتطلّب ذلك أيضًا سياسة تسمح بالوصول إلى جميع أنواع الواجهات (السياسة العامة)، لضمان حصول صورة المورّد على إذن الوصول. إذا أدّى ذلك إلى عدم قبول سياسة الأمان (كما قد يحدث مع تغييرات servicemanager)، قد يتم فرض ترقية من المورّد.
الصف أو الأذونات التي تمت إزالتها
يحدث هذا السيناريو عند إزالة مدير كائن (مثل مدير كائن
ZygoteConnection
) ولا يُفترض أن يتسبب في حدوث مشاكل. يمكن أن تظل فئة "مدير الكائنات" وأذوناته محدّدة في السياسة إلى أن يتوقف "إصدار المورّد" عن استخدامها. ويتم ذلك من خلال إضافة التعريفات
إلى ملف الربط المقابل.
تخصيص المورّد للأنواع الجديدة أو التي تمت إعادة تصنيفها
تشكّل أنواع المورّدين الجديدة جوهر تطوير سياسة المورّدين، لأنّها مطلوبة لوصف العمليات الثنائية والأجهزة والأنظمة الفرعية والبيانات المخزّنة الجديدة. وبهذا المعنى، من الضروري السماح بإنشاء أنواع يحدّدها المورّد.
وبما أنّ سياسة المورّد هي دائمًا الأقدم على الجهاز، ما مِن حاجة إلى
تحويل جميع أنواع المورّدين تلقائيًا إلى سمات في السياسة. لا تعتمد المنصة
على أيّ شيء مصنّف في سياسة المورّد لأنّ المنصة ليس لديها معرفة
بهذا النوع من التصنيفات. ومع ذلك، ستوفّر المنصة السمات والأنواع العامة
التي تستخدمها للتفاعل مع العناصر المصنّفة بهذه الأنواع (مثل
domain
وsysfs_type
وما إلى ذلك). لكي تستمر المنصة في التفاعل بشكل صحيح مع هذه العناصر، يجب تطبيق السمات والأنواع بشكل مناسب، وقد تحتاج إلى إضافة قواعد محدّدة إلى النطاقات القابلة للتخصيص (مثل init
).
تغييرات السمات في Android 9
يمكن للأجهزة التي يتم ترقيتها إلى Android 9 استخدام السمات التالية، ولكن يجب ألا تستخدمها الأجهزة التي تبدأ بتشغيل Android 9.
سمات المخالف
يتضمّن نظام التشغيل Android 9 السمات التالية ذات الصلة بالنطاقات:
-
data_between_core_and_vendor_violators
. سمة لجميع النطاقات التي تنتهك شرط عدم مشاركة الملفات من خلال مسار بينvendor
وcoredomains
. يجب ألا تستخدم عمليات النظام الأساسي وموفّري البرامج ملفات على القرص للتواصل (واجهة برمجة التطبيقات غير المستقرة). اقتراح:- يجب استخدام
/data/vendor
في رمز المورّد. - يجب ألا يستخدم النظام
/data/vendor
.
- يجب استخدام
- سمة
system_executes_vendor_violators
. لجميع نطاقات النظام (باستثناءinit
وshell domains
) التي تنتهك شرط عدم تنفيذ ملفات ثنائية للمورّدين تنفيذ ملفّات ثنائية المصنّع لها واجهة برمجة تطبيقات غير مستقرة. يجب ألا تنفِّذ المنصة ملفّات الثنائيات الخاصة بالمورّد مباشرةً. اقتراح:- يجب أن تكون تبعيات النظام الأساسي هذه على ملفات ثنائية المصنّع متأخرة عن واجهات HIDL HAL.
أو
- يجب نقل
coredomains
التي تحتاج إلى الوصول إلى ملفات ثنائية المورّد إلى قسم المورّد، وبالتالي سيتوقف تطبيقك عن أن يكونcoredomain
.
- يجب أن تكون تبعيات النظام الأساسي هذه على ملفات ثنائية المصنّع متأخرة عن واجهات HIDL HAL.
السمات غير الموثوق بها
يجب ألا تحصل التطبيقات غير الموثوق بها التي تستضيف رمزًا عشوائيًا على إذن الوصول إلى خدمات HwBinder ، باستثناء الخدمات التي يُعتبَر أنّها آمنة بما يكفي للوصول إليها من هذه التطبيقات (راجِع الخدمات الآمنة أدناه). في ما يلي السببان الرئيسيان لذلك:
- لا تُجري خوادم HwBinder مصادقة العميل لأنّ HIDL لا تُظهر حاليًا معلومات UID للمتصل. حتى إذا كانت HIDL تعرض هذه البيانات، فإنّ العديد من خدمات HwBinder تعمل على مستوى أقل من مستوى التطبيقات (مثل واجهات HAL) أو يجب ألا تعتمد على هوية التطبيق للحصول على الإذن. وبالتالي، من أجل ضمان الأمان، فإنّ الافتراض التلقائي هو أنّ كل خدمة HwBinder تتعامل مع جميع عملائها على أنّهم مفوَّضون بالتساوي لتنفيذ العمليات التي تقدّمها الخدمة.
- تحتوي خوادم HAL (مجموعة فرعية من خدمات HwBinder) على رمز برمجي يتضمن معدلًا أعلى
من حدوث مشاكل الأمان مقارنةً بمكونات
system/core
، ويمكنها الوصول إلى الطبقات السفلية من الحزمة (وصولاً إلى الأجهزة)، ما يؤدي بالتالي إلى زيادة فرص تجاوز نموذج أمان Android.
الخدمات الآمنة
تشمل الخدمات الآمنة ما يلي:
same_process_hwservice
. يتم تشغيل هذه الخدمات (بحكم التعريف) في عملية العميل، وبالتالي يكون لها إذن الوصول نفسه الذي يتمتع به نطاق العميل الذي تتم فيه تنفيذ العملية.coredomain_hwservice
. لا تشكل هذه الخدمات أي مخاطر مرتبطة بالأسباب المذكورة في النقطة 2.hal_configstore_ISurfaceFlingerConfigs
. تم تصميم هذه الخدمة خصيصًا لاستخدامها من قِبل أي نطاق.hal_graphics_allocator_hwservice
. توفّر خدمةsurfaceflinger
Binder أيضًا هذه العمليات، ويُسمح للتطبيقات بالوصول إليها.hal_omx_hwservice
: هذا هو إصدار HwBinder منmediacodec
خدمة Binder، والتي يُسمح للتطبيقات بالوصول إليها.hal_codec2_hwservice
. هذا إصدار أحدث منhal_omx_hwservice
.
السمات القابلة للاستخدام
تحتوي جميع hwservices
غير الآمنة على السمة
untrusted_app_visible_hwservice
. تحتوي خوادم HAL المقابلة على
السمة untrusted_app_visible_halserver
. يجب ألّا تستخدم الأجهزة التي تعمل
بنظام التشغيل Android 9 أيًا من سمة
untrusted
.
اقتراح:
- بدلاً من ذلك، يجب أن تتواصل التطبيقات غير الموثوق بها مع خدمة نظام تتواصل بدورها مع
HAL HIDL الخاصة بالمورّد. على سبيل المثال، يمكن للتطبيقات التواصل مع
binderservicedomain
، ثم يتواصلmediaserver
(وهوbinderservicedomain
) بدوره معhal_graphics_allocator
.أو
- يجب أن يكون للتطبيقات التي تحتاج إلى الوصول المباشر إلى واجهات برمجة التطبيقات
vendor
HALs نطاق سياسات الأمان الخاص بها والذي يحدّده المورّد.
اختبارات سمات الملفات
يتضمّن Android 9 اختبارات وقت الإنشاء التي تضمن أن تتضمّن جميع الملفات في مواقع محددة
السمات المناسبة (مثلاً، تتضمّن جميع الملفات في
sysfs
السمة المطلوبة sysfs_type
).
السياسة العامة للمنصة
تشكّل السياسة العامة للمنصة جوهر الامتثال لنموذج بنية Android 8.0
بدون الحفاظ على اتحاد سياسات المنصة
من الإصدار 1 والإصدار 2. يتعرّض المورّدون لمجموعة فرعية من سياسة المنصة التي
تحتوي على أنواع وسمات وقواعد قابلة للاستخدام بشأن هذه الأنواع والسمات
التي تصبح بعد ذلك جزءًا من سياسة المورّد (أي
vendor_sepolicy.cil
).
تتم ترجمة الأنواع والقواعد تلقائيًا في السياسة التي ينشئها المورّد
إلى attribute_vN
بحيث تكون جميع الأنواع التي تقدّمها المنصة
سمات لها إصدارات (مع ذلك، لا يتم إصدار السمات). يتحمّل النظام الأساسي
مسؤولية ربط الأنواع المحدّدة التي يوفّرها بالسمات المناسبة
لضمان استمرار عمل سياسة المورّد وتضمين القواعد
المتوفّرة لإصدار معيّن. إنّ الجمع بين
السياسة العامة للمنصة وسياسة المورّد يلبّي هدف نموذج بنية Android 8.0
المتمثل في السماح بإنشاءات مستقلة للمنصة والمورّد.
الربط بسلاسل السمات
عند استخدام السمات لربطها بإصدارات السياسات، يتم ربط النوع بسمة أو سمات متعدّدة، ما يضمن إمكانية الوصول إلى العناصر المصنّفة بالنوع من خلال السمات المقابلة لأنواعها السابقة.
إنّ الحفاظ على هدف إخفاء معلومات الإصدار عن كاتب السياسة يعني
إنشاء السمات التي تتضمّن معلومات الإصدار تلقائيًا وتخصيصها للأنواع
الملائمة. في الحالة الشائعة للأنواع الثابتة، يكون هذا الأمر بسيطًا:
يتم ربط type_foo
بـ type_foo_v1
.
في حال تغيير تصنيف عنصر مثل sysfs
→ sysfs_A
أو
mediaserver
→ audioserver
، يكون إنشاء عملية الربط هذه
معقدًا (ويكون موضّحًا في الأمثلة أعلاه). على القائمين على صيانة سياسة المنصة تحديد كيفية إنشاء عملية الربط عند نقاط النقل للعناصر، ما يتطلب فهم العلاقة بين العناصر والتسميات المخصّصة لها وتحديد الحالات التي يحدث فيها ذلك. من أجل التوافق مع الإصدارات القديمة، يجب إدارة هذه الصعوبة من جانب المنصة، وهي القسم الوحيد الذي يمكنه التحديث.
الإصدارات السابقة
للتبسيط، يُطلق نظام Android الأساسي إصدارًا من سياسة الأمان عند إنشاء مسار إصدار جديد. كما هو موضّح أعلاه، يتضمّن PLATFORM_SEPOLICY_VERSION
رقم الإصدار ويكون على الشكل MM.nn
، ويشير MM
إلى قيمة حزمة SDK وnn
هي قيمة خاصة يتم الاحتفاظ بها في /platform/system/sepolicy.
. على سبيل المثال، 19.0
لنظام التشغيل Kitkat و21.0
لنظام التشغيل Lollipop و22.0
لنظام التشغيل Lollipop-MR1 و23.0
لنظام التشغيل Marshmallow و24.0
لنظام التشغيل Nougat و25.0
لنظام التشغيل Nougat-MR1 و26.0
لنظام التشغيل Oreo و27.0
لنظام التشغيل Oreo-MR1 و28.0
لنظام التشغيل Android 9.
لا تكون التحديثات دائمًا أعدادًا صحيحة. على سبيل المثال، إذا كان تحديث MR إلى إصدار معيّن يتطلّب إجراء تغيير غير متوافق في
system/sepolicy/public
ولكن ليس تحديث واجهة برمجة التطبيقات، يمكن أن يكون إصدار سياسة الأمان
هذا: vN.1
. الإصدار المتوفر في أحد مشاريع التطوير
هو إصدار لا يتم استخدامه أبدًا في الأجهزة المُرسَلة 10000.0
.
قد يوقف Android الإصدار الأقدم نهائيًا عند ترقية التطبيق. للحصول على معلومات عن الحالات التي يجب فيها إيقاف إصدار نهائيًا، قد يجمع نظام Android عدد الأجهزة التي تعمل بإصدار Android هذا وتستوفي سياسة المورّد وتتلقّى تحديثات مهمة لنظام التشغيل. وإذا كان العدد أقل من حدّ معيّن، يتم إيقاف هذا الإصدار نهائيًا.
تأثير الأداء للسمات المتعدّدة
على النحو الموضّح في https://github.com/SELinuxProject/cil/issues/9، يؤدي تحديد عدد كبير من السمات لنوع معيّن إلى حدوث مشاكل في الأداء في حال عدم توفّر ذاكرة التخزين المؤقت للسياسة.
تم تأكيد أنّ هذه مشكلة في Android، لذا تم إجراء تغييرات على Android 8.0 لإزالة السمات التي أضافها compilador السياسة إلى السياسة، بالإضافة إلى إزالة السمات غير المستخدَمة. أدّت هذه التغييرات إلى حلّ مشكلات تدهور الأداء.
نظام_خارجي السياسة العامة للمنتجات والسياسة العامة
بدءًا من Android 11، يُسمح لقسمَي system_ext
وproduct
ب
تصدير أنواعهما العامة المحدّدة إلى قسم المورّد. مثل سياسة العلن
المتعلقة بالمنصة، يستخدم المورّد أنواعًا وقواعد يتم تحويلها تلقائيًا إلى
السمات التي تتضمّن إصدارًا، على سبيل المثال، من type
إلى
type_N
، حيث يكون N
هو إصدار
المنصة التي تم إنشاء قسم المورّد وفقًا لها.
عندما تستند القسمَين system_ext
وproduct
إلى إصدار النظام الأساسي نفسه
N
، ينشئ نظام الإنشاء ملفات ربط أساسية لملفَي system_ext/etc/selinux/mapping/N.cil
و
product/etc/selinux/mapping/N.cil
، اللذَين يحتويان على عمليات ربط هوية
من type
إلى type_N
. يمكن للمورّد
الوصول إلى type
باستخدام السمة التي تتضمّن إصدارًا type_N
.
في حال تعديل قسمَي system_ext
وproduct
فقط، مثلاً من N
إلى N+1
(أو إصدار أحدث)، بينما يبقى القسم المخصّص للمورّد على N
، قد يفقد المورّد إمكانية الوصول إلى أنواع قسمَي system_ext
وproduct
. لمنع حدوث أي مشاكل، يجب أن توفّر أقسام
system_ext
وproduct
ملفات ربط من الأنواع
المحددة إلى سمات type_N
. يكون كل شريك
مسؤولاً عن صيانة ملفات الربط، إذا كان سيوفّر N
للمورّد باستخدام N+1
(أو إصدار أحدث)
system_ext
وproduct
.
ولإجراء ذلك، على الشركاء:
- انسخ ملفات الربط الأساسية التي تم إنشاؤها من قسمَي
N
system_ext
وproduct
إلى شجرة المصدر. - عدِّل ملفات الربط حسب الحاجة.
-
ثبِّت
ملفّات الربط على قسمَي
system_ext
وproduct
فيN+1
(أو إصدار أحدث).
على سبيل المثال، لنفترض أنّ N
system_ext
يحتوي على نوع واحد علني
يُسمى foo_type
. بعد ذلك، سيظهر system_ext/etc/selinux/mapping/N.cil
في القسم N
system_ext
على النحو التالي:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
في حال إضافة bar_type
إلى N+1
system_ext،
وإذا كان يجب ربط bar_type
بـ foo_type
لأجل
N
المورّد، يمكن تعديل N.cil
من
(typeattributeset foo_type_N (foo_type))
إلى
(typeattributeset foo_type_N (foo_type bar_type))
ثم تم تثبيته على قسم N+1
system_ext.
يمكن لمورّد N
مواصلة الوصول إلى foo_type
وbar_type
في N+1
system_ext.
تصنيف سياقات SELinux
لدعم التمييز بين سياسة أمان نظام التشغيل والمورّد، يُنشئ النظام ملفات سياق SELinux بشكلٍ مختلف لإبقائها منفصلة.
سياقات الملفات
أدخل نظام Android 8.0 التغييرات التالية على file_contexts
:
- لتجنُّب زيادة وقت الترجمة على الجهاز أثناء بدء التشغيل،
file_contexts
لن يعود متوفّرًا بالتنسيق الثنائي. بدلاً من ذلك، هي ملفات نصية قابلة للقراءة للتعبيرات العادية، مثل{property, service}_contexts
(كما كانت في الإصدارات السابقة من 7.0). - يتم تقسيم
file_contexts
بين ملفين:plat_file_contexts
- نظام التشغيل Android
file_context
الذي لا يحتوي على علامات خاصة بالجهاز، باستثناء تصنيف أجزاء من القسم/vendor
التي يجب تصنيفها بدقة لضمان العمل السليم لملفات sepolicy - يجب أن تكون مضمّنة في القسم
system
في العنوان/system/etc/selinux/plat_file_contexts
على الجهاز ويحمّلهاinit
في البداية مع المورّدfile_context
.
- نظام التشغيل Android
vendor_file_contexts
file_context
خاص بالجهاز تم إنشاؤه من خلال دمجfile_contexts
المتوفّرة في الأدلة التي تشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز- يجب تثبيته في ملف
/vendor/etc/selinux/vendor_file_contexts
في القسم vendor
وتحميله بواسطة init
في البداية مع المنصة file_context
.
سياقات المواقع
في Android 8.0، يتم تقسيم property_contexts
بين ملفين:
plat_property_contexts
- نظام التشغيل Android
property_context
الذي لا يحتوي على تصنيفات خاصة بالأجهزة - يجب أن يكون مضمّنًا في القسم
system
في العنوان/system/etc/selinux/plat_property_contexts
وأن يتم تحميله بواسطةinit
في البداية مع المورّدproperty_contexts
.
- نظام التشغيل Android
vendor_property_contexts
property_context
خاص بالجهاز تم إنشاؤه من خلال دمجproperty_contexts
المتوفّرة في الأدلة التي تشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز- يجب أن يكون مضمّنًا في القسم
vendor
في/vendor/etc/selinux/vendor_property_contexts
وأن يتم carregarه من قِبلinit
في البداية مع النظام الأساسيproperty_context
سياقات الخدمة
في Android 8.0، يتم تقسيم service_contexts
بينملفَين التاليين:
plat_service_contexts
service_context
المخصّصة لنظام Android الأساسيservicemanager
لا يحتويservice_context
على تصنيفات خاصة بالأجهزة.- يجب أن يكون مضمّنًا في قسم
system
في العنوان/system/etc/selinux/plat_service_contexts
وأن يتم تحميله بواسطةservicemanager
في البداية مع المورّدservice_contexts
.
vendor_service_contexts
service_context
خاص بالجهاز تم إنشاؤه من خلال دمجservice_contexts
المتوفّرة في الأدلة التي تشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز- يجب أن يكون مضمّنًا في القسم
vendor
في/vendor/etc/selinux/vendor_service_contexts
وأن يتم تحميله بواسطةservicemanager
في البداية مع النظام الأساسيservice_contexts
. - على الرغم من أنّ
servicemanager
يبحث عن هذا الملف في وقت التشغيل، يجب ألّا يكونvendor_service_contexts
متوفّرًا في جهازTREBLE
متوافق تمامًا. ويرجع ذلك إلى أنّه يجب أن يتم من خلالhwservicemanager
/hwbinder
كل التفاعل بين عمليةvendor
وعمليةsystem
.
plat_hwservice_contexts
- نظام التشغيل Android
hwservice_context
لنظام التشغيلhwservicemanager
الذي لا يتضمّن تصنيفات خاصة بالأجهزة - يجب أن تكون مضمّنة في القسم
system
في العنوان/system/etc/selinux/plat_hwservice_contexts
وأن يتم تحميلها بواسطةhwservicemanager
في البداية معvendor_hwservice_contexts
.
- نظام التشغيل Android
vendor_hwservice_contexts
hwservice_context
خاص بالجهاز تم إنشاؤه من خلال دمجhwservice_contexts
المتوفّرة في الأدلة التي تشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز- يجب أن تكون مضمّنة في القسم
vendor
في العنوان/vendor/etc/selinux/vendor_hwservice_contexts
وأن يتم carregarla من خلالhwservicemanager
في البداية معplat_service_contexts
.
vndservice_contexts
service_context
خاص بالجهاز لملفvndservicemanager
تم إنشاؤه من خلال دمجvndservice_contexts
المتوفّرة في الأدلة التي يشير إليهاBOARD_SEPOLICY_DIRS
فيBoardconfig.mk
الجهاز- يجب أن يكون هذا الملف مضمّنًا في قسم
vendor
في /vendor/etc/selinux/vndservice_contexts
وأن يتم تحميله بواسطة vndservicemanager
في البداية.
سياقات Seapp
في Android 8.0، يتم تقسيم seapp_contexts
بين ملفين:
plat_seapp_contexts
- نظام التشغيل Android
seapp_context
الذي لا يتضمّن تغييرات تخصّ الجهاز - يجب أن يكون مثبّتًا في القسم
system
على العنوان/system/etc/selinux/plat_seapp_contexts.
- نظام التشغيل Android
vendor_seapp_contexts
- إضافة خاصة بالجهاز لمنصّة
seapp_context
تم إنشاؤها من خلال دمجseapp_contexts
المتوفّرة في الدلائل التي يشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز - يجب أن يكون مثبّتًا في القسم
vendor
على العنوان/vendor/etc/selinux/vendor_seapp_contexts
.
- إضافة خاصة بالجهاز لمنصّة
أذونات MAC
في Android 8.0، يتم تقسيم mac_permissions.xml
بين ملفين:
- النظام الأساسي
mac_permissions.xml
- نظام التشغيل Android
mac_permissions.xml
الذي لا يتضمّن تغييرات خاصة بالجهاز - يجب أن يكون مثبّتًا في القسم
system
على العنوان/system/etc/selinux/.
- نظام التشغيل Android
- غير مرتبطة بمنصّة معيّنة
mac_permissions.xml
- إضافة خاصة بالجهاز إلى النظام الأساسي
mac_permissions.xml
تم إنشاؤها منmac_permissions.xml
في الأدلة التي يشير إليهاBOARD_SEPOLICY_DIRS
في ملفاتBoardconfig.mk
على الجهاز - يجب أن يكون مثبّتًا في القسم
vendor
على العنوان/vendor/etc/selinux/.
- إضافة خاصة بالجهاز إلى النظام الأساسي