Kiểm soát truy cập tùy ý (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 các ID riêng biệt, duy nhất, được gọi là ID Android (AID). Hiện tại, nhiều tài nguyên như tệp và dịch vụ sử dụng AID cốt lõi (do Android xác định) một cách không cần thiết; trong nhiều trường hợp, bạn có thể sử dụng AID OEM (do OEM xác định) để thay thế.

Các phiên bản Android trước đó (Android 7.x trở xuống) đã mở rộng cơ chế AID bằng cách sử dụng tệp 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 OEM tùy chỉnh. Tuy nhiên, hệ thống này không trực quan vì nó không hỗ trợ sử dụng tên đẹp cho OEM AID, yêu cầu bạn chỉ định số thô cho trường người dùng và nhóm mà không có cách liên kết tên thân thiện với AID số.

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

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

Các cải tiến bổ sung bao gồm việc xóa mảng android_ids[] khỏi system/core/libcutils/include/private/android_filesystem_config.h . Mảng này hiện tồn tại trong Bionic dưới dạng mảng được tạo hoàn toàn riêng tư, với các bộ truy cập thông qua getpwnam()getgrnam() . (Điều này có tác dụng phụ là tạo ra các tệp nhị phân ổn định khi các AID cốt lõi được sửa đổi.) Để biết công cụ và tệp README có nhiều chi tiết hơn, hãy tham khảo build/make/tools/fs_config .

Thêm ID Android (AID)

Android 8.0 đã xóa mảng android_ids[] khỏi Dự án mã nguồn mở Android (AOSP). Thay vào đó, tất cả các tên thân thiện với AID đều được tạo từ tệp tiêu đề system/core/libcutils/include/private/android_filesystem_config.h khi tạo mảng Bionic android_ids[] . Bất kỳ define nào khớp với AID_* đều được công cụ chọn và * 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 thân thiện: hệ thống
  • uid: 1000
  • gid: 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 sẽ được tạo khi xây dựng và cung cấp cho các giao diện sử dụng đối số người dùng và nhóm. Công cụ này xác nhận AID mới không nằm trong phạm vi APP hoặc OEM; nó cũng tôn trọng những thay đổi đối với các phạm vi đó và sẽ tự động cấu hình lại theo những thay đổi hoặc phạm vi mới dành riêng cho OEM.

Định cấu hình AID

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

Theo quy ước, các tệp cấu hình sử dụng tên config.fs , nhưng trong thực tế, bạn có thể sử dụng bất kỳ tên nào. Các tệp config.fsđịnh dạng ini Python ConfigParser và bao gồm phần mũ (để định cấu hình khả năng của hệ thống tệp) và phần AID (để định cấu hình OEM AID).

Định cấu hình phần mũ

Phần mũ hỗ trợ cài đặt các khả năng của hệ thống tệp trên các đối tượng hệ thống tệp trong bản dựng (bản thân hệ thống tệp cũng phải hỗ trợ chức năng này).

Vì việc chạy một dịch vụ ổn định bằng quyền root trong Android gây ra lỗi Bộ kiểm tra tương thích (CTS) , nên các yêu cầu trước đó để duy trì một khả năng trong khi chạy một quy 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 cho AID thích hợp để chạy. Với mũ, bạn có thể bỏ qua các yêu cầu này và để hạt nhân thực hiện việc đó cho bạn. Khi quyền kiểm soát được chuyển cho main() , quy trình của bạn đã có sẵn các khả năng cần thiết để dịch vụ của bạn có thể sử dụng nhóm và người dùng không phải root (đây là cách ưa thích để bắt đầu các dịch vụ đặc quyền).

Phần mũ sử dụng cú pháp sau:

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

Sẽ có lỗi khi chỉ định nhiều phần có cùng [path] trong các tệp khác nhau. Trong các phiên bản Python <= 3.2, cùng một tệp có thể chứa các phần ghi đè phần trước đó; trong Python 3.2, nó được đặt ở chế độ nghiêm ngặt.
mode Chế độ tập tin bát phân Chế độ tệp bát phân hợp lệ có ít nhất 3 chữ số. Nếu 3 được chỉ định, nó có tiền tố là 0, chế độ khác sẽ được sử dụ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ả AID_RADIOradio đều được chấp nhận). Để xác định AID tùy chỉnh, hãy xem phần Định cấu hình AID .
group AID_<nhóm> Tương tự như người dùng.
caps mũ lưỡi trai* Tên được khai báo trong bionic/libc/kernel/uapi/linux/capability.h không có CAP_ ở đầu. Trường hợp hỗn hợp được phép. Mũ cũng có thể là dạng thô:
  • nhị phân (0b0101)
  • bát phân (0455)
  • int (42)
  • thập lục phân (0xFF)
Tách nhiều chữ hoa bằng cách sử dụng khoảng trắng.

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

Cấu hình phần AID

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

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

Sẽ là lỗi khi chỉ định nhiều phần có cùng AID_<name> (không phân biệt chữ hoa chữ thường với cùng các ràng buộc như [path] ).

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

Đó là một lỗi khi chỉ định nhiều phần có cùng tùy chọn giá trị.

Các tùy chọn giá trị phải được chỉ định trong phạm vi tương ứng với phân vùng được sử dụng trong <name> . Danh sách các phân vùng hợp lệ và phạm vi tương ứng của chúng được xác định trong system/core/libcutils/include/private/android_filesystem_config.h . Các tùy chọn là:
  • 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_PRODVED_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 ví dụ về cách sử dụng, hãy xem Xác định tên OEM AIDSử dụng OEM AID .

Ví dụ sử dụng

Các ví dụ sau nêu chi tiết cách xác định và sử dụng OEM AID cũng như cách kích hoạt các chức năng của hệ thống tệp. Tên OEM AID ( [AID_ name ] ) phải bắt đầu bằng tên phân vùng chẳng hạn như " nhà cung cấp_ " để đảm bảo chúng không xung đột với tên AOSP hoặc các phân vùng khác trong tương lai.

Xác định tên OEM AID

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

[AID_VENDOR_FOO]
value: 2900

Sau khi tạo file, hãy đặt biến TARGET_FS_CONFIG_GEN và trỏ đến nó trong BoardConfig.mk . Ví dụ: trong device/x/y/BoardConfig.mk , hãy đặt như sau:

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

Giờ đây, AID tùy chỉnh của bạn có thể được hệ thống sử dụng rộng rãi trên bản dựng mới.

Sử dụng OEM AID

Để sử dụng OEM AID, trong mã C của bạn, hãy bao gồm oemaids_headers trong Makefile được liên kết của bạn và thêm #include "generated_oem_aid.h" , sau đó bắt đầu sử dụng số nhận dạng đã khai báo. Ví dụ: trong my_file.c , hãy thêm thông tin sau:

#include "generated_oem_aid.h"
…

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

Trong tệp Android.bp được liên kết của bạn, hãy thêm thông tin sau:

header_libs: ["oemaids_headers"],

Nếu bạn đang sử dụng tệp Android.mk , hãy thêm phần 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 nào hỗ trợ tên AID. Ví dụ:

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

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

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

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

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

Đối với OEM AID , Android 8.x yêu cầu sử dụng oem_#### với getpwnam và các chức năng tương tự, cũng như ở những nơi xử lý tra cứu thông qua getpwnam (chẳng hạn như tập lệnh init ). Trong Android 9, bạn có thể sử dụng bạn bè getpwnamgetgrnam trong Bionic để chuyển đổi từ ID Android (AID) sang tên thân thiện và ngược lại.

Sử dụng khả năng của hệ thống tập tin

Để kích hoạt các khả năng của hệ thống tệp, hãy tạo phần mũ trong tệp config.fs . Ví dụ: trong device/x/y/config.fs , hãy 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 file, hãy đặt TARGET_FS_CONFIG_GEN để trỏ đến file đó trong BoardConfig.mk . Ví dụ: trong device/x/y/BoardConfig.mk , hãy đặt như sau:

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

Khi nhà cung cấp vendor_ foo được thực thi, nó sẽ bắt đầu với các khả năng CAP_SYS_ADMINCAP_SYS_NICE mà không cần các lệnh gọi setuidsetgid . Ngoài ra, chính sách SELinux của dịch vụ vendor_ foo không còn cần khả năng setuidsetgid và có thể bị xóa.

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

Android 6.0 đã chuyển fs_config và các định nghĩa cấu trúc liên quan ( system/core/include/private/android_filesystem_config.h ) sang system/core/libcutils/fs_config.c nơi chúng có thể được cập nhật hoặc ghi đè bằng các tệp nhị phân được cài đặt trong /system/etc/fs_config_dirs/system/etc/fs_config_files . Việc sử dụng các quy tắc phân tích và so khớp riêng biệt cho các thư mục và tệp (có thể sử dụng các biểu thức toàn cầu bổ sung) đã cho phép Android xử lý các thư mục và tệp trong hai bảng khác nhau. Các định nghĩa cấu trúc trong system/core/libcutils/fs_config.c không chỉ cho phép đọc các thư mục và tệp trong thời gian chạy mà máy chủ còn có thể sử dụng các tệp tương tự trong thời gian xây dựng để xây dựng 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 phương pháp cũ nếu muốn. Các phần sau đây trình bày chi tiết cách tạo và bao gồm các tệp ghi đè cũng như định cấu hình hệ thống tệp.

Tạo tập tin 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 . Công cụ này sử dụng chức năng thư viện libcutils ( fs_config_generate() ) để quản lý các yêu cầu DAC vào bộ đệm và xác định các quy tắc cho tệp bao gồm để thể chế hóa các quy tắc DAC.

Để sử dụng, hãy tạo một tệp bao gồm trong device/ vendor / device /android_filesystem_config.h đóng vai trò ghi đè. Tệp 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 với các khởi tạo cấu trúc sau cho ký hiệu thư mục và tệp:

  • Đối với các thư mục, hãy sử dụng android _device _dirs[] .
  • Đối với các tệp, hãy sử 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 tệp ghi đè bằng cách sử dụng TARGET_ANDROID_FILESYSTEM_CONFIG_H trong cấu hình bảng, với tên cơ sở được thi hành là android_filesystem_config.h .

Bao gồm các tập tin ghi đè

Để bao gồm các tệp, hãy đảm bảo rằng PRODUCT_PACKAGES bao gồm fs_config_dirs và/hoặc fs_config_files để nó có thể cài đặt chúng vào /system/etc/fs_config_dirs/system/etc/fs_config_files tương ứng. Hệ thống xây dựng tìm kiếm android_filesystem_config.h tùy chỉnh trong $(TARGET_DEVICE_DIR) , nơi 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í đó.

Cấu hình hệ thống tập tin

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

  1. Tạo tệp $(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ụ ghi đè

Ví dụ này hiển thị một bản vá để ghi đè daemon system/bin/glgps để thêm hỗ trợ khóa chế độ thức trong thư mục device/ vendor / device . Hãy ghi nhớ những điều sau:

  • Mỗi mục cấu trúc là chế độ, uid, gid, khả năng và tên. system/core/include/private/android_filesystem_config.h được tự động đư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 hành động ngăn chặn quyền truy cập vào system/etc/fs_config_dirs khi không được chỉ định, đóng vai trò như một biện pháp bảo vệ DAC bổ sung trong trường hợp thiếu nội dung để ghi đè thư mục. 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ứ điều 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 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)

Di chuyển hệ thống tập tin 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ở về trước, hãy nhớ rằng Android 6.x

  • Loại bỏ một số bao gồm, cấu trúc và định nghĩa nội tuyến.
  • 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 của nhà sản xuất thiết bị phụ thuộc vào system/code/include/private_filesystem_config.h cho cấu trúc tệp hoặc thư mục hoặc fs_config phải thêm các phần phụ thuộc thư viện libcutils .
  • Yêu cầu 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 với nội dung bổ sung trên các mục tiêu hiện có để chuyển sang device/ vendor / device /android_filesystem_config.h .
  • Có quyền áp dụng Kiểm soát truy cập bắt buộc SELinux (MAC) cho các tệp cấu hình trên hệ thống đích, việc triển khai bao gồm các tệp thực thi mục tiêu tùy chỉnh bằng cách sử dụng fs_config() phải đảm bảo quyền truy cập.