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

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

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

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

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

#define AID_SYSTEM 1000

يصبح:

  • الاسم الملائم: system
  • uid: ‏ 1000
  • gid: ‏ 1000

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

ضبط معرّفات AID

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

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

ضبط قسم "أحرف كبيرة"

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

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

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

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

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

للحصول على مثال عن الاستخدام، يمكنك الاطّلاع على استخدام إمكانيات نظام الملفات.

ضبط قسم 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_name]) باسم قسم مثل "vendor_" لضمان عدم تضاربها مع أسماء AOSP المستقبلية أو أقسام أخرى.

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

لتحديد معرّف AID الخاص بصانع الجهاز الأصلي، أنشئ ملف config.fs واضبط قيمة AID. على سبيل المثال، في 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 الخاص بصانع المعدّات الأصلية، يجب تضمين 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، يمكنك استخدام الاسم المعرِّف لأي واجهة متوافقة مع أسماء معرّفات AID. مثلاً:

  • في أمر 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
    

لأنّ عملية الربط الداخلية من اسم مألوف إلى معرّف uid تُطبَّق من خلال /vendor/etc/passwd و/vendor/etc/group، يجب تثبيت الجزء الخاص بالمورّد.

ربط الأسماء الودية

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

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

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

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

لتفعيل إمكانات نظام الملفات، أنشئ قسمًا للملفّات ذات الحجم الكبير في ملف 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 ويمكن حذفها.

ضبط عمليات الاستبدال (الإصدارات 6.x و7.x من Android)

غيّر نظام التشغيل Android 6.0 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. من خلال استخدام قواعد مطابقة وتحليل منفصلة للأدلة والملفات (التي يمكن أن تستخدم تعبيرات منتظمة إضافية)، تمكّن 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 تلقائيًا لتوفير التعريفات #defines في البيان (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() إمكانية الوصول.