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

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

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

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

  • مواقع مصادر متعددة لملفات التكوين (تتيح تكوينات بناء قابلة للتوسيع).
  • التحقق من سلامة وقت الإنشاء لقيم AID لـ OEM.
  • إنشاء رأس OEM AID مخصص يمكن استخدامه في الملفات المصدر حسب الحاجة.
  • اقتران اسم مألوف بقيمة OEM 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 (AIDs)

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

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

#define AID_SYSTEM 1000

يصبح:

  • الاسم المألوف: النظام
  • uid: 1000
  • gid: 1000

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

تكوين المساعدات

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

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

تكوين قسم القبعات

يدعم قسم caps إعداد إمكانيات نظام الملفات على كائنات نظام الملفات داخل الإنشاء (يجب أن يدعم نظام الملفات نفسه هذه الوظيفة أيضًا).

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

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

الجزء قيمة تعريف
[path] مسار نظام الملفات المطلوب تكوينه. المسار الذي ينتهي بـ / يعتبر dir ، وإلا فهو ملف.

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

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

تكوين قسم AID

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

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

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

يجب أن يبدأ <name> قسم للتأكد من أنه لا يتعارض مع المصادر المختلفة.
value <رقم> سلسلة رقم صالحة للنمط 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)
  • قسم التصميم
    • 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)

للحصول على أمثلة للاستخدام ، راجع تحديد أسماء OEM AID واستخدام OEM AID.

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

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

تحديد أسماء OEM AID

لتعريف OEM 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 المخصص الخاص بك.

استخدام مساعدات OEM

لاستخدام OEM AID ، في كود C الخاص بك ، قم بتضمين oemaids_headers في Makefile المرتبط ، وأضف #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 دعمًا لربط اسم مألوف بقيمة OEM AID الفعلية. يمكنك استخدام وسيطات سلسلة غير رقمية للمستخدم والمجموعة ، مثل " vendor_ foo" بدلاً من "2901".

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

بالنسبة إلى معرّفات OEM ، تطلب Android 8.x استخدام oem_#### مع getpwnam والوظائف المماثلة ، وكذلك في الأماكن التي تتعامل مع عمليات البحث عبر getpwnam (مثل البرامج النصية init ). في Android 9 ، يمكنك استخدام getpwnam و getgrnam friends في 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 بحاجة إلى setgid setuid حذفها.

تكوين التجاوزات (Android 6.x-7.x)

تم تغيير موقع 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 . إن استخدام قواعد المطابقة والتحليل المنفصلة للأدلة والملفات (التي يمكن أن تستخدم تعبيرات 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 للإشارة إلى هذا الموقع.

تكوين نظام الملفات

لتهيئة نظام الملفات في Android 6.0 والإصدارات الأحدث:

  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 . ضع في اعتبارك ما يلي:

  • كل إدخال هيكل هو الوضع ، uid ، gid ، والإمكانيات ، والاسم. يتم تضمين 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 filesystem
+** 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 .
  • يحتفظ بالحق في تطبيق عناصر التحكم في الوصول الإلزامية SELinux (MAC) على ملفات التكوين على النظام الهدف ، ويجب أن تضمن التطبيقات التي تتضمن الملفات التنفيذية المستهدفة المخصصة باستخدام fs_config() الوصول.