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

توضح هذه المقالة كيفية تعامل Android مع مشكلات توافق السياسة مع النظام الأساسي OTAs ، حيث قد تختلف إعدادات 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.* (خاصية واضحة متعلقة بالأجهزة).

يجب أن يكون لدى جميع خدمات البائع في ملفات rc الأولية vendor. للخدمات في ملفات init rc للأقسام غير التابعة للنظام. يتم تطبيق قواعد مماثلة على ملصقات SELinux لخصائص البائع ( vendor_ لخصائص البائع).

ملكية الملف

يعد منع الاصطدامات بين الملفات أمرًا صعبًا لأن النظام الأساسي وسياسة البائع يوفران عادةً تسميات لجميع أنظمة الملفات. على عكس تسمية النوع ، فإن مساحة أسماء الملفات ليست عملية لأن العديد منها يتم إنشاؤها بواسطة النواة. لمنع هذه التصادمات ، اتبع إرشادات التسمية لأنظمة الملفات في هذا القسم. بالنسبة لنظام التشغيل Android 8.0 ، فهذه توصيات بدون فرض تقني. في المستقبل ، سيتم تنفيذ هذه التوصيات من قبل مجموعة اختبار البائع (VTS).

النظام (/ النظام)

يجب أن توفر صورة النظام فقط ملصقات /system من خلال file_contexts ، و service_contexts ، وما إلى ذلك. إذا تمت إضافة ملصقات /system في /vendor ، فقد لا يكون تحديث OTA للإطار فقط ممكنًا.

بائع (/ بائع)

تقوم سياسة AOSP SELinux بالفعل بتسمية أجزاء من قسم vendor الذي تتفاعل معه المنصة ، مما يتيح كتابة قواعد SELinux لعمليات النظام الأساسي لتكون قادرة على التحدث و / أو الوصول إلى أجزاء من قسم vendor . أمثلة:

/vendor التسمية التي توفرها المنصة عمليات النظام الأساسي اعتمادًا على الملصق
/vendor(/. * )? vendor_file جميع عملاء HAL في framework ، 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 .
  • يجب تسمية جميع تبعيات المكتبة لـ AOSPs نفسها التي تم تحديدها من خلال HALs على أنها same_process_hal_file.

Procfs (/ proc)

يمكن تسمية الملفات الموجودة في /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 .

Tracefs (/ sys / kernel / debug / tracing)

يمكن تسمية Tracefs في كل من file_contexts و genfscon . في Android 7.0 ، تسميات النظام الأساسي tracefs .

توصية: يمكن للمنصة فقط تسمية tracefs .

Sysfs (/ sys)

يمكن تسمية الملفات الموجودة في /sys باستخدام كل من file_contexts و genfscon . في Android 7.0 ، يستخدم كل من النظام الأساسي file_contexts و genfscon لتسمية الملفات في sysfs .

توصية: قد يقوم النظام الأساسي بتسمية عقد sysfs غير الخاصة بالجهاز. خلاف ذلك ، يمكن للبائع فقط تسمية الملفات.

tmpfs (/ dev)

يمكن تسمية الملفات الموجودة في /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 هو إصدار خاص بالنظام الأساسي.

لا يتم إصدار السمات في السياسة العامة ، ولكنها موجودة كواجهة برمجة تطبيقات يمكن للنظام الأساسي وسياسة البائع أن تبني عليها للحفاظ على استقرار الواجهة بين القسمين. يمكن لكتاب سياسة النظام الأساسي والبائع الاستمرار في كتابة السياسة كما هي مكتوبة اليوم.

تم تصدير السياسة العامة للنظام الأساسي على أنها 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)

في ملف تعيين الإصدار 1 (CIL):

(typeattributeset binder_device_v1 (binder_device))

في ملف تعيين الإصدار 2 (CIL):

(typeattributeset binder_device_v2 (binder_device))

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

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

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))

في v1 سياسة البائع (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)

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

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))

في v1 سياسة البائع (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)

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

# 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

في v1 سياسة البائع (CIL):

(typeattribute foo_v1)
(allow foo …)
(typeattribute sysfs_v1)
(allow sysfs_v1 …)

في الإصدار 2 من سياسة البائع (CIL):

(typeattribute sysfs_v2)
(allow sysfs_v2 …)
فئة / أذونات جديدة

يحدث هذا السيناريو عندما تقدم ترقية النظام الأساسي مكونات نهج جديدة غير موجودة في الإصدارات السابقة. على سبيل المثال ، عندما أضاف Android مدير كائن servicemanager الذي أنشأ أذونات الإضافة والعثور والقائمة ، احتاجت شياطين البائعين الراغبين في التسجيل مع مدير servicemanager إلى أذونات لم تكن متاحة. في Android 8.0 ، يمكن لسياسة النظام الأساسي فقط إضافة فئات وأذونات جديدة.

للسماح لجميع المجالات التي كان من الممكن إنشاؤها أو توسيعها بواسطة سياسة المورد لاستخدام الفئة الجديدة دون عوائق ، يجب أن تتضمن سياسة النظام الأساسي قاعدة مشابهة لـ:

allow {domain -coredomain} *:new_class perm;

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

تمت إزالة الفئة / الأذونات

يحدث هذا السيناريو عند إزالة مدير كائن (مثل ZygoteConnection Object Manager) ويجب ألا يتسبب في حدوث مشكلات. يمكن أن تظل فئة وأذونات إدارة الكائنات محددة في السياسة حتى يتوقف إصدار المورد عن استخدامها. يتم ذلك عن طريق إضافة التعريفات إلى ملف التعيين المقابل.

تخصيص البائع للأنواع الجديدة / المعاد تسميتها

تعد أنواع البائعين الجديدة في صميم تطوير سياسة البائع حيث إنها ضرورية لوصف العمليات الجديدة والثنائيات والأجهزة والأنظمة الفرعية والبيانات المخزنة. على هذا النحو ، من الضروري السماح بإنشاء أنواع محددة بواسطة البائع.

نظرًا لأن سياسة المورد هي الأقدم دائمًا على الجهاز ، فلا داعي لتحويل جميع أنواع البائعين تلقائيًا إلى سمات في السياسة. لا تعتمد المنصة على أي شيء موصوف في سياسة البائع لأن النظام الأساسي ليس لديه معرفة به ؛ ومع ذلك ، ستوفر المنصة السمات والأنواع العامة التي تستخدمها للتفاعل مع الكائنات المصنفة بهذه الأنواع (مثل 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 . هذا إصدار mediacodec من خدمة mediacodec Binder ، والتي يُسمح للتطبيقات بالوصول إليها.
  • hal_codec2_hwservice . هذه نسخة أحدث من hal_omx_hwservice .

سمات قابلة للاستخدام

جميع خدمات hw التي لا تعتبر آمنة لها untrusted_app_visible_hwservice hwservices . خوادم HAL المقابلة لها السمة untrusted_app_visible_halserver . يجب ألا تستخدم الأجهزة التي تعمل بنظام Android 9 سمة untrusted .

توصية:

  • يجب أن تتحدث التطبيقات غير الموثوقة بدلاً من ذلك إلى خدمة نظام تتحدث إلى البائع HIDL HAL. على سبيل المثال ، يمكن للتطبيقات التحدث إلى binderservicedomain ، ثم mediaserver (وهو جزء أساسي من binderservicedomain ) يتحدث بدوره إلى hal_graphics_allocator .

    أو

  • يجب أن يكون للتطبيقات التي تحتاج إلى وصول مباشر إلى HALs الخاصة vendor نطاق منفصل يحدده البائع.

اختبارات سمات الملف

يتضمن Android 9 اختبارات وقت الإنشاء التي تضمن أن جميع الملفات في مواقع محددة لها السمات المناسبة (مثل ، جميع الملفات في sysfs لها سمة sysfs_type المطلوبة).

النظام الأساسي - السياسة العامة

تعد السياسة العامة للنظام الأساسي هي جوهر التوافق مع نموذج بنية Android 8.0 دون الحفاظ ببساطة على اتحاد سياسات النظام الأساسي من الإصدارين 1 و v2. يتعرض البائعون لمجموعة فرعية من سياسة النظام الأساسي التي تحتوي على أنواع وسمات وقواعد قابلة للاستخدام على تلك الأنواع والسمات التي تصبح بعد ذلك جزءًا من سياسة البائع ( vendor_sepolicy.cil ).

تُترجم الأنواع والقواعد تلقائيًا في السياسة التي ينشئها البائع إلى attribute_v N بحيث تكون جميع الأنواع التي يوفرها النظام الأساسي سمات ذات إصدار (على الرغم من عدم إصدار السمات). النظام الأساسي مسؤول عن تعيين الأنواع الملموسة التي يوفرها في السمات المناسبة لضمان استمرار سياسة البائع في العمل وإدراج القواعد المنصوص عليها لإصدار معين. إن الجمع بين السياسة العامة للنظام الأساسي وسياسة البائعين يلبي هدف نموذج بنية Android 8.0 المتمثل في السماح لمنصات مستقلة وبنيات البائعين.

تعيين سلاسل السمة

عند استخدام السمات للتعيين إلى إصدارات السياسة ، يتم تعيين النوع إلى سمة أو سمات متعددة ، مما يضمن إمكانية الوصول إلى الكائنات المصنفة بالنوع عبر السمات المقابلة لأنواعها السابقة.

يعني الحفاظ على هدف إخفاء معلومات الإصدار عن كاتب السياسة إنشاء سمات ذات إصدار وتعيينها إلى الأنواع المناسبة تلقائيًا. في الحالة الشائعة للأنواع الثابتة ، يكون هذا مباشرًا: خرائط type_foo إلى type_foo_v1 .

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

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

للتبسيط ، تقوم منصة 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. Uprevs ليست كذلك دائما الأعداد الصحيحة. على سبيل المثال ، إذا استلزم ارتداد MR لإحدى الإصدارات تغييرًا غير متوافق في system/sepolicy/public ولكن ليس نتوءًا لواجهة برمجة التطبيقات ، فيمكن أن يكون هذا الإصدار المنفصل: 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

في حالة تحديث أقسام نص النظام والمنتج فقط ، قل N إلى N+1 (أو أحدث) ، بينما يبقى البائع في N ، فقد يفقد البائع الوصول إلى أنواع نص النظام وأقسام المنتج. لمنع الكسر ، يجب أن يوفر نص النظام وأقسام المنتج ملفات تعيين من أنواع محددة إلى سمات type_ N يكون كل شريك مسؤولاً عن الحفاظ على ملفات التعيين ، إذا كان سيقدم الدعم لمورد N مع N+1 (أو أحدث) system_ext وأقسام المنتج.

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

  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 bar_type ، وإذا كان يجب تعيين 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 foo_type .

وضع العلامات على سياقات SELinux

لدعم التمييز بين النظام الأساسي وسياسة البائع المنفصلة ، يقوم النظام ببناء ملفات سياق SELinux بشكل مختلف لإبقائها منفصلة.

سياقات الملف

قدم Android 8.0 التغييرات التالية لـ file_contexts :

  • لتجنب عبء التجميع الإضافي على الجهاز أثناء التمهيد ، يتوقف file_contexts عن الوجود في النموذج الثنائي. بدلاً من ذلك ، تكون ملفات نصية قابلة للقراءة وتعبيرات عادية مثل {property, service}_contexts (كما كانت قبل 7.0).
  • يتم تقسيم file_contexts بين ملفين:
    • plat_file_contexts
      • نظام Android file_context الذي لا يحتوي على تسميات خاصة بالجهاز ، باستثناء وضع العلامات على أجزاء من قسم /vendor الذي يجب تسميته بدقة لضمان حسن سير ملفات البيانات المنفصلة.
      • يجب أن يتواجد في قسم 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 .
    • على الرغم من أن vendor_service_contexts يبحث عن هذا الملف في وقت التمهيد ، فإنه بالنسبة لجهاز TREBLE المتوافق تمامًا ، يجب ألا يكون servicemanager موجودًا. هذا لأن كل التفاعلات بين 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 .

أذونات MAC

في 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/.