کنترل دسترسی اختیاری (DAC)

سرویس‌ها و اشیای سیستم فایل که به ساخت اضافه می‌شوند اغلب به شناسه‌های یکتا و جداگانه‌ای نیاز دارند که به آن‌ها «شناسه Android» (AID) گفته می‌شود. درحال‌حاضر، بسیاری از منابع مثل فایل‌ها و خدمات به‌طور غیرضروری از AIDهای اصلی (تعریف‌شده در Android) استفاده می‌کنند؛ در بسیاری از موارد می‌توانید به‌جای آن از AIDهای سازنده اصلی محصول (تعریف‌شده در سازنده اصلی محصول) استفاده کنید.

نسخه‌های قبلی Android (نسخه Android 7.x و پایین‌تر) سازوکار شناسه Android را بااستفاده از فایل android_filesystem_config.h مختص دستگاه گسترش دادند تا قابلیت‌های سیستم فایل و/یا شناسه‌های Android سفارشی سازنده اصلی را مشخص کنند. بااین‌حال، این سیستم غیرشهودی بود زیرا از استفاده از نام‌های مناسب برای OEM AID پشتیبانی نمی‌کرد، و شما را ملزم می‌کرد که عدد خام را برای فیلدهای کاربر و گروه بدون راهی برای مرتبط کردن نامی آشنا با AID عددی مشخص کنید.

نسخه‌های جدیدتر Android (‏Android 8.0 و بالاتر) از روش جدیدی برای گسترش قابلیت‌های سیستم فایل پشتیبانی می‌کنند. این روش جدید از موارد زیر پشتیبانی می‌کند:

  • چندین مکان منبع برای فایل‌های پیکربندی (پیکربندی‌های ساخت توسعه‌پذیر را فعال می‌کند).
  • بررسی سلامت زمان ساخت مقادیر AID سازنده اصلی محصول.
  • تولید سرصفحه AID سفارشی سازنده اصلی محصول که درصورت نیاز می‌تواند در فایل‌های منبع استفاده شود.
  • اختصاص نامی آشنا به مقدار واقعی OEM AID. از آرگومان‌های رشته‌ای غیرعددی برای کاربر و گروه پشتیبانی می‌کند، یعنی «foo» به‌جای «۲۹۰۱».

بهبودهای دیگر شامل برداشتن آرایه android_ids[] از system/core/libcutils/include/private/android_filesystem_config.h است. این آرایه اکنون در Bionic به‌عنوان آرایه تولیدشده کاملاً خصوصی وجود دارد، با دسترسی‌کننده‌هایی با getpwnam() و getgrnam(). (این کار عوارض جانبی تولید باینری‌های پایدار را به‌همراه دارد زیرا AIDهای اصلی اصلاح می‌شوند.) برای ابزارها و فایل «مرا بخوان» با جزئیات بیشتر، به build/make/tools/fs_config مراجعه کنید.

افزودن شناسه‌های Android (AID)

‫Android 8.0 آرایه android_ids[] را از «پروژه منبع باز Android»‏ (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

برای افزودن یک AID اصلی AOSP جدید، کافی است #define را به فایل سرصفحه android_filesystem_config.h اضافه کنید. ‫AID در زمان ساخت تولید می‌شود و برای واسط‌هایی که از آرگومان‌های کاربر و گروه استفاده می‌کنند دردسترس قرار می‌گیرد. ابزار جدید تأیید می‌کند که AID جدید در محدوده APP یا OEM نباشد؛ همچنین تغییرات این محدوده‌ها را رعایت می‌کند و درصورت تغییر یا اضافه شدن محدوده‌های رزروشده OEM، به‌طور خودکار پیکربندی مجدد انجام می‌دهد.

پیکربندی شناسه‌های برنامه کاربردی

برای فعال کردن سازوکار جدید «شناسه‌های تبلیغ‌کننده»، TARGET_FS_CONFIG_GEN را در فایل BoardConfig.mk تنظیم کنید. این متغیر فهرستی از فایل‌های پیکربندی را دربرمی‌گیرد و به شما امکان می‌دهد فایل‌ها را درصورت نیاز پیوست کنید.

طبق قرارداد، فایل‌های پیکربندی از نام config.fs استفاده می‌کنند، اما در عمل می‌توانید از هر نامی استفاده کنید. ‫config.fs فایل در قالب Python ConfigParser ini وجود دارد و شامل بخش حروف بزرگ (برای پیکربندی قابلیت‌های سیستم فایل) و بخش AIDs (برای پیکربندی AIDs سازنده اصلی محصول) است.

پیکربندی بخش کلاهک‌ها

بخش caps از تنظیم قابلیت‌های سیستم فایل در اشیای سیستم فایل در ساخت پشتیبانی می‌کند (خود سیستم فایل نیز باید از این عملکرد پشتیبانی کند).

ازآنجایی‌که اجرای سرویس پایدار به‌عنوان ریشه در Android باعث شکست مجموعه آزمون سازگاری (CTS) می‌شود، الزامات قبلی برای حفظ قابلیت درحین اجرای فرایند یا سرویس شامل تنظیم قابلیت‌ها و سپس استفاده از setuid/setgid برای AID مناسب برای اجرا بود. با caps، می‌توانید این الزامات را نادیده بگیرید و اجازه دهید هسته این کار را برای شما انجام دهد. وقتی کنترل به main() واگذار می‌شود، فرایند شما ازقبل قابلیت‌های موردنیازش را دارد، بنابراین سرویس شما می‌تواند از کاربر و گروه غیرریشه استفاده کند (این روش ترجیحی برای شروع سرویس‌های ممتاز است).

بخش سقف از نحو زیر استفاده می‌کند:

بخش مقدار تعریف
[path] مسیر سیستم فایل برای پیکربندی. مسیر منتهی به / به‌عنوان پوشه درنظر گرفته می‌شود، درغیراین‌صورت فایل است.

مشخص کردن چندین بخش با [path] یکسان در فایل‌های مختلف خطا است. در نسخه‌های Python <= 3.2، ممکن است همان فایل حاوی بخش‌هایی باشد که بخش قبلی را لغو می‌کند؛ در Python 3.2، روی حالت سخت‌گیرانه تنظیم شده است.
mode حالت فایل هشت‌تایی حالت فایل هشت‌تایی معتبر با حداقل ۳ رقم. اگر ۳ مشخص شده باشد، با ۰ پیشوندگذاری می‌شود، درغیراین‌صورت حالت همان‌گونه که هست استفاده می‌شود.
user AID_<user> یا C define برای AID معتبر یا نام دوستانه (برای نمونه، هم AID_RADIO و هم radio قابل‌قبول هستند). برای تعریف AID سفارشی، به بخش پیکربندی AID مراجعه کنید.
group AID_<group> مشابه کاربر.
caps کلاه* نام همان‌گونه که در bionic/libc/kernel/uapi/linux/capability.h بدون CAP_ ابتدایی اعلام شده است. ترکیب حروف بزرگ و کوچک مجاز است. حروف بزرگ می‌تواند خام هم باشد:
  • دودویی (0b0101)
  • هشت‌هشتی (0455)
  • قطع توپ (۴۲)
  • مبنای ۱۶ (0xFF)
چند کلاهک را بااستفاده از فضای سفید از هم جدا کنید.

برای مشاهده نمونه استفاده، به استفاده از قابلیت‌های سیستم فایل مراجعه کنید.

پیکربندی بخش AID

بخش AID حاوی AIDهای سازنده اصلی محصول است و از نحو زیر استفاده می‌کند:

بخش مقدار تعریف
[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)
  • بخش 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)

برای نمونه‌های استفاده، تعریف نام‌های 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 سفارشی شما می‌تواند توسط سیستم به‌طور کلی در ساخت جدید مصرف شود.

استفاده از شناسه‌های برنامه سازنده اصلی محصول

برای استفاده از 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 به نام‌های دوستانه

برای AIDهای سازنده تجهیزات اصلی، Android نسخه ۸.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)

‫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 استفاده کند.

While the override method of extending the file system has been superseded by the modular config system introduced in Android 8.0, you can still use the old method if desired. بخش‌های زیر نحوه تولید و گنجاندن فایل‌های لغو و پیکربندی سیستم فایل را به‌طور دقیق شرح می‌دهند.

تولید فایل‌های لغو

می‌توانید فایل‌های باینری تراز‌شده /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 نصب کند. سیستم ساخت در $(TARGET_DEVICE_DIR) به‌دنبال android_filesystem_config.h سفارشی می‌گردد، جایی که 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 نشان می‌دهد. موارد زیر را به‌خاطر داشته باشید:

  • هر ورودی ساختار عبارت است از حالت، شناسه کاربر، شناسه گروه، قابلیت‌ها، و نام. ‫system/core/include/private/android_filesystem_config.h به‌طور خودکار اضافه می‌شود تا #define مانیفست را ارائه دهد (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

  • برخی‌از شامل‌ها، ساختارها، و تعاریف درون‌خطی را برمی‌دارد.
  • به‌جای اجرا شدن مستقیم از system/core/include/private/android_filesystem_config.h، به ارجاع به libcutils نیاز دارد. اجرایی‌های خصوصی سازنده دستگاه که به system/code/include/private_filesystem_config.h برای فایل یا ساختارهای دایرکتوری یا fs_config وابسته هستند باید وابستگی‌های کتابخانه libcutils را اضافه کنند.
  • برای انتقال به device/vendor/device/android_filesystem_config.h، به نسخه‌های شاخه خصوصی سازنده دستگاه از system/core/include/private/android_filesystem_config.h با محتوای اضافی در هدف‌های موجود نیاز است.
  • حق اعمال «کنترل‌های دسترسی اجباری» (MAC) مربوط به SELinux را برای فایل‌های پیکربندی در سیستم هدف برای خود محفوظ می‌دارد، پیاده‌سازی‌هایی که شامل فایل‌های اجرایی هدف سفارشی بااستفاده از fs_config() هستند باید دسترسی را تضمین کنند.