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ó mã nhận dạng riêng biệt và duy nhất, được gọi là mã nhận dạng Android (AID). Hiện tại, nhiều tài nguyên như tệp và dịch vụ đang sử dụng các 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 các AID của OEM (do OEM xác định) thay thế.
Các phiên bản Android cũ hơn (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 chức năng của hệ thống tệp và/hoặc AID tuỳ chỉnh của OEM. Tuy nhiên, hệ thống này không trực quan vì không hỗ trợ việc sử dụng tên thân thiện cho các AID OEM, yêu cầu bạn chỉ định số thô cho các trường người dùng và nhóm mà không có cách nào để liên kết 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 các chức năng của hệ thống tệp. Phương thức mới này hỗ trợ những nội dung sau:
- Nhiều vị trí nguồn cho tệp cấu hình (cho phép các cấu hình bản dựng có thể mở rộng).
- Kiểm tra tính hợp lý trong thời gian xây dựng của các giá trị AID OEM.
- Tạo tiêu đề AID OEM tuỳ chỉnh có thể dùng trong các tệp nguồn khi cần.
- Liên kết tên thân thiện với giá trị AID thực tế của OEM. 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 điểm cải tiến khác bao gồm việc xoá mảng android_ids[]
khỏi system/core/libcutils/include/private/android_filesystem_config.h
. Mảng này hiện có trong Bionic dưới dạng một mảng được tạo hoàn toàn riêng tư, với các phương thức truy cập có getpwnam()
và getgrnam()
. (Việc 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 thêm thông tin về công cụ và tệp README, hãy tham khảo build/make/tools/fs_config
.
Thêm mã nhận dạng Android (AID)
Android 8.0 đã xoá mảng android_ids[]
khỏi Dự án nguồn mở Android (AOSP). Thay vào đó, tất 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 android_ids[]
Bionic. Mọi define
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 dễ nhớ: hệ thống
- uid: 1000
- gid: 1000
Để thêm một AID lõi AOSP mới, bạn chỉ cần thêm #define
vào tệp tiêu đề android_filesystem_config.h
. AID được tạo trong quá trình tạo 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 thực rằng AID mới không nằm trong phạm vi APP hoặc OEM; công cụ này cũng tuân thủ các thay đổi đối với những phạm vi đó và sẽ tự động định cấu hình lại khi có thay đổi hoặc phạm vi mới do OEM dành riêng.
Định cấu hình AID
Để bậ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 thêm tệp khi cần.
Theo quy ước, các tệp cấu hình sử dụng tên config.fs
, nhưng trên thực tế, bạn có thể sử dụng bất kỳ tên nào. Các tệp config.fs
có định dạng Python ConfigParser ini và bao gồm một phần caps (để định cấu hình các chức năng của hệ thống tệp) và một phần AIDs (để định cấu hình các AID của OEM).
Định cấu hình phần giới hạn
Phần caps hỗ trợ việc thiết lập các chức 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 dưới dạng gốc trong Android sẽ gây ra lỗi Bộ kiểm tra tính tương thích (CTS), nên các yêu cầu trước đây về việc giữ lại một chức 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 chức năng, sau đó sử dụng setuid
/setgid
cho một AID thích hợp để chạy. Với các tính năng, bạn có thể bỏ qua những yêu cầu này và để hạt nhân thực hiện cho bạn. Khi quyền kiểm soát được chuyển cho main()
, quy trình của bạn đã có những chức năng cần thiết để dịch vụ có thể sử dụng người dùng và nhóm không phải là người dùng root (đây là cách ưu tiên để bắt đầu các dịch vụ có đặc quyền).
Phần phụ đề sử dụng cú pháp sau:
Phần | Giá trị | Định nghĩa |
---|---|---|
[path] |
Đường dẫn trong hệ thống tệp để định cấu hình. Đường dẫn kết thúc bằng / được coi là một thư mục, nếu không thì đó là một tệp.
Bạn không được chỉ định nhiều phần có cùng [path] trong các tệp khác nhau. Trong Python phiên bản <= 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, tệp 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ì giá trị này sẽ có tiền tố là 0, nếu không, chế độ sẽ được sử dụng nguyên trạng. |
user |
AID_<user> | C define cho một AID hợp lệ hoặc tên thân thiện (ví dụ: cả AID_RADIO và radio đều được chấp nhận). Để xác định một AID tuỳ chỉnh, hãy xem phần Định cấu hình AID. |
group |
AID_<group> | Giống như người dùng. |
caps |
cap* | Tên được khai báo trong bionic/libc/kernel/uapi/linux/capability.h mà không có CAP_ ở đầu. Cho phép sử dụng cả chữ hoa và chữ thường. Chữ hoa cũng có thể là chữ hoa thô:
|
Để biết ví dụ về cách sử dụng, hãy xem phần Sử dụng các chức năng của hệ thống tệp.
Định cấu hình phần AID
Phần AID chứa các AID của OEM và sử dụng cú pháp sau:
Phần | Giá trị | Định nghĩa |
---|---|---|
[AID_<name>] |
<name> có thể chứa các ký tự trong bộ chữ cái viết hoa, chữ 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 để đưa mã vào sử dụng chính xác AID_<name> .
Bạn không được chỉ định nhiều phần có cùng AID_<name> (không phân biệt chữ hoa chữ thường và có 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 tên này không xung đột với các nguồn khác. |
|
value |
<number> | Một chuỗi số hợp lệ theo kiểu C (thập lục phân, bát phân, nhị phân và thập phân).
Bạn sẽ gặp lỗi nếu chỉ định nhiều phần có cùng giá trị. Bạn phải chỉ định các lựa chọn về giá trị trong phạm vi 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 dải tương ứng được xác định trong system/core/libcutils/include/private/android_filesystem_config.h .
Các lựa chọn là:
|
Để xem ví dụ về cách sử dụng, hãy xem phần Xác định tên AID của OEM và Sử 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 xác định và sử dụng AID của OEM 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 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 không xung đột với tên AOSP trong tương lai hoặc các phân vùng khác.
Xác định tên AID của OEM
Để xác định một AID OEM, hãy tạo tệp config.fs
và đặt giá trị AID. Ví dụ: trong device/x/y/config.fs
, hãy thiết lập những mục sau:
[AID_VENDOR_FOO] value: 2900
Sau khi tạo tệp, hãy đặt biến TARGET_FS_CONFIG_GEN
và trỏ đến biến đó trong BoardConfig.mk
. Ví dụ: trong device/x/y/BoardConfig.mk
, hãy thiết lập những mục sau:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Giờ đây, hệ thống 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 AID của OEM, trong mã C, hãy thêm oemaids_headers
vào Makefile được liên kết và thêm #include "generated_oem_aid.h"
, sau đó bắt đầu sử dụng các giá trị nhận dạng đã khai báo. Ví dụ: trong my_file.c
, hãy thêm nội dung 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 nội dung sau:
header_libs: ["oemaids_headers"],
Nếu bạn đang dùng tệp Android.mk
, hãy thêm nội dung 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 mọi giao diện hỗ trợ tên AID. Ví dụ:
- Trong lệnh
chown
trongsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- Trong
service
ởsome/init.rc
:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Vì quá trình ánh xạ nội bộ từ tên thân thiện sang uid được thực hiện bởi /vendor/etc/passwd
và /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 có hỗ trợ việc liên kết một tên thân thiện với giá trị AID thực tế của OEM. Bạn có thể sử dụng các đối số chuỗi không phả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
Đối với 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ự, cũng như ở những nơi xử lý các hoạt động tra cứu bằng getpwnam
(chẳng hạn như tập lệnh init
). Trong Android 9, bạn có thể sử dụng các đối tượng getpwnam
và getgrnam
trong Bionic để 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 caps 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 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 những mục sau:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Khi dịch vụ vendor_foo
được thực thi, dịch vụ này sẽ bắt đầu bằng các chức năng CAP_SYS_ADMIN
và CAP_SYS_NICE
mà không có các lệnh gọi setuid
và setgid
. Ngoài ra, chính sách SELinux của dịch vụ vendor_foo
không còn cần đến khả năng setuid
và setgid
nữa và có thể bị xoá.
Định cấu hình các chế độ ghi đè (Android 6.x – 7.x)
Android 6.0 đã di chuyển fs_config
và các định nghĩa cấu trúc liên kết (system/core/include/private/android_filesystem_config.h
) sang system/core/libcutils/fs_config.c
, nơi các định nghĩa này 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
và /system/etc/fs_config_files
. Việc sử dụng các quy tắc phân tích cú pháp và so khớp riêng biệt cho các thư mục và tệp (có thể sử dụng thêm các biểu thức glob) cho phép Android xử lý các thư mục và tệp trong 2 bảng riêng biệt.
Đị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ủ lưu trữ có thể sử dụng cùng các tệp này trong thời gian tạo bản dựng để tạo hình ảnh hệ thống tệp dưới dạng ${OUT}/system/etc/fs_config_dirs
và ${OUT}/system/etc/fs_config_files
.
Mặc dù phương thức ghi đè để mở rộng hệ thống tệp đã được thay thế bằng hệ thống cấu hình theo mô-đun được giới thiệu trong Android 8.0, nhưng bạn vẫn có thể sử dụng phương thức cũ nếu muốn. Các phần sau đây trình bày chi tiết cách tạo và đưa các tệp ghi đè vào cũng như cách đị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
và /system/etc/fs_config_files
bằng công cụ fs_config_generate
trong build/tools/fs_config
. Công cụ này sử dụng một hàm thư viện libcutils
(fs_config_generate()
) để quản lý các yêu cầu DAC vào một vùng đệm và xác định các quy tắc cho một tệp bao gồm để thể chế hoá các quy tắc DAC.
Để sử dụng, hãy tạo một tệp include trong device/vendor/device/android_filesystem_config.h
đóng vai trò là tệp 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
với các chế độ khởi tạo cấu trúc sau cho các biểu tượng 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 tệp, hãy dùng
android_device_files[]
.
Khi không sử dụng android_device_dirs[]
và android_device_files[]
, bạn có thể xác định NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
và NO_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ở bắt buộc là android_filesystem_config.h
.
Bao gồm các tệp ghi đè
Để thê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
để có thể cài đặt các tệp này vào /system/etc/fs_config_dirs
và /system/etc/fs_config_files
tương ứng. Hệ thống bản dựng sẽ tìm kiếm android_filesystem_config.h
tuỳ chỉnh trong $(TARGET_DEVICE_DIR)
, nơi có BoardConfig.mk
.
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:
- Tạo tệp
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Thêm
fs_config_dirs
và/hoặcfs_config_files
vàoPRODUCT_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 đè trình nền system/bin/glgps
nhằm thêm tính năng hỗ trợ khoá đánh thức trong thư mục device/vendor/device
. Lưu ý những điều sau:
- Mỗi mục cấu trúc là chế độ, uid, gid, các chức năng và tên.
system/core/include/private/android_filesystem_config.h
sẽ tự động được đưa vào để cung cấp các #define trong tệp kê khai (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - Mục
android_device_files[]
bao gồm một hành động ngăn chặn quyền truy cập vàosystem/etc/fs_config_dirs
khi không được chỉ định. Hành động này đóng vai trò là một biện pháp bảo vệ DAC bổ sung trong trường hợp thiếu nội dung cho các chế độ ghi đè thư mục. Tuy nhiên, đây là một biện pháp bảo vệ yếu; nếu có quyền kiểm soát/system
, thì người dùng 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 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 lưu ý rằng Android 6.x
- Xoá một số nội dung 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 tư của nhà sản xuất thiết bị phụ thuộc vàosystem/code/include/private_filesystem_config.h
cho cấu trúc tệp hoặc thư mục hoặcfs_config
phải thêm các phần phụ thuộc của thư việnlibcutils
. - Yêu cầu các bản sao nhánh riêng tư của nhà sản xuất thiết bị về
system/core/include/private/android_filesystem_config.h
có nội dung bổ sung trên các mục tiêu hiện có để chuyển sangdevice/vendor/device/android_filesystem_config.h
. - Có quyền áp dụng các chế độ kiểm soát bắt buộc đối với quyền truy cập (MAC) SELinux cho các tệp cấu hình trên hệ thống đích, những cách triển khai bao gồm các tệp thực thi đích tuỳ chỉnh bằng
fs_config()
phải đảm bảo quyền truy cập.