باستخدام Binder IPC

تصف هذه الصفحة التغييرات التي تم إجراؤها على برنامج تشغيل الرابط في Android 8 ، وتوفر تفاصيل حول استخدام Binder IPC ، وتسرد سياسة SELinux المطلوبة.

التغييرات على سائق الموثق

بدءًا من Android 8 ، يتواصل الآن إطار عمل Android و HALs مع بعضهما البعض باستخدام Binder. نظرًا لأن هذا الاتصال يزيد بشكل كبير من حركة مرور البيانات Binder ، يشتمل Android 8 على العديد من التحسينات المصممة للحفاظ على سرعة Binder IPC. شركة نفط الجنوب البائعين ويجب أن مصنعي المعدات الأصلية دمج مباشرة من الفروع ذات الصلة من الروبوت-4.4، الروبوت 4.9، وأعلى من / مشترك نواة المشروع.

مجالات موثق متعددة (سياقات)

Common-4.4 والإصدارات الأحدث ، بما في ذلك المنبع

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

جمع مبعثر

Common-4.4 والإصدارات الأحدث ، بما في ذلك المنبع

في الإصدارات السابقة من Android ، تم نسخ كل جزء من البيانات في مكالمة Binder ثلاث مرات:

  • مرة واحدة لتسلسل هو داخل Parcel في عملية الدعوة
  • مرة واحدة في برنامج تشغيل نواة لنسخ Parcel إلى عملية الهدف
  • مرة واحدة لunserialize على Parcel في عملية الهدف

الروبوت 8 استخدامات مبعثر جمع الأمثل للحد من عدد النسخ من 3 إلى 1. بدلا من تسلسل البيانات في Parcel أولا، لا يزال هناك بيانات في تخطيط هيكل والذاكرة الأصلي والسائق على الفور نسخ إلى عملية الهدف. بعد أن تكون البيانات في العملية المستهدفة ، يكون الهيكل وتخطيط الذاكرة متماثلين ويمكن قراءة البيانات دون الحاجة إلى نسخة أخرى.

قفل دقيق الحبيبات

Common-4.4 والإصدارات الأحدث ، بما في ذلك المنبع

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

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

بعد تحديد المشكلات الصغيرة في تنفيذ القفل الدقيق ، ابتكرنا حلاً محسنًا بهندسة قفل مختلفة وأرسلنا التغييرات في جميع فروع kernel الشائعة. نواصل اختبار هذا التنفيذ على عدد كبير من الأجهزة المختلفة ؛ نظرًا لأننا غير مدركين لأي مشكلات معلقة ، فهذا هو التنفيذ الموصى به للأجهزة المشحونة بنظام Android 8.

توريث الأولوية في الوقت الحقيقي

Common-4.4 و Common-4.9 (المنبع قريبًا)

يدعم برنامج تشغيل الموثق دائمًا الميراث ذي الأولوية اللطيفة. نظرًا لأن عددًا متزايدًا من العمليات في Android يتم تشغيلها بأولوية في الوقت الفعلي ، فمن المنطقي في بعض الحالات الآن أنه إذا قام مؤشر ترابط في الوقت الفعلي بإجراء مكالمة Binder ، فإن مؤشر الترابط في العملية التي تتعامل مع هذا الاستدعاء يعمل أيضًا بأولوية في الوقت الفعلي . لدعم حالات الاستخدام هذه ، يقوم Android 8 الآن بتنفيذ توريث الأولوية في الوقت الفعلي في برنامج تشغيل Binder.

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

تغييرات مساحة المستخدمين

الروبوت 8 يتضمن يتغير كل مساحة المستخدم المطلوبة للعمل مع السائق الموثق الحالي في نواة مشتركة مع استثناء واحد: تنفيذ الأصلي لتعطيل الوقت الحقيقي الميراث الأولوية لل /dev/binder استخدمت IOCTL . قام التطوير اللاحق بتحويل التحكم في الوراثة ذات الأولوية إلى طريقة أكثر دقة لكل وضع رابط (وليس لكل سياق). وهكذا، فإن IOCTL ليس في فرع المشترك الروبوت وبدلا من ذلك قدمت في حبات المشتركة .

هو تأثير هذا التغيير أن الوقت الحقيقي الميراث الأولوية يتم تعطيل افتراضيا لكل عقدة. وقد وجد الفريق أداء الروبوت من المفيد لتمكين الوقت الحقيقي الميراث الأولوية لجميع العقد في hwbinder المجال. ولتحقيق ذلك نفس التأثير، الكرز اختيار هذا التغيير في مساحة المستخدم.

SHAs للنواة المشتركة

للحصول على التغييرات اللازمة لبرنامج تشغيل Binder ، قم بالمزامنة مع SHA المناسب:

  • عام 3.18
    cc8b90c121de ANDROID: Binder: لا تتحقق من أذونات prio عند الاستعادة.
  • عام - 4.4
    76b376eac7a2 ANDROID: Binder: لا تتحقق من أذونات prio عند الاستعادة.
  • عام 4.9
    ecd972d4f9b5 ANDROID: Binder: لا تتحقق من أذونات prio عند الاستعادة.

باستخدام Binder IPC

من الناحية التاريخية ، استخدمت عمليات البائع اتصال بين العمليات (IPC) للتواصل. في الروبوت 8، و /dev/binder عقدة الجهاز تصبح حصرية لعمليات الإطار، وهذا يعني عمليات البائع لم يعد لدينا الوصول إليها. ويمكن لعمليات بائع الوصول /dev/hwbinder ، ولكن يجب تحويل واجهات AIDL لاستخدام HIDL. بالنسبة للبائعين الذين يرغبون في الاستمرار في استخدام واجهات AIDL بين عمليات البائعين ، فإن Android يدعم Binder IPC كما هو موضح أدناه.

فندبيندر

الروبوت 8 يدعم مجال الموثق جديد للاستخدام الخدمات بائع، الوصول إليها باستخدام /dev/vndbinder بدلا من /dev/binder . مع إضافة /dev/vndbinder ، الروبوت لديها الآن ثلاثة مجالات IPC التالية:

مجال IPC وصف
/dev/binder IPC بين عمليات الإطار / التطبيق مع واجهات AIDL
/dev/hwbinder IPC بين عمليات الإطار / البائع مع واجهات HIDL
IPC بين عمليات البائع مع واجهات HIDL
/dev/vndbinder IPC بين عمليات البائع / البائع باستخدام واجهات AIDL

ل /dev/vndbinder لتظهر، وضمان عنصر التكوين نواة CONFIG_ANDROID_BINDER_DEVICES من المقرر أن "binder,hwbinder,vndbinder" (هذا هو الافتراضي في الأشجار نواة مشتركة الروبوت).

عادة، والعمليات بائع لا تفتح سائق الموثق مباشرة وبدلا من ذلك يرتبط ضد libbinder مكتبة مساحة المستخدم، والذي يفتح السائق الموثق. مضيفا طريقة ل ::android::ProcessState() يختار السائق الموثق ل libbinder . يجب أن العمليات بائع استدعاء هذا الأسلوب قبل استدعاء إلى ProcessState, IPCThreadState ، أو قبل إجراء أية مكالمات الموثق بشكل عام. الاستخدام، وإجراء المكالمة التالية بعد main() لعملية بائع (العميل والخادم):

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

سابقا، تم تسجيل الخدمات الموثق مع servicemanager ، حيث يمكن استردادها من قبل عمليات أخرى. في الروبوت 8، servicemanager يستخدم الآن بشكل حصري من خلال عمليات إطار والتطبيق والعمليات بائع لم تعد قادرة على الوصول إليه.

ومع ذلك، يمكن لخدمات بائع الآن استخدام vndservicemanager ، نسخة جديدة من servicemanager أن الاستخدامات /dev/vndbinder بدلا من /dev/binder والتي بنيت من المصادر نفسها كإطار servicemanager . عمليات البائع لا تحتاج إلى إجراء تغييرات على التحدث الى vndservicemanager . عندما تفتح عملية بائع / dev/vndbinder ، عمليات البحث عن خدمة تذهب تلقائيا إلى vndservicemanager .

و vndservicemanager يتم تضمين ثنائي في makefiles الجهاز الافتراضي الروبوت.

سياسة SELinux

تحتاج عمليات البائع التي ترغب في استخدام وظيفة Binder للتواصل مع بعضها البعض إلى ما يلي:

  1. الوصول إلى /dev/vndbinder .
  2. الموثق {transfer, call} السنانير في vndservicemanager .
  3. binder_call(A, B) لأي بائع المجال A الذي يريد أن يدعو إلى نطاق بائع B عبر واجهة بائع الموثق.
  4. إذن ل {add, find} الخدمات في vndservicemanager .

للوفاء بمتطلبات 1 و 2، استخدم vndbinder_use() ماكرو:

vndbinder_use(some_vendor_process_domain);

لتلبية احتياجات 3، و binder_call(A, B) للبائع عمليات A و B التي تحتاج إلى التحدث عبر الموثق يمكن ان يبقى في مكان، ولا يحتاج إلى إعادة تسمية.

للوفاء بالمتطلب 4 ، يجب إجراء تغييرات في طريقة التعامل مع أسماء الخدمة وتسميات الخدمة والقواعد.

للاطلاع على تفاصيل سيلينو، انظر الأمن المحسن لينكس في الروبوت . للاطلاع على تفاصيل سيلينو في الروبوت 8.0، انظر سيلينو لالروبوت 8.0 .

أسماء الخدمة

سابقا، والعمليات بائع مسجل من الخدمات والأسماء في service_contexts ملف وأضاف القواعد للوصول إلى هذا الملف المقابلة. مثال service_contexts ملف من device/google/marlin/sepolicy :

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

في الروبوت 8، vndservicemanager أحمال vndservice_contexts ملف بدلا من ذلك. الخدمات بائع الهجرة إلى vndservicemanager (والتي هي بالفعل في القديم service_contexts يجب إضافة ملف) إلى جديد vndservice_contexts الملف.

تسميات الخدمة

سابقا، خدمة تسميات مثل u:object_r:atfwd_service:s0 تم تعريفها في service.te الملف. مثال:

type atfwd_service,      service_manager_type;

في الروبوت 8، يجب تغيير نوع إلى vndservice_manager_type ونقل القاعدة إلى vndservice.te الملف. مثال:

type atfwd_service,      vndservice_manager_type;

قواعد مدير الخدمة

سابقا، وقواعد منح المجالات الوصول إلى إضافة أو تجد الخدمات من servicemanager . مثال:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

في Android 8 ، يمكن أن تظل هذه القواعد سارية وتستخدم نفس الفئة. مثال:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;