توافق السياسة

توضح هذه المقالة كيفية تعامل 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

عند الترقية من v1v2 ، يجب أن تحتوي سياسة النظام الأساسي على:

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 ، ويحتاج إلى تضمين تلك القاعدة كسمة من النوع الجديد.

عند الترقية من v1v2 ، يجب أن تحتوي سياسة النظام الأساسي على:

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)

عند الترقية من v1v2 ، يجب أن تحتوي سياسة النظام الأساسي على:

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)

عند الترقية من v1v2 ، يجب أن تحتوي سياسة النظام الأساسي على:

# 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 .

صفات غير موثوقة

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

  1. لا تقوم خوادم HwBinder بإجراء مصادقة العميل لأن HIDL لا يكشف حاليًا عن معلومات UID للمتصل. حتى لو كشف HIDL عن مثل هذه البيانات، فإن العديد من خدمات HwBinder إما تعمل بمستوى أقل من مستوى التطبيقات (مثل HALs) أو يجب ألا تعتمد على هوية التطبيق للحصول على الترخيص. وبالتالي، لكي تكون آمنًا، فإن الافتراض الافتراضي هو أن كل خدمة HwBinder تعامل جميع عملائها على أنهم مرخص لهم على قدم المساواة بتنفيذ العمليات التي تقدمها الخدمة.
  2. تحتوي خوادم 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 .

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

تحديثات الإصدار

من أجل البساطة، يقوم نظام 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 (أو الأحدث) وأقسام المنتج.

للقيام بذلك، يتوقع من الشركاء:

  1. انسخ ملفات التعيين الأساسية التي تم إنشاؤها من N system_ext وأقسام المنتج إلى الشجرة المصدر الخاصة بها.
  2. قم بتعديل ملفات التعيين حسب الحاجة.
  3. قم بتثبيت ملفات التعيين على 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 .
    • 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 .
  • 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 الخاص بمنصة 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 يبحث عن هذا الملف في وقت التمهيد، إلا أنه بالنسبة لجهاز 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 .
  • 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.
  • 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/.
  • غير النظام الأساسي mac_permissions.xml
    • تم العثور على الامتداد الخاص بالجهاز للنظام الأساسي mac_permissions.xml المبني من mac_permissions.xml في الدلائل المشار إليها بواسطة BOARD_SEPOLICY_DIRS في ملفات Boardconfig.mk الخاصة بالجهاز.
    • يجب أن يكون موجودًا في قسم vendor في /vendor/etc/selinux/.