توضح هذه المقالة كيفية تعامل Android مع مشكلات توافق السياسة مع أجهزة OTA الخاصة بالنظام الأساسي، حيث قد تختلف إعدادات SELinux للنظام الأساسي الجديد عن إعدادات SELinux الخاصة بالمورد القديم.
يأخذ تصميم سياسة SELinux المستندة إلى Treble في الاعتبار التمييز الثنائي بين النظام الأساسي وسياسة البائع ؛ يصبح المخطط أكثر تعقيدًا إذا قامت أقسام البائع بإنشاء تبعيات، مثل platform
< vendor
< oem
.
في Android 8.0 والإصدارات الأحدث، تنقسم سياسة SELinux العالمية إلى مكونات خاصة وعامة. تتكون المكونات العامة من السياسة والبنية الأساسية المرتبطة بها، والتي نضمن توفرها لإصدار النظام الأساسي. سيتم عرض هذه السياسة لكتاب سياسة البائع لتمكين البائعين من إنشاء ملف سياسة البائع، والذي عند دمجه مع السياسة المقدمة من النظام الأساسي، يؤدي إلى سياسة كاملة الوظائف للجهاز.
- بالنسبة للإصدارات، ستتم كتابة السياسة العامة للمنصة المُصدَّرة على هيئة سمات .
- لتسهيل كتابة السياسة، سيتم تحويل الأنواع المصدرة إلى سمات ذات إصدار كجزء من عملية بناء السياسة. يمكن أيضًا استخدام الأنواع العامة مباشرةً في قرارات التصنيف التي توفرها ملفات سياقات البائع.
يحتفظ Android بالتخطيط بين الأنواع المحددة المصدرة في سياسة النظام الأساسي وسمات الإصدار المقابلة لكل إصدار من إصدار النظام الأساسي . وهذا يضمن أنه عندما يتم تصنيف الكائنات بنوع ما، فإن ذلك لا يكسر السلوك الذي تضمنه السياسة العامة للنظام الأساسي في إصدار سابق. يتم الحفاظ على هذا التعيين من خلال تحديث ملف التعيين لكل إصدار من إصدارات النظام الأساسي ، والذي يحافظ على معلومات عضوية السمات لكل نوع مُصدَّر في السياسة العامة.
ملكية الكائنات ووضع العلامات عليها
عند تخصيص السياسة في Android 8.0 والإصدارات الأحدث، يجب تحديد الملكية بوضوح لكل كائن للحفاظ على الفصل بين النظام الأساسي وسياسة البائع. على سبيل المثال، إذا قام البائع بتسمية /dev/foo
ثم قام النظام الأساسي بتسمية /dev/foo
في OTA لاحقة، فسيكون هناك سلوك غير محدد. بالنسبة لـ SELinux، يظهر هذا على شكل تصادم في العلامات. يمكن أن تحتوي عقدة الجهاز على تسمية واحدة فقط والتي يتم حلها على أي تسمية يتم تطبيقها أخيرًا. نتيجة ل:
- العمليات التي تحتاج إلى الوصول إلى التصنيف الذي تم تطبيقه بشكل غير ناجح ستفقد الوصول إلى المورد.
- قد تنقطع العمليات التي يمكنها الوصول إلى الملف بسبب إنشاء عقدة الجهاز الخاطئة.
تتمتع خصائص النظام أيضًا بإمكانية تسمية التصادمات التي قد تؤدي إلى سلوك غير محدد على النظام (وكذلك تسمية SELinux). يمكن أن يحدث تعارض بين تسميات النظام الأساسي والبائعين لأي كائن يحمل علامة SELinux، بما في ذلك الخصائص والخدمات والعمليات والملفات والمقابس. لتجنب هذه المشكلات، حدد بوضوح ملكية هذه الكائنات.
بالإضافة إلى تضارب الملصقات، قد تتعارض أيضًا أسماء أنواع/سمات SELinux. سيؤدي تضارب اسم النوع/السمة دائمًا إلى حدوث خطأ في برنامج التحويل البرمجي للسياسة.
مساحة اسم النوع/السمة
لا يسمح SELinux بإعلانات متعددة من نفس النوع/السمة. سوف يفشل تجميع السياسة التي تحتوي على إعلانات مكررة. لتجنب تضارب أسماء النوع والسمة، يجب أن تكون جميع إعلانات البائعين ذات مساحة اسم تبدأ بـ np_
.
type foo, domain; → type np_foo, domain;
خاصية النظام وملكية وضع العلامات على العملية
من الأفضل حل مشكلة تجنب تضارب العلامات باستخدام مساحات أسماء الخصائص. للتعرف بسهولة على خصائص النظام الأساسي وتجنب تعارض الأسماء عند إعادة تسمية أو إضافة خصائص النظام الأساسي المصدر، تأكد من أن جميع خصائص البائع لها بادئات خاصة بها:
نوع الملكية | البادئات المقبولة |
---|---|
خصائص التحكم | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
للقراءة والكتابة | 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
من خلال file_contexts
و service_contexts
وما إلى ذلك. إذا تمت إضافة تسميات لمكونات /system
في سياسة /vendor
، فقد لا يكون التحديث عبر الهواء لإطار العمل فقط ممكنًا.
بائع (/بائع)
تقوم سياسة AOSP SELinux بالفعل بتسمية أجزاء من قسم 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
. - يجب تسمية كافة تبعيات المكتبة لنفس العمليات التي تم تحديدها من قبل AOSP باسم
same_process_hal_file.
بروكس (/بروك)
قد يتم تصنيف الملفات الموجودة في /proc
باستخدام علامة genfscon
فقط. في Android 7.0، استخدم كل من النظام الأساسي وسياسة البائع genfscon
لتسمية الملفات في procfs
.
توصية: فقط تسميات سياسة النظام الأساسي /proc
. إذا كانت عمليات vendor
تحتاج إلى الوصول إلى الملفات الموجودة في /proc
والتي تم تصنيفها حاليًا بالتسمية الافتراضية ( proc
)، فيجب ألا تقوم سياسة البائع بتسميتها بشكل صريح ويجب بدلاً من ذلك استخدام نوع proc
العام لإضافة قواعد لنطاقات البائع. يتيح ذلك لتحديثات النظام الأساسي استيعاب واجهات kernel المستقبلية المكشوفة من خلال procfs
وتصنيفها بشكل صريح حسب الحاجة.
تصحيح الأخطاء (/sys/kernel/debug)
يمكن تصنيف Debugfs
في كل من file_contexts
و genfscon
. في الإصدار Android 7.0 إلى Android 10، debugfs
كل من النظام الأساسي وتصنيف البائع.
في Android 11، لا يمكن الوصول إلى debugfs
أو تثبيتها على أجهزة الإنتاج. يجب على الشركات المصنعة للأجهزة إزالة debugfs
.
آثار التتبع (/sys/kernel/debug/tracing)
يمكن تصنيف Tracefs
في كل من file_contexts
و genfscon
. في Android 7.0، يقوم النظام الأساسي فقط بوضع tracefs
.
توصية: النظام الأساسي فقط هو الذي يمكنه تصنيف tracefs
.
سيفس (/ سيس)
يمكن تسمية الملفات الموجودة في /sys
باستخدام كل من file_contexts
و genfscon
. في Android 7.0، يستخدم كل من النظام الأساسي والمورد file_contexts
و genfscon
لتسمية الملفات في sysfs
.
توصية: قد يقوم النظام الأساسي بتسمية عقد sysfs
غير الخاصة بالجهاز. بخلاف ذلك، يجوز للمورد فقط تسمية الملفات.
تمبفس (/ ديف)
قد يتم تصنيف الملفات الموجودة في /dev
في file_contexts
. في Android 7.0، توجد ملفات تسمية النظام الأساسي والبائعين هنا.
توصية: يجوز للمورد تسمية الملفات الموجودة في /dev/vendor
فقط (على سبيل المثال، /dev/vendor/foo
، /dev/vendor/socket/bar
).
الجذور (/)
قد يتم تصنيف الملفات الموجودة في /
في file_contexts
. في Android 7.0، توجد ملفات تسمية النظام الأساسي والبائعين هنا.
توصية: يمكن للنظام فقط تصنيف الملفات بتنسيق /
.
البيانات (/ البيانات)
يتم تصنيف البيانات من خلال مجموعة من file_contexts
و seapp_contexts
.
توصية: عدم السماح بتسمية البائع خارج /data/vendor
. يمكن للنظام الأساسي فقط تسمية أجزاء أخرى من /data
.
سمات التوافق
سياسة 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
الجديد.
من خلال تحديد سياسة من حيث السمات، يمكننا إعطاء الكائن الأساسي نوعًا يحتوي على سمة تتوافق مع السياسة لكل من النظام الأساسي ورمز البائع. يمكن القيام بذلك لجميع الأنواع لإنشاء سياسة سمات بشكل فعال حيث لا يتم استخدام الأنواع الملموسة أبدًا. من الناحية العملية، يكون هذا مطلوبًا فقط لأجزاء السياسة التي تتداخل بين النظام الأساسي والبائع، والتي يتم تعريفها وتوفيرها كسياسة عامة للنظام الأساسي والتي يتم إنشاؤها كجزء من سياسة البائع.
إن تعريف السياسة العامة كسمات منقحة يلبي هدفين من أهداف توافق السياسة:
- تأكد من استمرار عمل رمز البائع بعد تحديث النظام الأساسي . يتم تحقيق ذلك عن طريق إضافة سمات إلى الأنواع الملموسة للكائنات المطابقة لتلك التي يعتمد عليها كود البائع، مع الحفاظ على الوصول.
- القدرة على إهمال السياسة . يتم تحقيق ذلك من خلال تحديد مجموعات السياسات بوضوح في سمات يمكن إزالتها بمجرد أن يصبح الإصدار الذي تتوافق معه غير مدعوم. يمكن أن يستمر التطوير في النظام الأساسي، مع العلم أن السياسة القديمة لا تزال موجودة في سياسة البائع وسيتم إزالتها تلقائيًا عند/في حالة الترقية.
إمكانية كتابة السياسة
لتحقيق هدف عدم طلب المعرفة بتغييرات محددة في الإصدار لتطوير السياسة، يتضمن Android 8.0 تعيينًا بين أنواع السياسات العامة للنظام الأساسي وسماتها. يتم تعيين النوع foo
للسمة foo_v N
، حيث N
هو الإصدار المستهدف. يتوافق vN
مع متغير البناء PLATFORM_SEPOLICY_VERSION
وهو بالصيغة MM.NN
، حيث يتوافق MM
مع رقم SDK للنظام الأساسي و NN
عبارة عن إصدار خاص بسياسة النظام الأساسي.
لا يتم إصدار السمات في السياسة العامة، بل توجد كواجهة برمجة التطبيقات (API) التي يمكن بناء النظام الأساسي وسياسة البائع عليها للحفاظ على استقرار الواجهة بين القسمين. يمكن لكاتبي سياسة النظام الأساسي والبائعين الاستمرار في كتابة السياسة كما هي مكتوبة اليوم.
تم تصدير السياسة العامة للنظام الأساسي على النحو allow source_foo target_bar: class perm ;
يتم تضمينه كجزء من سياسة البائع. أثناء التجميع (الذي يتضمن الإصدار المقابل) يتم تحويله إلى السياسة التي ستنتقل إلى جزء البائع من الجهاز (كما هو موضح في اللغة الوسيطة المشتركة المحولة (CIL)):
(allow source_foo_vN target_bar_vN (class (perm)))
نظرًا لأن سياسة البائع لا تتقدم أبدًا على النظام الأساسي، فلا ينبغي أن تهتم بالإصدارات السابقة. ومع ذلك، ستحتاج سياسة النظام الأساسي إلى معرفة مدى رجعية سياسة البائع، وتضمين السمات لأنواعها، وتعيين السياسة المقابلة للسمات التي تم إصدارها.
اختلافات السياسة
إن إنشاء السمات تلقائيًا عن طريق إضافة _v N
إلى نهاية كل نوع لا يفعل شيئًا دون تعيين السمات إلى الأنواع عبر اختلافات الإصدار. يحتفظ 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)
في ملف التعيين v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
في ملف تعيين v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
في سياسة البائعين v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
في سياسة البائعين v2 (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)
في ملف التعيين v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
في ملف تعيين v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
في سياسة البائعين v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
في سياسة البائعين v2 (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)
في ملف التعيين v1 (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))
في ملف تعيين v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
في سياسة البائعين v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
في سياسة البائعين v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
مثال الإصدار 2: الإزالة الكاملة (نوع foo)
عند الترقية من v1
→ v2
، يجب أن تحتوي سياسة النظام الأساسي على:
# nothing - we got rid of the type
في ملف التعيين v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
في ملف تعيين v2 (CIL):
# nothing - get rid of it
في سياسة البائعين v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
في سياسة البائعين v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
فئة/أذونات جديدة
يحدث هذا السيناريو عندما تقدم ترقية النظام الأساسي مكونات سياسة جديدة غير موجودة في الإصدارات السابقة. على سبيل المثال، عندما أضاف Android مدير كائنات servicemanager
الذي أنشأ أذونات الإضافة والبحث والقائمة، احتاجت برامج البائعين التي تريد التسجيل في servicemanager
إلى أذونات لم تكن متوفرة. في Android 8.0، يمكن لسياسة النظام الأساسي فقط إضافة فئات وأذونات جديدة.
للسماح لجميع المجالات التي كان من الممكن إنشاؤها أو توسيعها بواسطة سياسة البائع لاستخدام الفئة الجديدة دون عائق، تحتاج سياسة النظام الأساسي إلى تضمين قاعدة مشابهة لما يلي:
allow {domain -coredomain} *:new_class perm;
قد يتطلب هذا أيضًا سياسة تسمح بالوصول لجميع أنواع الواجهة (السياسة العامة)، للتأكد من حصول صورة البائع على حق الوصول. إذا أدى ذلك إلى سياسة أمان غير مقبولة (كما قد يحدث مع تغييرات مدير الخدمة)، فمن المحتمل أن يتم فرض ترقية البائع.
تمت إزالة الفئة/الأذونات
يحدث هذا السيناريو عند إزالة مدير كائن (مثل مدير كائن ZygoteConnection
) ويجب ألا يسبب مشاكل. يمكن أن تظل فئة إدارة الكائنات وأذوناتها محددة في السياسة حتى يتوقف إصدار البائع عن استخدامها. ويتم ذلك عن طريق إضافة التعريفات إلى ملف التعيين المقابل.
تخصيص البائع للأنواع الجديدة/المعاد تسميتها
تعد أنواع البائعين الجديدة هي جوهر تطوير سياسة البائعين حيث إنها ضرورية لوصف العمليات الجديدة والثنائيات والأجهزة والأنظمة الفرعية والبيانات المخزنة. على هذا النحو، من الضروري السماح بإنشاء أنواع محددة من قبل البائع.
نظرًا لأن سياسة البائع هي دائمًا الأقدم على الجهاز، فليست هناك حاجة لتحويل جميع أنواع البائعين تلقائيًا إلى سمات في السياسة. لا تعتمد المنصة على أي شيء مذكور في سياسة البائع لأن المنصة ليس لديها علم به؛ ومع ذلك، سيوفر النظام الأساسي السمات والأنواع العامة التي يستخدمها للتفاعل مع الكائنات المصنفة بهذه الأنواع (مثل domain
و sysfs_type
وما إلى ذلك). لكي يستمر النظام الأساسي في التفاعل بشكل صحيح مع هذه الكائنات، يجب تطبيق السمات والأنواع بشكل مناسب وقد يلزم إضافة قواعد محددة إلى المجالات القابلة للتخصيص (مثل init
).
تغييرات السمات لنظام Android 9
يمكن للأجهزة التي تقوم بالترقية إلى Android 9 استخدام السمات التالية، ولكن لا يجب على الأجهزة التي تعمل بنظام Android 9.
صفات المخالف
يتضمن Android 9 هذه السمات المتعلقة بالمجال:
-
data_between_core_and_vendor_violators
. سمة لجميع النطاقات التي تنتهك متطلبات عدم مشاركة الملفات حسب المسار بينvendor
والمجالاتcoredomains
. يجب ألا تستخدم عمليات النظام الأساسي والبائعين الملفات الموجودة على القرص للتواصل (ABI غير المستقر). توصية:- يجب أن يستخدم رمز البائع
/data/vendor
. - يجب ألا يستخدم النظام
/data/vendor
.
- يجب أن يستخدم رمز البائع
-
system_executes_vendor_violators
. سمة لجميع مجالات النظام (باستثناء نطاقاتinit
وshell domains
) التي تنتهك متطلبات عدم تنفيذ ثنائيات البائع. تنفيذ ثنائيات البائع له واجهة برمجة تطبيقات غير مستقرة. لا ينبغي للنظام الأساسي تنفيذ ثنائيات البائع مباشرة. توصية:- يجب أن تكون تبعيات النظام الأساسي هذه على ثنائيات البائع خلف HIDL HALs.
أو
- يجب نقل
coredomains
التي تحتاج إلى الوصول إلى ثنائيات البائع إلى قسم البائع وبالتالي التوقف عن كونهاcoredomain
.
- يجب أن تكون تبعيات النظام الأساسي هذه على ثنائيات البائع خلف HIDL HALs.
صفات غير موثوقة
لا ينبغي أن تتمكن التطبيقات غير الموثوقة التي تستضيف تعليمات برمجية عشوائية من الوصول إلى خدمات HwBinder، باستثناء تلك التي تعتبر آمنة بما يكفي للوصول إليها من هذه التطبيقات (انظر الخدمات الآمنة أدناه). السببان الرئيسيان لذلك هما:
- لا تقوم خوادم HwBinder بإجراء مصادقة العميل لأن HIDL لا يكشف حاليًا عن معلومات UID للمتصل. حتى لو كشف HIDL عن مثل هذه البيانات، فإن العديد من خدمات HwBinder إما تعمل بمستوى أقل من مستوى التطبيقات (مثل HALs) أو يجب ألا تعتمد على هوية التطبيق للحصول على الترخيص. وبالتالي، لكي تكون آمنًا، فإن الافتراض الافتراضي هو أن كل خدمة 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
.
توصية:
- يجب أن تتحدث التطبيقات غير الموثوقة بدلاً من ذلك مع خدمة النظام التي تتحدث مع البائع HIDL HAL. على سبيل المثال، يمكن للتطبيقات التحدث إلى
binderservicedomain
، ثمmediaserver
(وهوbinderservicedomain
) بدوره يتحدث إلىhal_graphics_allocator
.أو
- يجب أن يكون للتطبيقات التي تحتاج إلى وصول مباشر إلى
vendor
(HALs) الخاصة بالموردين مجال حماية خاص بها يحدده البائع.
اختبارات سمات الملف
يتضمن Android 9 اختبارات وقت البناء التي تضمن أن جميع الملفات الموجودة في مواقع محددة تحتوي على السمات المناسبة (على سبيل المثال، تحتوي جميع الملفات الموجودة في sysfs
على سمة sysfs_type
المطلوبة).
منصة السياسة العامة
تعد السياسة العامة للنظام الأساسي هي جوهر التوافق مع نموذج بنية Android 8.0 دون الحفاظ ببساطة على اتحاد سياسات النظام الأساسي من الإصدارين 1 و2. يتعرض البائعون لمجموعة فرعية من سياسة النظام الأساسي التي تحتوي على أنواع وسمات قابلة للاستخدام وقواعد على تلك الأنواع والسمات التي تصبح بعد ذلك جزءًا من سياسة البائع (على سبيل المثال، vendor_sepolicy.cil
).
تتم ترجمة الأنواع والقواعد تلقائيًا في السياسة التي أنشأها البائع إلى attribute_v N
بحيث تكون جميع الأنواع المقدمة من النظام الأساسي عبارة عن سمات ذات إصدار (على الرغم من عدم إصدار السمات). النظام الأساسي مسؤول عن تعيين الأنواع الملموسة التي يوفرها في السمات المناسبة لضمان استمرار سياسة البائع في العمل وإدراج القواعد المقدمة لإصدار معين. يلبي الجمع بين السياسة العامة للنظام الأساسي وسياسة البائعين هدف نموذج بنية Android 8.0 المتمثل في السماح ببناء منصات مستقلة وبائعين.
رسم الخرائط لسلاسل السمات
عند استخدام السمات للتعيين إلى إصدارات السياسة، يقوم النوع بتعيين سمة أو سمات متعددة، مما يضمن إمكانية الوصول إلى الكائنات المسماة بالنوع عبر السمات المقابلة لأنواعها السابقة.
إن الحفاظ على هدف إخفاء معلومات الإصدار عن كاتب السياسة يعني إنشاء السمات التي تم إصدارها تلقائيًا وتعيينها للأنواع المناسبة. في الحالة الشائعة للأنواع الثابتة، يكون هذا أمرًا مباشرًا: يتم تعيين type_foo
إلى type_foo_v1
.
بالنسبة لتغيير تسمية الكائن مثل sysfs
→ sysfs_A
أو mediaserver
→ audioserver
، فإن إنشاء هذا التعيين ليس بالأمر التافه (وتم وصفه في الأمثلة أعلاه). يجب أن يحدد مشرفو سياسة النظام الأساسي كيفية إنشاء التعيين عند نقاط الانتقال للكائنات، الأمر الذي يتطلب فهم العلاقة بين الكائنات والتسميات المخصصة لها وتحديد متى يحدث ذلك. من أجل التوافق مع الإصدارات السابقة، يجب إدارة هذا التعقيد على جانب النظام الأساسي، وهو القسم الوحيد الذي قد يتم تحديثه.
تحديثات الإصدار
من أجل البساطة، يقوم نظام Android بإصدار إصدار sepolicy عند قطع فرع إصدار جديد. كما هو موضح أعلاه، رقم الإصدار موجود في 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
ولكن ليس ارتداد API، فمن الممكن أن يكون إصدار sepolicy هذا: vN.1
. الإصدار الموجود في فرع التطوير هو إصدار لا يُستخدم أبدًا في أجهزة الشحن 10000.0
.
قد يتجاهل Android الإصدار الأقدم عند التحديث. للحصول على معلومات حول وقت إيقاف إصدار ما، قد يجمع Android عدد الأجهزة التي لديها سياسات البائعين التي تعمل بإصدار Android هذا ولا تزال تتلقى تحديثات النظام الأساسي الرئيسية. إذا كان الرقم أقل من حد معين، فسيتم إهمال هذا الإصدار.
تأثير الأداء لسمات متعددة
كما هو موضح في https://github.com/SELinuxProject/cil/issues/9 ، يؤدي عدد كبير من السمات المخصصة للنوع إلى حدوث مشكلات في الأداء في حالة فقدان ذاكرة التخزين المؤقت للسياسة.
تم التأكيد على أن هذه مشكلة في Android، لذلك تم إجراء تغييرات على Android 8.0 لإزالة السمات المضافة إلى السياسة بواسطة مترجم السياسة، وكذلك لإزالة السمات غير المستخدمة. حلت هذه التغييرات تراجعات الأداء.
System_ext السياسة العامة والسياسة العامة للمنتج
بدءًا من Android 11، يُسمح لقسمي system_ext والمنتج بتصدير الأنواع العامة المخصصة لهما إلى قسم البائع. مثل السياسة العامة للنظام الأساسي، يستخدم البائع الأنواع والقواعد المترجمة تلقائيًا إلى السمات ذات الإصدار، على سبيل المثال من type
إلى type_ N
، حيث N
هو إصدار النظام الأساسي الذي تم بناء قسم البائع عليه.
عندما يعتمد قسمي system_ext والمنتج على نفس إصدار النظام الأساسي N
، يقوم نظام البناء بإنشاء ملفات تعيين أساسية إلى system_ext/etc/selinux/mapping/ N .cil
و product/etc/selinux/mapping/ N .cil
، والتي تحتوي على الهوية تعيينات من type
إلى type_ N
. يمكن للمورد الوصول إلى type
باستخدام السمة التي تم إصدارها type_ N
.
في حالة تحديث قسمي system_ext والمنتج فقط، على سبيل المثال N
إلى N+1
(أو الأحدث)، بينما يبقى البائع في N
، فقد يفقد البائع إمكانية الوصول إلى أنواع أقسام system_ext والمنتج. لمنع الكسر، يجب أن يوفر قسمي system_ext والمنتج ملفات تعيين من الأنواع الملموسة إلى سمات type_ N
يكون كل شريك مسؤولاً عن صيانة ملفات التعيين، إذا كانوا سيدعمون بائع N
مع N+1
(أو الأحدث) وأقسام المنتج.
للقيام بذلك، يتوقع من الشركاء:
- انسخ ملفات التعيين الأساسية التي تم إنشاؤها من
N
system_ext وأقسام المنتج إلى الشجرة المصدر الخاصة بها. - قم بتعديل ملفات التعيين حسب الحاجة.
- قم بتثبيت ملفات التعيين على
N+1
(أو الأحدث) system_ext وأقسام المنتج.
على سبيل المثال، لنفترض أن 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
ويتم تحميله بواسطةinit
في البداية جنبًا إلى جنب مع النظام الأساسيproperty_context
- تم إنشاء
سياقات الخدمة
في Android 8.0، يتم تقسيم service_contexts
بين الملفات التالية:
-
plat_service_contexts
-
service_context
الخاص بمنصة Androidservicemanager
. لا يحتوي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
يبحث عن هذا الملف في وقت التمهيد، إلا أنه بالنسبة لجهازTREBLE
متوافق تمامًا، يجب ألا يكونvendor_service_contexts
موجودًا. وذلك لأن كل التفاعل بين عملياتvendor
system
يجب أن يمر عبرhwservicemanager
/hwbinder
.
- تم إنشاء
-
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
ويتم تحميله بواسطة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
.
- تم إنشاء الامتداد الخاص بالجهاز للنظام الأساسي
أذونات ماك
في 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/.
- تم العثور على الامتداد الخاص بالجهاز للنظام الأساسي