Điều khiển truy cập tuỳ ý (DAC)

Các đối tượng và dịch vụ hệ thống tệp được thêm vào bản dựng thường cần riêng biệt, mã nhận dạng duy nhất, còn được gọi là mã nhận dạng Android (AID). Hiện tại, nhiều tài nguyên như các tệp và dịch vụ sử dụng AID (do Android xác định) cốt lõi (do Android xác định) không cần thiết; trong nhiều các trường hợp, bạn có thể sử dụng AID của OEM (do OEM xác định).

Các phiên bản Android cũ (Android 7.x trở xuống) đã mở rộng AID cơ chế sử dụng android_filesystem_config.h dành riêng cho thiết bị để chỉ định các khả năng của hệ thống tệp và/hoặc AID của OEM tuỳ chỉnh. Tuy nhiên, việc này hệ thống không trực quan vì nó không hỗ trợ sử dụng tên hay cho AID của OEM, yêu cầu bạn chỉ định số thô cho các trường nhóm và người dùng mà không có để kết hợp tên thân thiện với AID dạng số.

Các phiên bản Android mới hơn (Android 8.0 trở lên) hỗ trợ một phương thức mới để mở rộng khả năng của hệ thống tệp. Phương thức mới này hỗ trợ cho sau:

  • Nhiều vị trí nguồn cho các tệp cấu hình (cho phép mở rộng cấu hình bản dựng).
  • Kiểm tra mức độ hợp lý trong thời gian xây dựng của các giá trị AID của OEM.
  • Tạo tiêu đề AID của OEM tuỳ chỉnh có thể được sử dụng trong các tệp nguồn dưới dạng cần thiết.
  • Liên kết tên thân thiện với giá trị AID của OEM thực tế. Hỗ trợ đối số chuỗi không phải là số cho người dùng và nhóm, ví dụ: "foo" thay vì "2901".

Các điểm cải tiến khác bao gồm việc xoá android_ids[] mảng từ system/core/libcutils/include/private/android_filesystem_config.h. Chiến dịch này mảng này hiện tồn tại trong Bionic dưới dạng một mảng được tạo hoàn toàn riêng tư, với trình truy cập có getpwnam()getgrnam(). (Kết quả này có tác dụng phụ của việc tạo tệp nhị phân ổn định khi AID chính được sửa đổi.) Cho và tệp README có thông tin chi tiết hơn, hãy tham khảo build/make/tools/fs_config.

Thêm mã nhận dạng thiết bị Android (AID)

Android 8.0 đã xoá mảng android_ids[] khỏi Android Dự án nguồn mở (AOSP). Tất cả tên thân thiện với AID được tạo từ system/core/libcutils/include/private/android_filesystem_config.h khi tạo mảng android_ids[] Bionic. Bất kỳ hạng nào Công cụ chọn define trùng khớp với AID_** trở thành tên viết thường.

Ví dụ: trong private/android_filesystem_config.h:

#define AID_SYSTEM 1000

Trở thành:

  • Tên phù hợp: system
  • uid: 1000
  • cố định: 1000

Để thêm AID lõi AOSP mới, chỉ cần thêm #define vào Tệp tiêu đề android_filesystem_config.h. AID là được tạo khi tạo bản dựng và cung cấp cho các giao diện sử dụng người dùng và nhóm đối số. Công cụ xác thực mã nhận dạng mới không nằm trong APP hoặc OEM các dải ô; nó cũng tuân theo các thay đổi đối với các phạm vi đó và sẽ tự động định cấu hình lại các thay đổi hoặc dải ô mới dành riêng cho OEM.

Định cấu hình AID

Để bật cơ chế AID mới, hãy đặt TARGET_FS_CONFIG_GEN trong BoardConfig.mk. Biến này chứa danh sách cấu hình tệp, cho phép bạn nối tệp khi cần.

Theo quy ước, tệp cấu hình sử dụng tên config.fs, nhưng trong bạn có thể sử dụng bất kỳ tên nào. config.fs tệp nằm trong Python Định dạng ini ConfigParer và thêm phần viết hoa (để định cấu hình tệp chức năng hệ thống) và phần AID (để định cấu hình AID của OEM).

Định cấu hình mục giới hạn

Mục giới hạn hỗ trợ chế độ cài đặt tệp khả năng hệ thống trên đối tượng hệ thống tệp trong bản dựng (hệ thống tệp chính nó cũng phải hỗ trợ chức năng này).

Vì việc chạy một dịch vụ ổn định dưới dạng thư mục gốc trong Android sẽ gây ra Bộ kiểm tra tính tương thích (CTS) lỗi, các yêu cầu trước đây để duy trì một chức năng trong khi chạy một quá trình hoặc dịch vụ liên quan đến việc thiết lập các khả năng sau đó sử dụng setuid/setgid thành một AID phù hợp để chạy. Với chữ hoa, bạn có thể bỏ qua các yêu cầu này và để nhân thực hiện việc đó cho bạn. Khi chế độ kiểm soát là được chuyển giao cho main(), quy trình của bạn đã có các khả năng để dịch vụ của bạn có thể sử dụng người dùng và nhóm không phải người dùng gốc (đây là để bắt đầu các dịch vụ đặc quyền).

Phần giới hạn sử dụng cú pháp sau:

Khu Giá trị Định nghĩa
[path] Đường dẫn hệ thống tệp để định cấu hình. Đường dẫn kết thúc bằng / được coi là dir, nếu không thì đó là một tệp.

Có thể xảy ra lỗi khi chỉ định nhiều mục bằng cùng một [path] trong các tệp khác nhau. Trong các phiên bản Python <= 3.2, giá trị cùng một tệp có thể chứa các phần ghi đè phần trước; trong Python 3.2, chế độ này được đặt ở chế độ nghiêm ngặt.
mode Chế độ tệp bát phân Chế độ tệp bát phân hợp lệ có ít nhất 3 chữ số. Nếu bạn chỉ định 3, thì đó là có tiền tố là 0, chế độ else sẽ được sử dụng như nguyên trạng.
user AID_<người dùng> C define cho AID hợp lệ hoặc tên thân thiện (ví dụ: có thể chấp nhận cả AID_RADIOradio). Người nhận xác định AID tuỳ chỉnh, xem phần Định cấu hình phần AID.
group AID_<nhóm> Giống như người dùng.
caps mũ* Tên như được khai báo trong bionic/libc/kernel/uapi/linux/capability.h mà không có CAP_ đứng đầu. Cho phép viết hoa chữ thường. Viết hoa cũng có thể dữ liệu thô:
  • nhị phân (0b0101)
  • bát phân (0455)
  • int (42)
  • hệ lục phân (0xFF)
Phân tách nhiều chữ hoa bằng khoảng trắng.

Để biết ví dụ về cách sử dụng, hãy xem phần Sử dụng tệp khả năng của hệ thống.

Định cấu hình mục AID

Phần AID chứa các AID của OEM và sử dụng cú pháp sau:

Khu Giá trị Định nghĩa
[AID_<name>] <name> có thể chứa các ký tự trong tập hợp chữ hoa, số và dấu gạch dưới. Phiên bản chữ thường được dùng làm tên thân thiện. Tệp tiêu đề được tạo để bao gồm mã sử dụng tệp tiêu đề chính xác AID_<name>.

Có thể xảy ra lỗi khi chỉ định nhiều mục bằng cùng một AID_<name> (không phân biệt chữ hoa chữ thường với các điều kiện ràng buộc tương tự như [path]).

<name> phải bắt đầu bằng tên phân vùng để đảm bảo để không xung đột với các nguồn khác.
value <số> Một chuỗi số kiểu C hợp lệ (thập lục phân, bát phân, nhị phân và thập phân).

Có thể xảy ra lỗi khi chỉ định nhiều mục bằng cùng một lựa chọn giá trị.

Bạn phải chỉ định các lựa chọn về giá trị trong dải ô tương ứng với phân vùng được dùng trong <name>. Danh sách các phân vùng hợp lệ và các phân vùng tương ứng được xác định trong system/core/libcutils/include/private/android_filesystem_config.h. Các tùy chọn bao gồm:
  • Phân vùng nhà cung cấp
    • AID_OEM_RESERVED_START(2900) – AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) – AID_OEM_RESERVED_2_END(5999)
  • Phân vùng hệ thống
    • AID_SYSTEM_RESERVED_START(6000) – AID_SYSTEM_RESERVED_END(6499)
  • Phân vùng ODM
    • AID_ODM_RESERVED_START(6500) – AID_ODM_RESERVED_END(6999)
  • Phân vùng sản phẩm
    • AID_PRODUCT_RESERVED_START(7000) – AID_PRODUCT_RESERVED_END(7499)
  • Phân vùng System_ext
    • AID_SYSTEM_EXT_RESERVED_START(7500) – AID_SYSTEM_EXT_RESERVED_END(7999)

Để biết các ví dụ về cách sử dụng, hãy xem phần Định nghĩa OEM Tên AIDSử dụng AID của OEM.

Ví dụ về cách dùng

Các ví dụ sau đây trình bày chi tiết cách định nghĩa và sử dụng AID của OEM (Nhà sản xuất thiết bị gốc) cũng như cách bật các chức năng của hệ thống tệp. Tên AID của OEM (Nhà sản xuất thiết bị gốc) ([AID_name]) phải bắt đầu bằng tên phân vùng, chẳng hạn như "vendor_" để đảm bảo chúng không xung đột với tương lai Tên AOSP hoặc các phân vùng khác.

Xác định tên AID của OEM (Nhà sản xuất thiết bị gốc)

Để xác định AID của OEM, hãy tạo một tệp config.fs và thiết lập giá trị AID. Ví dụ: trong device/x/y/config.fs, đặt giá trị sau:

[AID_VENDOR_FOO]
value: 2900

Sau khi tạo tệp, hãy đặt biến TARGET_FS_CONFIG_GEN và trỏ vào đó trong BoardConfig.mk. Ví dụ: trong device/x/y/BoardConfig.mk, hãy thiết lập các giá trị sau:

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

Hệ thống hiện có thể sử dụng AID tuỳ chỉnh của bạn trên một bản dựng mới.

Sử dụng AID của OEM

Để sử dụng mã AID của OEM, trong mã C, hãy thêm oemaids_headers vào Makefile và thêm #include "generated_oem_aid.h", sau đó bắt đầu sử dụng các thuộc tính đã khai báo giá trị nhận dạng. Ví dụ: trong my_file.c, hãy thêm đoạn mã sau:

#include "generated_oem_aid.h"
…

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

Trong tệp Android.bp được liên kết, hãy thêm đoạn mã sau:

header_libs: ["oemaids_headers"],

Nếu bạn đang sử dụng tệp Android.mk, hãy thêm đoạn mã sau:

LOCAL_HEADER_LIBRARIES := oemaids_headers

Sử dụng tên thân thiện

Trong Android 9, bạn có thể sử dụng tên thân thiện cho bất kỳ giao diện hỗ trợ tên AID. Ví dụ:

  • Trong một lệnh chownsome/init.rc:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • Trong một servicesome/init.rc:
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Vì việc ánh xạ nội bộ từ tên thân thiện đến uid được thực hiện bởi /vendor/etc/passwd/vendor/etc/group, nhà cung cấp phân vùng phải được gắn kết.

Liên kết tên thân thiện

Android 9 có hỗ trợ liên kết tên thân thiện cùng với giá trị AID của OEM thực tế. Bạn có thể sử dụng chuỗi không phải số đối số cho người dùng và nhóm, tức là "vendor_foo" thay vì "2901".

Chuyển đổi từ AID sang tên thân thiện

Cho AID của OEM, Android 8.x yêu cầu sử dụng oem_#### với getpwnam và các hàm tương tự, như tốt ở những vị trí xử lý việc tra cứu bằng getpwnam (chẳng hạn như init tập lệnh). Trong Android 9, bạn có thể sử dụng bạn bè getpwnamgetgrnam trong Bionic cho chuyển đổi từ mã nhận dạng Android (AID) sang tên thân thiện và ngược lại.

Sử dụng các chức năng của hệ thống tệp

Để bật các chức năng của hệ thống tệp, hãy tạo một phần giới hạn trong Tệp config.fs. Ví dụ: trong device/x/y/config.fs, thêm phần sau:

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

Sau khi tạo tệp, hãy đặt TARGET_FS_CONFIG_GEN để trỏ đến tệp đó trong BoardConfig.mk. Ví dụ: trong device/x/y/BoardConfig.mk, hãy thiết lập các giá trị sau:

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

Khi dịch vụ vendor_foo được thực thi, dịch vụ sẽ bắt đầu với các tính năng CAP_SYS_ADMINCAP_SYS_NICE mà không có cuộc gọi setuidsetgid. Ngoài ra, Chính sách SELinux của dịch vụ vendor_foo không còn nữa cần chức năng setuidsetgid và có thể đã bị xoá.

Định cấu hình chế độ ghi đè (Android 6.x-7.x)

Android 6.0 đã di chuyển fs_config và cấu trúc liên quan định nghĩa (system/core/include/private/android_filesystem_config.h) đến system/core/libcutils/fs_config.c nơi chúng có thể được cập nhật hoặc bị ghi đè bởi các tệp nhị phân được cài đặt trong /system/etc/fs_config_dirs/system/etc/fs_config_files. Sử dụng kiểu so khớp và phân tích cú pháp riêng biệt quy tắc cho các thư mục và tệp (có thể sử dụng các biểu thức toàn cầu khác) cho phép Android xử lý các thư mục và tệp trong hai bảng khác nhau. Định nghĩa cấu trúc bằng system/core/libcutils/fs_config.c không chỉ cho phép đọc thư mục và tệp trong thời gian chạy, nhưng máy chủ lưu trữ có thể sử dụng các tệp giống nhau trong thời gian xây dựng để tạo hình ảnh hệ thống tệp như ${OUT}/system/etc/fs_config_dirs${OUT}/system/etc/fs_config_files.

Mặc dù phương pháp ghi đè mở rộng hệ thống tệp đã được thay thế bằng hệ thống cấu hình mô-đun được giới thiệu trong Android 8.0, bạn vẫn có thể sử dụng hệ thống cấu hình cũ nếu muốn. Các phần sau đây trình bày chi tiết về cách tạo và thêm ghi đè tệp và định cấu hình hệ thống tệp.

Tạo tệp ghi đè

Bạn có thể tạo các tệp nhị phân được căn chỉnh /system/etc/fs_config_dirs/system/etc/fs_config_files bằng cách sử dụng Công cụ fs_config_generate trong build/tools/fs_config. Chiến lược phát hành đĩa đơn công cụ dùng hàm thư viện libcutils (fs_config_generate()) để quản lý các yêu cầu về DAC vào vùng đệm và định nghĩa các quy tắc cho một tệp đưa vào để thể chế hoá các quy tắc DAC.

Để sử dụng, hãy tạo một tệp đính kèm trong device/vendor/device/android_filesystem_config.h đóng vai trò là thông tin ghi đè. Tệp này phải sử dụng Định dạng structure fs_path_config được xác định trong system/core/include/private/android_filesystem_config.h bằng các cách khởi tạo cấu trúc sau đây cho các biểu tượng thư mục và tệp:

  • Đối với thư mục, hãy dùng android_device_dirs[].
  • Đối với tệp, hãy dùng android_device_files[].

Khi không sử dụng android_device_dirs[]android_device_files[], bạn có thể xác định NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRSNO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (xem ví dụ bên dưới). Bạn cũng có thể chỉ định chế độ ghi đè bằng cách sử dụng TARGET_ANDROID_FILESYSTEM_CONFIG_H trong bảng cấu hình, có tên cơ sở được thực thi là android_filesystem_config.h.

Bao gồm các tệp ghi đè

Để bao gồm tệp, hãy đảm bảo rằng PRODUCT_PACKAGES bao gồm fs_config_dirs và/hoặc fs_config_files để có thể cài đặt chúng vào /system/etc/fs_config_dirs/system/etc/fs_config_files. Hệ thống xây dựng tìm kiếm android_filesystem_config.h tuỳ chỉnh trong $(TARGET_DEVICE_DIR), trong đó BoardConfig.mk tồn tại. Nếu tệp này tồn tại ở nơi khác, hãy đặt biến cấu hình bảng TARGET_ANDROID_FILESYSTEM_CONFIG_H để trỏ đến vị trí đó.

Định cấu hình hệ thống tệp

Cách định cấu hình hệ thống tệp trong Android 6.0 trở lên:

  1. Tạo $(TARGET_DEVICE_DIR)/android_filesystem_config.h .
  2. Thêm fs_config_dirs và/hoặc fs_config_files vào PRODUCT_PACKAGES trong tệp cấu hình bảng (ví dụ: $(TARGET_DEVICE_DIR)/device.mk).

Ví dụ về ghi đè

Ví dụ này cho thấy một bản vá để ghi đè system/bin/glgps trình nền để thêm hỗ trợ khoá chế độ thức trong Thư mục device/vendor/device. Giữ nguyên những lưu ý sau:

  • Mỗi mục cấu trúc là chế độ, uid, tốc độ, chức năng và tên. system/core/include/private/android_filesystem_config.h là tự động được đưa vào để cung cấp tệp kê khai #defines (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND).
  • Phần android_device_files[] bao gồm một thao tác để chặn quyền truy cập vào system/etc/fs_config_dirs khi không được chỉ định, hoạt động như một lớp bảo vệ DAC bổ sung trong trường hợp thiếu nội dung cho thư mục ghi đè. Tuy nhiên, đây là khả năng bảo vệ yếu; nếu ai đó có quyền kiểm soát /system, họ thường có thể làm bất cứ việc gì họ muốn.
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)

Di chuyển hệ thống tệp từ các bản phát hành trước

Khi di chuyển hệ thống tệp từ Android 5.x trở xuống, hãy nhớ rằng Android 6.x

  • Xoá một số phần bao gồm, cấu trúc và định nghĩa cùng dòng.
  • Yêu cầu tham chiếu đến libcutils thay vì chạy trực tiếp từ system/core/include/private/android_filesystem_config.h. Các tệp thực thi riêng tư của nhà sản xuất thiết bị phụ thuộc vào system/code/include/private_filesystem_config.h cho tệp hoặc cấu trúc thư mục hoặc fs_config phải thêm libcutils phần phụ thuộc thư viện.
  • Yêu cầu các bản sao nhánh riêng của nhà sản xuất thiết bị của system/core/include/private/android_filesystem_config.h bằng nội dung bổ sung trên các mục tiêu hiện tại cần chuyển sang device/vendor/device/android_filesystem_config.h.
  • Giữ quyền áp dụng các chế độ kiểm soát truy cập bắt buộc (MAC) SELinux cho tệp cấu hình trên hệ thống mục tiêu, các triển khai bao gồm các tệp thực thi mục tiêu đang sử dụng fs_config() phải đảm bảo quyền truy cập.