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 duy nhất, riêng biệt, 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ụ 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).
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 OEM tuỳ chỉnh. Tuy nhiên, hệ thống này khó sử dụng vì nó không hỗ trợ dùng tên hay cho các AID của OEM, yêu cầu bạn phải chỉ định số thô cho các trường nhóm và người dùng mà không có cách để 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 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ấu hình bản dựng có thể mở rộng).
- Kiểm tra tính hợp lệ tại thời điểm tạo bản dựng của các giá trị AID của OEM.
- Tạo tiêu đề AID OEM tuỳ chỉnh có thể dùng trong các tệp nguồn nếu cần.
- Liên kết tên thân thiện với giá trị AID OEM thực tế. Hỗ trợ các đối số chuỗi không phải dạng 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á 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ộ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()
. (Điều này có tác dụng phụ của việc tạo các tệp nhị phân ổn định khi các AID chính được sửa đổi.) Để biết thêm thông tin chi tiết 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 đượ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. Công cụ sẽ chọn mọi define
khớp với AID_*
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 bản 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 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 theo các thay đổi đối với các 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 đặt trước.
Định cấu hình AID
Để bật cơ chế AIDs 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 các tệp nếu cần.
Theo quy ướ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
nằm ở định dạng ini của Python và bao gồm một phần có phần giới hạn (để định cấu hình các chức năng của hệ thống tệp) và một 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 mũ hỗ trợ việc đặt các tính 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 (chính 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 thư mục 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 để 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 chức năng, sau đó sử dụng setuid
/setgid
cho một AID thích hợp để chạy. Với các chữ cái viết hoa, bạn có thể bỏ qua các yêu cầu này và để nhân thực hiện việc này cho bạn. Khi quyền kiểm soát được chuyển đến main()
, quy trình của bạn đã có các chức năng cần thiết để dịch vụ của bạn có thể sử dụng người dùng và nhóm không phải là người dùng gốc (đây là cách ưu tiên để khởi động các dịch vụ đặc quyền).
Phần viết hoa 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à thư mục, nếu không đó là một tệp.
Sẽ xảy ra lỗi nếu bạn chỉ định nhiều phần có cùng một [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, tệp này được đặt thành 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, còn chế độ khác sẽ được sử dụng như nguyên trạng. |
user |
AID_<user> | define C cho 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 phần AID. |
group |
AID_<nhóm> | 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. Dấu mũ cũng có thể là dữ liệu thô:
|
Để biết ví dụ về cách sử dụng, hãy xem phần Sử dụng các tính năng của hệ thống tệp.
Đị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 viết thường được sử 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> .
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á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 phân vùng đó không xung đột với các nguồn khác. |
|
value |
<number> | 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).
Lỗi chỉ định nhiều mục có cùng một tuỳ chọn giá trị. Bạn phải chỉ định các lựa chọn giá trị trong dải ô tương ứng với phân vùng 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 các phân vùng đó được xác định trong system/core/libcutils/include/private/android_filesystem_config.h .
Có các lựa chọn sau:
|
Để biết 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 OEM ([AID_name]) phải bắt đầu bằng tên phân vùng, chẳng hạn như "vendor_" để đảm bảo các tên này 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 AID của OEM
Để xác định AID của 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ư 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 OEM, trong mã C, hãy thêm oemaids_headers
vào Makefile liên kết và thêm #include "generated_oem_aid.h"
, sau đó bắt đầu sử dụng 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 sử 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 một lệnh
chown
ởsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- Trong
service
trongsome/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 do /vendor/etc/passwd
và /vendor/etc/group
thực hiện, nên bạn phải gắn phân vùng của nhà cung cấp.
Liên kết tên dễ nhớ
Android 9 hỗ trợ việc liên kết tên thân thiện với giá trị AID OEM 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à "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 lượt 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 bạn bè 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 tính 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 đặt như sau:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Khi thực thi dịch vụ vendor_foo
, dịch vụ đó sẽ bắt đầu bằng các tính năng CAP_SYS_ADMIN
và CAP_SYS_NICE
mà không 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 tính năng setuid
và setgid
nữa và bạn có thể xoá tính năng này.
Định cấu hình 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 so khớp và phân tích cú pháp riêng biệt cho thư mục và tệp (có thể sử dụng biểu thức glob bổ sung) đã cho phép Android xử lý 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 thư mục và tệp trong thời gian chạy, mà máy chủ lưu trữ cũng có thể sử dụng các tệp đó 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
và ${OUT}/system/etc/fs_config_files
.
Mặc dù hệ thống cấu hình mô-đun được giới thiệu trong Android 8.0 đã thay thế phương thức ghi đè để mở rộng hệ thống tệp, 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 vào các tệp ghi đè cũng như đị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ă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 hàm thư viện libcutils
(fs_config_generate()
) để quản lý các yêu cầu DAC vào vùng đệm và xác định các quy tắc cho tệp bao gồm để thiết lập 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 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 hoạt động 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 sử dụng
android_device_dirs[]
. - Đối với tệp, hãy sử 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 đè
Để đưa các tệp vào, 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 đó vào /system/etc/fs_config_dirs
và /system/etc/fs_config_files
tương ứng. Hệ thống xây 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á chế độ thức trong thư mục device/vendor/device
. Hãy lưu ý những điều sau:
- Mỗi mục nhập cấu trúc là chế độ, uid, gid, chức năng và tên.
system/core/include/private/android_filesystem_config.h
được tự động đưa vào để cung cấp các #defines tệp kê khai (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - Mục
android_device_files[]
bao gồm một thao tác để ngăn chặn quyền truy cập vàosystem/etc/fs_config_dirs
khi không được chỉ định, đóng vai trò là biện pháp bảo vệ DAC bổ sung do thiếu nội dung để ghi đè thư mục. Tuy nhiên, đây là biện pháp bảo vệ yếu; nếu có người kiểm soát/system
, thì 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 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ố 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à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 thư việnlibcutils
. - Yêu cầu nhà sản xuất thiết bị cung cấp bản sao nhánh riêng tư của
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
. - Giữ quyền áp dụng các biện pháp Kiểm soát quyền truy cập bắt buộc (MAC) của SELinux cho các tệp cấu hình trên hệ thống mục tiêu, các phương thức triển khai bao gồm các tệp thực thi mục tiêu tuỳ chỉnh bằng
fs_config()
phải đảm bảo quyền truy cập.