自主訪問控制 (DAC)

添加到構建中的文件系統對象和服務經常需要單獨的、唯一的 ID,稱為 Android ID (AID)。目前,許多資源(例如文件和服務)不必要地使用核心(Android 定義的)AID;在許多情況下,您可以改用 OEM(OEM 定義的)AID。

的Android的早期版本(的Android 7.x和降低),使用設備特定的擴展艾滋病機構android_filesystem_config.h文件指定的文件系統的能力和/或定制的OEM助劑。但是,該系統不直觀,因為它不支持為 OEM AID 使用好聽的名稱,要求您為用戶和組字段指定原始數字,而無法將友好名稱與數字 AID 相關聯。

較新版本的 Android(Android 8.0 及更高版本)支持擴展文件系統功能的新方法。這種新方法支持以下內容:

  • 配置文件的多個源位置(啟用可擴展的構建配置)。
  • OEM AID 值的構建時健全性檢查。
  • 生成可根據需要在源文件中使用的自定義 OEM AID 標頭。
  • 友好名稱與實際 OEM AID 值的關聯。支持用戶和組的非數字字符串參數,即“foo”而不是“2901”。

其他改進包括除去的android_ids[]從陣列system/core/libcutils/include/private/android_filesystem_config.h 。此陣列現在仿生存在作為一個完全私人產生陣列,經由存取getpwnam()getgrnam() (這有生產穩定的二進制文件為核心的艾滋病被修改的副作用)。對於工具和更多細節的README文件,請參閱build/make/tools/fs_config

添加 Android ID (AID)

的Android 8.0除去android_ids[]從Android開源項目(AOSP)陣列。所有AID友好名稱,而不是從生成的system/core/libcutils/include/private/android_filesystem_config.h產生仿生時頭文件android_ids[]數組。任何define匹配AID_*由加工拿起和*變成小寫的名字。

例如,在private/android_filesystem_config.h

#define AID_SYSTEM 1000

變成:

  • 友好名稱:系統
  • 用戶名:1000
  • gid:1000

要添加新的AOSP核心AID,只需將增加#defineandroid_filesystem_config.h頭文件。 AID 將在構建時生成並提供給使用用戶和組參數的接口。工具驗證新的 AID 不在 APP 或 OEM 範圍內;它還尊重對這些範圍的更改,並應根據更改或新的 OEM 保留範圍自動重新配置。

配置 AID

為了使艾滋病新機制,集TARGET_FS_CONFIG_GENBoardConfig.mk文件。此變量包含配置文件列表,使您能夠根據需要附加文件。

按照慣例,配置文件使用的名稱config.fs ,但實際上,你可以使用任何名字。 config.fs文件是在Python的ConfigParser INI格式和包括(用於配置文件系統功能)一蓋部和艾滋病部(用於配置OEM助劑)。

配置 caps 部分

帽部分支持設置文件系統功能的文件系統構建(文件系統本身也必須支持此功能)中的對象。

由於運行穩定服務作為Android的根源兼容性測試套件(CTS)失敗,用於保持能力,同時運行的進程或服務涉案設置功能,然後使用先前要求setuid / setgid到合適的AID運行。使用上限,您可以跳過這些要求並讓內核為您完成。當控制交給main()你的進程已經擁有它需要讓你的服務可以使用非root用戶和組(這是啟動特權服務的首選方式)的能力。

caps 部分使用以下語法:

部分價值定義
[path]要配置的文件系統路徑。以 / 結尾的路徑被認為是一個目錄,否則它是一個文件。

它是具有相同指定多個部分的誤差[path]在不同的文件。在 Python 版本 <= 3.2 中,同一個文件可能包含覆蓋上一部分的部分;在 Python 3.2 中,它被設置為嚴格模式。
mode八進製文件模式至少 3 位的有效八進製文件模式。如果指定了 3,則以 0 為前綴,否則按原樣使用模式。
user AID_<用戶>不管是C define為一個有效的或AID的友好名稱(例如兩者AID_RADIOradio是可接受的)。要定義自定義幫助,請參見配置AID部分
group AID_<組>與用戶相同。
caps帽*在聲明的名稱bionic/libc/kernel/uapi/linux/capability.h沒有前導CAP_ 。允許混合大小寫。 Caps 也可以是原始的:
  • 二進制 (0b0101)
  • 八進制 (0455)
  • 內部 (42)
  • 十六進制 (0xFF)
使用空格分隔多個大寫字母。

對於使用示例,請參閱使用文件系統功能

配置 AID 部分

AID 部分包含 OEM 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艾滋病

使用示例

以下示例詳細說明瞭如何定義和使用 OEM AID 以及如何啟用文件系統功能。 OEM AID名([AID_])必須與分區名稱開頭,如“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 AID

要使用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
    
  • servicesome/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_富”,而不是“2901”。

從 AID 轉換為友好名稱

對於OEM艾滋病,Android的8.x中需要使用的oem_####getpwnam和類似的功能,以及在地方在於通過手柄查找getpwnam (如init腳本)。在Android中9,您可以使用getpwnamgetgrnam在仿生朋友從Android的標識(AIDS)轉換成友好的名稱,反之亦然。

使用文件系統功能

要啟用文件系統功能,建立在一個蓋部分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_ADMINCAP_SYS_NICE沒有setuidsetgid電話。此外, vendor_ foo服務的SELinux策略不再需要能力setuidsetgid ,可以被刪除。

配置覆蓋(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_DIRSNO_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_filesPRODUCT_PACKAGES板的配置文件(例如,在$(TARGET_DEVICE_DIR)/device.mk )。

覆蓋示例

此示例示出了用於重寫一個補丁system/bin/glgps守護進程在添加之後鎖支撐device/ vendor / device目錄。請記住以下幾點:

  • 每個結構條目是模式、uid、gid、功能和名稱。 system/core/include/private/android_filesystem_config.h被自動包括以提供對清單#定義( AID_ROOTAID_SHELLCAP_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()必須保證訪問。