التحكّم في الوصول التقديري (DAC)

تحتاج عناصر وخدمات نظام الملفات التي تتم إضافتها إلى الإصدار بشكل متكرر إلى معرّفات منفصلة وفريدة، تُعرف باسم معرّفات Android (AID). في الوقت الحالي، تستخدم العديد من الموارد، مثل الملفات والخدمات، معرّفات AID الأساسية (المحدّدة في Android) بدون داعٍ، وفي العديد من الحالات، يمكنك استخدام معرّفات AID الخاصة بمصنّع المعدات الأصلية (المحدّدة من قِبل مصنّع المعدات الأصلية) بدلاً من ذلك.

كانت الإصدارات السابقة من Android (الإصدار 7.x والإصدارات الأقدم) توسّع آلية معرّفات AID باستخدام ملف android_filesystem_config.h خاص بالجهاز لتحديد إمكانات نظام الملفات و/أو معرّفات AID المخصّصة من الشركة المصنّعة للجهاز الأصلي. ومع ذلك، كان هذا النظام غير بديهي لأنّه لم يكن يتيح استخدام أسماء مألوفة لمعرّفات التطبيقات (AID) الخاصة بمصنّعي المعدات الأصلية، ما كان يتطلّب منك تحديد الرقم الأولي للحقول الخاصة بالمستخدمين والمجموعات بدون توفير طريقة لربط اسم مألوف بمعرّف التطبيق الرقمي.

تتيح الإصدارات الأحدث من نظام التشغيل Android (الإصدار 8.0 والإصدارات الأحدث) طريقة جديدة لتوسيع إمكانات نظام الملفات. تتيح هذه الطريقة الجديدة ما يلي:

  • أماكن مصدر متعددة لملفات الإعداد (تتيح إعدادات إنشاء قابلة للتوسيع)
  • التحقّق من صحة قيم AID الخاصة بمصنّع المعدات الأصلية في وقت الإنشاء
  • إنشاء عنوان AID مخصّص للمصنّع الأصلي للجهاز يمكن استخدامه في ملفات المصدر حسب الحاجة
  • ربط اسم مألوف بقيمة AID الفعلية الخاصة بمصنّع المعدات الأصلية يتيح استخدام وسيطات سلسلة غير رقمية للمستخدم والمجموعة، أي "foo" بدلاً من "2901".

تشمل التحسينات الإضافية إزالة مصفوفة android_ids[] من system/core/libcutils/include/private/android_filesystem_config.h. تتوفّر هذه المصفوفة الآن في Bionic كمصفوفة تم إنشاؤها بشكل خاص بالكامل، مع أدوات الوصول التي تتضمّن getpwnam() وgetgrnam(). (ويؤدي ذلك إلى إنتاج ملفات ثنائية ثابتة عند تعديل معرّفات AID الأساسية). للحصول على أدوات وملف README يتضمّن المزيد من التفاصيل، يُرجى الرجوع إلى build/make/tools/fs_config.

إضافة معرّفات Android‏ (AID)

أزالت الإصدار 8.0 من نظام التشغيل Android مصفوفة android_ids[] من "مشروع Android المفتوح المصدر" (AOSP). يتم بدلاً من ذلك إنشاء جميع الأسماء المتوافقة مع AID من ملف العنوان system/core/libcutils/include/private/android_filesystem_config.h عند إنشاء مصفوفة android_ids[] Bionic. يتم اختيار أي define تطابق AID_* بواسطة الأدوات، ويصبح * الاسم بالأحرف الصغيرة.

على سبيل المثال، في private/android_filesystem_config.h:

#define AID_SYSTEM 1000

يصبح:

  • الاسم الملائم: النظام
  • uid: 1000
  • gid: 1000

لإضافة معرّف تطبيق أساسي جديد لنظام التشغيل AOSP، ما عليك سوى إضافة #define إلى ملف العنوان android_filesystem_config.h. يتم إنشاء معرّف AID أثناء عملية الإنشاء، ويتم توفيره للواجهات التي تستخدم وسيطات المستخدم والمجموعة. تتحقّق الأداة من أنّ معرّف التطبيق الجديد ليس ضمن نطاقات التطبيق أو الشركة المصنّعة للمعدّات الأصلية، كما أنّها تراعي التغييرات التي تطرأ على هذه النطاقات ويجب أن تتم إعادة ضبطها تلقائيًا عند حدوث تغييرات أو إضافة نطاقات جديدة محجوزة للشركة المصنّعة للمعدّات الأصلية.

إعداد أرقام تعريف المعلِنين

لتفعيل آلية معرّفات المعلِنين الجديدة، اضبط TARGET_FS_CONFIG_GEN في ملف BoardConfig.mk. يحتوي هذا المتغيّر على قائمة بملفات الإعداد، ما يتيح لك إلحاق الملفات حسب الحاجة.

وبموجب الاتفاقية، تستخدم ملفات الإعداد الاسم config.fs، ولكن يمكنك في الواقع استخدام أي اسم. تكون ملفات config.fs بتنسيق Python ConfigParser ini وتتضمّن قسمًا للأحرف الكبيرة (لضبط إمكانات نظام الملفات) وقسمًا لمعرّفات التطبيقات (لضبط معرّفات التطبيقات الخاصة بمصنّعي المعدات الأصلية).

ضبط قسم الحد الأقصى

يتيح قسم "القدرات" ضبط قدرات نظام الملفات على عناصر نظام الملفات ضمن الإصدار (يجب أن يتيح نظام الملفات نفسه هذه الوظيفة أيضًا).

بما أنّ تشغيل خدمة ثابتة بصفتها الجذر في Android يؤدي إلى تعذُّر اجتياز مجموعة أدوات اختبار التوافق (CTS)، كانت المتطلبات السابقة للاحتفاظ بإذن أثناء تشغيل عملية أو خدمة تتضمّن إعداد الأذونات ثم استخدام setuid/setgid لمعرّف AID مناسب لتشغيلها. باستخدام حدود قصوى، يمكنك تخطّي هذه المتطلبات والسماح للنظام الأساسي بتنفيذها نيابةً عنك. عند نقل عنصر التحكّم إلى main()، تكون العملية قد حصلت على الإمكانات التي تحتاج إليها، وبالتالي يمكن أن تستخدم خدمتك مستخدمًا ومجموعة غير جذريين (هذه هي الطريقة المفضّلة لبدء الخدمات التي تتطلّب امتيازات).

يستخدم قسم الأحرف الكبيرة البنية التالية:

القسم القيمة التعريف
[path] مسار نظام الملفات المطلوب ضبطه يُعد المسار الذي ينتهي بـ / دليلاً، وإلا فهو ملف.

يُعدّ تحديد أقسام متعددة لها [path] نفسها في ملفات مختلفة خطأً. في إصدارات Python الأقدم من 3.2، قد يحتوي الملف نفسه على أقسام تلغي القسم السابق. أما في إصدار Python 3.2، فيتم ضبطه على الوضع الصارم.
mode وضع الملف الثماني وضع ملف ثماني صالح يتضمّن 3 أرقام على الأقل إذا تم تحديد 3، تتم إضافة 0 قبلها، وإلا يتم استخدام الوضع كما هو.
user AID_<user> إما C define لمعرّف تطبيق صالح أو الاسم المألوف (على سبيل المثال، يمكن استخدام كل من AID_RADIO وradio). لتحديد معرّف تطبيق مخصّص، يُرجى الاطّلاع على قسم إعداد معرّف التطبيق.
group AID_<group> مثل المستخدم.
caps cap* الاسم كما هو معرَّف في bionic/libc/kernel/uapi/linux/capability.h بدون CAP_ في البداية. يُسمح باستخدام أحرف كبيرة وصغيرة. يمكن أن تكون الأحرف الكبيرة أيضًا هي الأحرف الأصلية:
  • ثنائي (0b0101)
  • ثماني (0455)
  • int (42)
  • hex (0xFF)
يجب الفصل بين الأحرف الكبيرة المتعددة باستخدام مسافات بيضاء.

للاطّلاع على مثال على الاستخدام، راجِع استخدام إمكانات نظام الملفات.

ضبط قسم AID

يحتوي قسم AID على معرّفات AID الخاصة بمصنّع المعدات الأصلية ويستخدم البنية التالية:

القسم القيمة التعريف
[AID_<name>] يمكن أن يحتوي <name> على أحرف كبيرة وأرقام وشرطات سفلية. يتم استخدام نسخة الأحرف الصغيرة كاسم سهل الاستخدام. يستخدم ملف العنوان الذي تم إنشاؤه لتضمين الرمز AID_<name>.

يحدث خطأ عند تحديد أقسام متعددة باستخدام AID_<name> نفسه (غير حساس لحالة الأحرف مع القيود نفسها التي تنطبق على [path]).

يجب أن يبدأ <name> باسم قسم لضمان عدم حدوث تعارض مع مصادر مختلفة.
value <number> سلسلة أرقام صالحة بتنسيق C (سداسي عشري وثماني وثنائي وعشري)

يُعدّ تحديد أقسام متعددة تتضمّن خيار القيمة نفسه خطأً.

يجب تحديد خيارات القيمة في النطاق المتوافق مع القسم المستخدَم في <name>. يتم تحديد قائمة الأقسام الصالحة والنطاقات المقابلة لها في system/core/libcutils/include/private/android_filesystem_config.h. في ما يلي الخيارات المتاحة:
  • قسم المورّد
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • ‫AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • قسم النظام
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • قسم ODM
    • ‫AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • قسم المنتج
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • قسم System_ext
    • ‫AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

للاطّلاع على أمثلة حول الاستخدام، يُرجى الرجوع إلى تحديد أسماء معرّفات التطبيقات (AID) الخاصة بمصنّع المعدات الأصلية واستخدام معرّفات التطبيقات (AID) الخاصة بمصنّع المعدات الأصلية.

أمثلة على الاستخدام

توضّح الأمثلة التالية بالتفصيل كيفية تحديد واستخدام معرّف تطبيق خاص بمصنّع المعدات الأصلية وكيفية تفعيل إمكانات نظام الملفات. يجب أن تبدأ أسماء معرّفات التطبيقات (AID) الخاصة بالمصنّع الأصلي للجهاز ([AID_name]) باسم قسم، مثل "vendor_"، لضمان عدم تعارضها مع أسماء AOSP المستقبلية أو الأقسام الأخرى.

تحديد أسماء معرّفات التطبيقات الأصلية (AID) الخاصة بمصنّع المعدات الأصلية

لتحديد معرّف تطبيق (AID) خاص بمصنّع المعدات الأصلية، أنشئ ملف config.fs واضبط قيمة معرّف التطبيق. على سبيل المثال، في device/x/y/config.fs، اضبط ما يلي:

[AID_VENDOR_FOO]
value: 2900

بعد إنشاء الملف، اضبط المتغيّر TARGET_FS_CONFIG_GEN وأشِر إليه في BoardConfig.mk. على سبيل المثال، في device/x/y/BoardConfig.mk، اضبط ما يلي:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

يمكن الآن أن يستخدم النظام بأكمله معرّف AID المخصّص في إصدار جديد.

استخدام أجهزة AID من المصنّع الأصلي للجهاز

لاستخدام معرّف AID خاص بمصنّع المعدات الأصلية، أدرِج oemaids_headers في ملف Makefile المرتبط في رمز C، ثم أضِف #include "generated_oem_aid.h"، وابدأ في استخدام المعرّفات المحدّدة. على سبيل المثال، في my_file.c، أضِف ما يلي:

#include "generated_oem_aid.h"


If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

في ملف Android.bp المرتبط، أضِف ما يلي:

header_libs: ["oemaids_headers"],

إذا كنت تستخدم ملف Android.mk، أضِف ما يلي:

LOCAL_HEADER_LIBRARIES := oemaids_headers

استخدام أسماء سهلة الاستخدام

في نظام التشغيل Android 9، يمكنك استخدام الاسم المألوف لأي واجهة تتوافق مع أسماء معرّفات التطبيقات. مثلاً:

  • في أمر chown في some/init.rc:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • في service في some/init.rc:
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

بما أنّ عملية الربط الداخلي بين الاسم المألوف والمعرّف الفريد تتم بواسطة /vendor/etc/passwd و/vendor/etc/group، يجب تثبيت قسم المورّد.

ربط الأسماء غير الرسمية

يتيح نظام التشغيل Android 9 ربط اسم مألوف بقيمة AID الفعلية الخاصة بمصنّع المعدات الأصلية. يمكنك استخدام وسيطات سلسلة غير رقمية للمستخدم والمجموعة، أي "vendor_foo" بدلاً من "2901".

التحويل من معرّف AID إلى أسماء مألوفة

بالنسبة إلى معرّفات AID الخاصة بمصنّعي المعدات الأصلية، كان نظام التشغيل Android 8.x يتطلّب استخدام oem_#### مع getpwnam ووظائف مشابهة، بالإضافة إلى الأماكن التي تتعامل مع عمليات البحث باستخدام getpwnam (مثل نصوص init البرمجية). في نظام التشغيل Android 9، يمكنك استخدام الصديقين getpwnam وgetgrnam في Bionic للتحويل من معرّفات Android (AID) إلى أسماء مألوفة والعكس.

استخدام إمكانات نظام الملفات

لتفعيل إمكانات نظام الملفات، أنشئ قسم caps في ملف config.fs. على سبيل المثال، في device/x/y/config.fs، أضِف القسم التالي:

[system/bin/foo_service]
mode: 0555
user: AID_VENDOR_FOO
group: AID_SYSTEM
caps: SYS_ADMIN | SYS_NICE

بعد إنشاء الملف، اضبط TARGET_FS_CONFIG_GEN للإشارة إلى هذا الملف في BoardConfig.mk. على سبيل المثال، في device/x/y/BoardConfig.mk، اضبط ما يلي:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

عند تنفيذ الخدمة vendor_foo، تبدأ بالإمكانات CAP_SYS_ADMIN وCAP_SYS_NICE بدون طلبات setuid وsetgid. بالإضافة إلى ذلك، لم تعُد سياسة SELinux الخاصة بخدمة vendor_foo بحاجة إلى الإذن setuid وsetgid، ويمكن حذفها.

ضبط عمليات الإلغاء (Android 6.x-7.x)

في الإصدار 6.0 من نظام التشغيل Android، تم نقل تعريفات fs_config وبنية البيانات المرتبطة بها (system/core/include/private/android_filesystem_config.h) إلى system/core/libcutils/fs_config.c، حيث يمكن تعديلها أو تجاهلها من خلال الملفات الثنائية المثبّتة في /system/etc/fs_config_dirs و/system/etc/fs_config_files. وقد أتاحت استخدام قواعد منفصلة للمطابقة والتحليل لكل من الأدلة والملفات (التي يمكن أن تستخدم تعبيرات glob إضافية) لنظام التشغيل Android إمكانية التعامل مع الأدلة والملفات في جدولَين مختلفَين. لم تسمح تعريفات البنية في system/core/libcutils/fs_config.c بقراءة الأدلة والملفات في وقت التشغيل فحسب، بل كان بإمكان المضيف استخدام الملفات نفسها أثناء وقت الإنشاء لإنشاء صور لنظام الملفات مثل ${OUT}/system/etc/fs_config_dirs و${OUT}/system/etc/fs_config_files.

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

إنشاء ملفات تجاوز

يمكنك إنشاء ملفات ثنائية متوافقة /system/etc/fs_config_dirs و /system/etc/fs_config_files باستخدام أداة fs_config_generate في build/tools/fs_config. تستخدم الأداة دالة مكتبة libcutils (fs_config_generate()) لإدارة متطلبات DAC في مخزن مؤقت وتحديد قواعد لملف تضمين من أجل إضفاء الطابع المؤسسي على قواعد DAC.

لاستخدام هذه الميزة، أنشئ ملف تضمين في device/vendor/device/android_filesystem_config.h يعمل كملف تجاهل. يجب أن يستخدم الملف تنسيق structure fs_path_config المحدّد في system/core/include/private/android_filesystem_config.h مع عمليات تهيئة البنية التالية لرموز الدليل والملف:

  • بالنسبة إلى الأدلة، استخدِم android_device_dirs[].
  • بالنسبة إلى الملفات، استخدِم android_device_files[].

عند عدم استخدام android_device_dirs[] وandroid_device_files[]، يمكنك تحديد NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS وNO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (راجِع المثال أدناه). يمكنك أيضًا تحديد ملف التجاوز باستخدام TARGET_ANDROID_FILESYSTEM_CONFIG_H في إعدادات اللوحة، مع فرض اسم أساسي android_filesystem_config.h.

تضمين ملفات الإلغاء

لتضمين الملفات، تأكَّد من أنّ PRODUCT_PACKAGES يتضمّن fs_config_dirs و/أو fs_config_files حتى يتمكّن من تثبيتها في /system/etc/fs_config_dirs و/system/etc/fs_config_files على التوالي. يبحث نظام الإنشاء عن android_filesystem_config.h مخصّص في $(TARGET_DEVICE_DIR)، حيث يتوفّر BoardConfig.mk. إذا كان هذا الملف متوفّرًا في مكان آخر، اضبط متغيّر إعداد اللوحة TARGET_ANDROID_FILESYSTEM_CONFIG_H للإشارة إلى ذلك الموقع.

ضبط نظام الملفات

لضبط نظام الملفات في الإصدار 6.0 من نظام التشغيل Android والإصدارات الأحدث، اتّبِع الخطوات التالية:

  1. أنشِئ ملف $(TARGET_DEVICE_DIR)/android_filesystem_config.h.
  2. أضِف fs_config_dirs و/أو fs_config_files إلى PRODUCT_PACKAGES في ملف إعداد اللوحة (مثل $(TARGET_DEVICE_DIR)/device.mk).

مثال على الإلغاء

يعرض هذا المثال تصحيحًا لتجاوز البرنامج الخفي system/bin/glgps من أجل إضافة إمكانية استخدام قفل التنشيط في الدليل device/vendor/device. يُرجى مراعاة ما يلي:

  • كل إدخال في البنية هو الوضع والمعرّف الفريد للمستخدم والمعرّف الفريد للمجموعة والإمكانات والاسم. يتم تضمين system/core/include/private/android_filesystem_config.h تلقائيًا لتوفير تعريفات مسبقة لملف البيان (AID_ROOT وAID_SHELL وCAP_BLOCK_SUSPEND).
  • يتضمّن القسم android_device_files[] إجراءً لمنع الوصول إلى system/etc/fs_config_dirs عندما لا يتم تحديد أي قيمة، ما يوفّر حماية إضافية من خلال التحكّم في الوصول التقديري (DAC) في حال عدم توفّر محتوى لتجاوزات الدليل. ومع ذلك، هذه الحماية ضعيفة، فإذا كان بإمكان شخص التحكّم في /system، يمكنه عادةً تنفيذ أي إجراء يريده.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h
new file mode 100644
index 0000000..874195f
--- /dev/null
+++ b/android_filesystem_config.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* This file is used to define the properties of the file system
+** images generated by build tools (eg: mkbootfs) and
+** by the device side of adb.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+/* static const struct fs_path_config android_device_dirs[] = { }; */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+static const struct fs_path_config android_device_files[] = {
+  { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND),
"system/bin/glgps" },
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+};


diff --git a/device.mk b/device.mk
index 0c71d21..235c1a7 100644
--- a/device.mk
+++ b/device.mk
@@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \
     libwpa_client \
     hostapd \
     wpa_supplicant \
-    wpa_supplicant.conf
+    wpa_supplicant.conf \
+    fs_config_files

 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)

نقل أنظمة الملفات من الإصدارات السابقة

عند نقل أنظمة الملفات من Android 5.x والإصدارات الأقدم، يُرجى العِلم أنّ Android 6.x

  • تزيل هذه السمة بعض عمليات التضمين والبِنى والتعريفات المضمّنة.
  • يتطلّب ذلك الإشارة إلى libcutils بدلاً من التشغيل مباشرةً من system/core/include/private/android_filesystem_config.h. يجب أن تضيف الملفات التنفيذية الخاصة بالشركة المصنّعة للجهاز والتي تعتمد على system/code/include/private_filesystem_config.h لبُنى الملفات أو الدليل أو fs_config، تبعيات مكتبة libcutils.
  • يتطلّب ذلك أن تقدّم الشركة المصنّعة للجهاز نسخًا خاصة من فرع system/core/include/private/android_filesystem_config.h مع محتوى إضافي على الأهداف الحالية للانتقال إلى device/vendor/device/android_filesystem_config.h.
  • يحتفظ بالحق في تطبيق عناصر التحكّم الإلزامي في الوصول (MAC) في SELinux على ملفات الإعداد في النظام المستهدف، ويجب أن تضمن عمليات التنفيذ التي تتضمّن ملفات تنفيذية مخصّصة مستهدفة باستخدام fs_config() إمكانية الوصول.