Bài viết này mô tả cách Android xử lý các vấn đề về khả năng tương thích với chính sách với nền tảng OTA, trong đó chế độ cài đặt SELinux của nền tảng mới có thể khác với nhà cung cấp cũ Cài đặt SELinux.
Thiết kế chính sách SELinux dựa trên Treble xem xét sự khác biệt nhị phân
giữa chính sách platform và vendor; lược đồ trở thành
phức tạp hơn nếu phân vùng của nhà cung cấp tạo ra các phần phụ thuộc, chẳng hạn như
platform
< vendor
< oem
.
Trong Android 8.0 trở lên, chính sách chung SELinux được chia thành chính sách riêng tư và thành phần công khai. Các thành phần công khai bao gồm chính sách và các thành phần liên kết cơ sở hạ tầng được đảm bảo sẵn có cho một phiên bản nền tảng. Người viết chính sách của nhà cung cấp sẽ đọc chính sách này để giúp nhà cung cấp xây dựng tệp chính sách của nhà cung cấp. Khi kết hợp với chính sách do nền tảng cung cấp, dẫn đến một chính sách đầy đủ chức năng cho một thiết bị.
- Để ghi phiên bản, chính sách công khai của nền tảng đã xuất sẽ được viết là thuộc tính.
- Để dễ viết chính sách, các loại đã xuất sẽ được chuyển đổi thành thuộc tính có phiên bản trong quá trình xây dựng chính sách. Công khai loại cũng có thể được sử dụng trực tiếp trong quyết định gắn nhãn do nhà cung cấp cung cấp tệp ngữ cảnh.
Android duy trì mối liên kết giữa các loại bê tông đã xuất trong nền tảng và các thuộc tính có phiên bản tương ứng cho từng nền tảng phiên bản. Điều này đảm bảo rằng khi các đối tượng được gắn nhãn bằng một loại, đối tượng không làm hỏng hành vi được đảm bảo bởi chính sách công khai của nền tảng trong . Ánh xạ này được duy trì bằng cách luôn cập nhật tệp ánh xạ cho từng phiên bản nền tảng. Tính năng này lưu giữ thông tin thuộc tính về tư cách thành viên cho mỗi phiên bản loại được xuất trong chính sách công khai.
Quyền sở hữu và gắn nhãn đối tượng
Khi tuỳ chỉnh chính sách trong Android 8.0 trở lên, bạn phải xác định rõ quyền sở hữu
cho từng đối tượng để tách biệt chính sách của nền tảng và nhà cung cấp. Ví dụ: nếu
nhãn nhà cung cấp /dev/foo
và nền tảng, sau đó gắn nhãn
/dev/foo
trong OTA tiếp theo sẽ có hành vi không xác định. Cho
SELinux, điều này biểu thị dưới dạng một xung đột tạo nhãn. Nút thiết bị chỉ có thể có một
một nhãn phân giải thành bất kỳ nhãn nào được áp dụng gần đây nhất. Kết quả là:
- Những quy trình cần quyền truy cập vào nhãn được áp dụng không thành công sẽ mất quyền truy cập vào tài nguyên.
- Các quá trình có được quyền truy cập vào tệp có thể bị lỗi do nhầm lẫn nút thiết bị đã được tạo.
Các thuộc tính hệ thống cũng có khả năng dẫn đến xung đột khi đặt tên hành vi không xác định trên hệ thống (cũng như đối với việc gắn nhãn SELinux). Va chạm giữa nhãn nền tảng và nhãn nhà cung cấp có thể xảy ra đối với bất kỳ đối tượng nào có SELinux nhãn, bao gồm các thuộc tính, dịch vụ, quy trình, tệp và ổ cắm. Cần tránh các vấn đề này, hãy xác định rõ quyền sở hữu của các đối tượng này.
Ngoài xung đột về nhãn, tên loại/thuộc tính SELinux cũng có thể xung đột. Việc xung đột loại/tên thuộc tính sẽ luôn dẫn đến lỗi trình biên dịch chính sách.
Tốc độ tên thuộc tính/loại
SELinux không cho phép khai báo cùng một loại/thuộc tính. Chính sách
có khai báo trùng lặp sẽ không biên dịch được. Để tránh loại và
xung đột tên thuộc tính, tất cả khai báo nhà cung cấp đều phải được đặt tên
bắt đầu bằng vendor_
.
type foo, domain; → type vendor_foo, domain;
Thuộc tính hệ thống và quyền sở hữu gắn nhãn quy trình
Cách tốt nhất để tránh xung đột gắn nhãn là sử dụng không gian tên thuộc tính. Người nhận dễ dàng xác định các thuộc tính của nền tảng và tránh xung đột tên khi đổi tên hoặc thêm các thuộc tính nền tảng đã xuất, hãy đảm bảo tất cả các thuộc tính của nhà cung cấp đều có tiền tố riêng:
Loại khách sạn | Tiền tố được chấp nhận |
---|---|
thuộc tính kiểm soát | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor.
|
có thể đọc | vendor. |
chỉ có thể đọc | ro.vendor. ro.boot. ro.hardware.
|
liên tục | persist.vendor. |
Các nhà cung cấp có thể tiếp tục sử dụng ro.boot.*
(bắt nguồn từ nhân
cmdline) và ro.hardware.*
(một thuộc tính rõ ràng liên quan đến phần cứng).
Tất cả dịch vụ của nhà cung cấp trong các tệp rc init phải có vendor.
cho các dịch vụ trong tệp rc init của phân vùng không phải hệ thống. Các quy tắc tương tự là
đã áp dụng cho các nhãn SELinux cho thuộc tính của nhà cung cấp (vendor_
cho thuộc tính của nhà cung cấp).
Quyền sở hữu tệp
Việc ngăn chặn xung đột cho các tệp là một thách thức vì nền tảng và nhà cung cấp cả hai chính sách này thường cung cấp nhãn cho tất cả hệ thống tệp. Không giống như cách đặt tên kiểu, không gian tên tệp không thực tế vì nhiều tệp được tạo bằng nhân hệ điều hành. Để ngăn chặn những xung đột này, hãy làm theo hướng dẫn đặt tên cho hệ thống tệp trong phần này. Đối với Android 8.0, đây là các đề xuất không cần đến thực thi chính sách. Trong tương lai, các đề xuất này sẽ được thực thi bằng Bộ thử nghiệm dành cho nhà cung cấp (VTS).
Hệ thống (/system)
Chỉ hình ảnh hệ thống phải cung cấp nhãn cho các thành phần /system
thông qua file_contexts
, service_contexts
, v.v. Nếu nhãn
cho các thành phần /system
được thêm vào chính sách /vendor
, một
có thể không cập nhật được qua mạng không dây (OTA) chỉ trong khung.
Nhà cung cấp (/nhà cung cấp)
Chính sách AOSP SELinux đã gắn nhãn các phần của phân vùng vendor
nền tảng tương tác, cho phép viết các quy tắc SELinux cho nền tảng
các quy trình để có thể trò chuyện và/hoặc truy cập các phần của vendor
phân vùng. Ví dụ:
/vendor đường dẫn |
Nhãn do nền tảng cung cấp | Nền tảng xử lý tuỳ thuộc vào nhãn |
---|---|---|
/vendor(/.*)?
|
vendor_file
|
Tất cả ứng dụng HAL trong khung, ueventd , v.v.
|
/vendor/framework(/.*)?
|
vendor_framework_file
|
dex2oat , appdomain , v.v.
|
/vendor/app(/.*)?
|
vendor_app_file
|
dex2oat , installd , idmap , v.v.
|
/vendor/overlay(/.*)
|
vendor_overlay_file
|
system_server , zygote , idmap , v.v.
|
Vì vậy, nhà quảng cáo phải tuân thủ các quy tắc cụ thể (thực thi thông qua
neverallows
) khi gắn nhãn cho các tệp khác trong vendor
phân vùng:
vendor_file
phải là nhãn mặc định cho tất cả các tệp trong Phân vùngvendor
. Chính sách nền tảng yêu cầu quyền này để truy cập triển khai HAL truyền qua.- Đã thêm tất cả
exec_types
mới vào phân vùngvendor
phải có thuộc tínhvendor_file_type
thông qua SEPolicy của nhà cung cấp. Chiến dịch này sẽ được thực thi thông qua chiến dịch không bao giờ cho phép. - Để tránh xung đột với các bản cập nhật nền tảng/khung trong tương lai, hãy tránh gắn nhãn
các tệp khác
exec_types
trong phân vùngvendor
. - Tất cả phần phụ thuộc thư viện cho HAL quy trình tương tự do AOSP xác định đều phải
được gắn nhãn là
same_process_hal_file.
Procf (/proc)
Chỉ có thể gắn nhãn các tệp trong /proc
bằng genfscon
. Trong Android 7.0, cả hai
nền tảng
và nhà cung cấp
chính sách đã sử dụng genfscon
để gắn nhãn tệp trong procfs
.
Đề xuất: Chỉ các nhãn chính sách của nền tảng /proc
.
Nếu các quy trình vendor
cần quyền truy cập vào các tệp trong /proc
hiện được gắn nhãn với nhãn mặc định (proc
), chính sách của nhà cung cấp
không nên gắn nhãn chúng một cách rõ ràng mà thay vào đó nên sử dụng nhãn chung
Nhập proc
để thêm quy tắc cho miền của nhà cung cấp. Điều này cho phép nền tảng
các bản cập nhật để phù hợp với giao diện nhân hệ điều hành trong tương lai được hiển thị thông qua
procfs
và gắn nhãn chúng một cách rõ ràng nếu cần.
Debugfs (/sys/kernel/debug)
Bạn có thể gắn nhãn Debugfs
trong cả file_contexts
và
genfscon
. Trong Android 7.0 đến Android 10, cả nhãn nền tảng lẫn nhà cung cấp
debugfs
.
Trong Android 11, debugfs
không thể
được truy cập hoặc được gắn trên các thiết bị phát hành chính thức. Nhà sản xuất thiết bị nên
xoá debugfs
.
Dấu vết (/sys/kernel/debug/tracing)
Bạn có thể gắn nhãn Tracefs
trong cả file_contexts
và
genfscon
. Trong Android 7.0, chỉ có các nhãn nền tảng
tracefs
.
Đề xuất: Chỉ nền tảng mới có thể gắn nhãn tracefs
.
Sysfs (/hệ thống)
Các tệp trong /sys
có thể được gắn nhãn bằng cả file_contexts
và genfscon
. Trong Android 7.0, cả nền tảng và nhà cung cấp đều sử dụng
file_contexts
và genfscon
để gắn nhãn cho tệp trong
sysfs
.
Đề xuất: Nền tảng có thể gắn nhãn sysfs
các nút không dành riêng cho thiết bị. Nếu không, chỉ nhà cung cấp mới có thể gắn nhãn cho tệp.
tmpfs (/dev)
Các tệp trong /dev
có thể được gắn nhãn trong file_contexts
. Trong
Android 7.0, tệp nhãn của cả nền tảng và nhà cung cấp đều ở đây.
Đề xuất: Nhà cung cấp chỉ có thể gắn nhãn các tệp trong
/dev/vendor
(ví dụ: /dev/vendor/foo
,
/dev/vendor/socket/bar
).
Rootfs (/)
Các tệp trong /
có thể được gắn nhãn trong file_contexts
. Trong Android
7.0, cả tệp nhãn của nền tảng và nhà cung cấp đều ở đây.
Đề xuất: Chỉ hệ thống mới có thể gắn nhãn cho các tệp trong /
.
Dữ liệu (/data)
Dữ liệu được gắn nhãn bằng cách kết hợp file_contexts
và
seapp_contexts
Đề xuất: Không cho phép gắn nhãn nhà cung cấp bên ngoài
/data/vendor
. Chỉ nền tảng mới có thể gắn nhãn các phần khác của
/data
.
Thuộc tính tương thích
Chính sách SELinux là sự tương tác giữa loại nguồn và loại đích cho các các lớp đối tượng và quyền. Mọi đối tượng (quy trình, tệp, v.v.) đều bị ảnh hưởng theo chính sách SELinux có thể chỉ có một loại, nhưng loại đó có thể có nhiều .
Chính sách được viết chủ yếu theo các loại hiện có:
allow source_type target_type:target_class permission(s);
Điều này hiệu quả vì chính sách được viết dựa trên kiến thức thuộc mọi loại nội dung. Tuy nhiên, chính sách của nhà cung cấp và chính sách của nền tảng có sử dụng các loại cụ thể hay không và nhãn của chỉ thay đổi đối tượng cụ thể ở một trong các chính sách đó, còn chính sách còn lại có thể chứa đã được cấp hoặc mất quyền truy cập trước đó. Ví dụ:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Có thể được thay đổi thành:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Mặc dù chính sách dành cho nhà cung cấp sẽ không thay đổi, v_domain
sẽ mất quyền truy cập do thiếu chính sách cho sysfs_A
mới
loại.
Bằng cách xác định chính sách theo thuộc tính, chúng ta có thể cung cấp cho đối tượng cơ bản một có thuộc tính tương ứng với chính sách của cả nền tảng và mã nhà cung cấp. Điều này có thể thực hiện được cho tất cả các loại để tạo một cách hiệu quả attribute-policy trong đó các loại cụ thể không bao giờ được sử dụng. Trên thực tế, điều này chỉ bắt buộc đối với các phần của chính sách trùng lặp giữa các nền tảng và nhà cung cấp được định nghĩa và cung cấp là chính sách công khai của nền tảng được xây dựng như một phần trong chính sách của nhà cung cấp.
Việc xác định chính sách công làm thuộc tính có tạo phiên bản sẽ đáp ứng hai chính sách mục tiêu về khả năng tương thích:
- Đảm bảo mã của nhà cung cấp tiếp tục hoạt động sau khi cập nhật nền tảng. Đạt được bằng cách thêm thuộc tính vào loại cụ thể cho các đối tượng tương ứng với những dịch vụ mà mã nhà cung cấp dựa vào, giúp duy trì quyền truy cập.
- Khả năng ngừng áp dụng chính sách. Đạt được bằng việc mô tả các tập hợp chính sách thành các thuộc tính có thể được xoá ngay khi phiên bản mà chúng tương ứng không còn được hỗ trợ. Nhà phát triển có thể tiếp tục sử dụng nền tảng khi biết rằng chính sách cũ vẫn còn chính sách của nhà cung cấp và sẽ tự động bị xoá khi/nếu nâng cấp.
Khả năng viết chính sách
Để đáp ứng mục tiêu không đòi hỏi kiến thức về những thay đổi cụ thể của phiên bản cho
Trong quá trình phát triển chính sách, Android 8.0 sẽ bao gồm việc ánh xạ giữa
loại chính sách và thuộc tính của chúng. Loại foo
đã được liên kết
vào thuộc tính foo_vN
, trong đó N
là
phiên bản được nhắm mục tiêu. vN
tương ứng với
Biến thể bản dựng PLATFORM_SEPOLICY_VERSION
có dạng
MM.NN
, trong đó MM
tương ứng với số SDK của nền tảng
và NN
là một phiên bản chính sách sepolicy của nền tảng.
Các thuộc tính trong chính sách công khai không được tạo phiên bản mà tồn tại dưới dạng API trên nền tảng và chính sách nhà cung cấp nào có thể được tạo để duy trì giao diện giữa các phân vùng ổn định. Cả người viết chính sách cho nền tảng và nhà cung cấp đều có thể tiếp tục viết chính sách được đề cập hiện nay.
Chính sách công khai về nền tảng được xuất dưới dạng allow source_foo target_bar:class
perm;
được đưa vào chính sách của nhà cung cấp. Trong
biên dịch (bao gồm
phiên bản tương ứng), chính sách sẽ được chuyển đổi thành chính sách sẽ chuyển đến
phần nhà cung cấp của thiết bị (xuất hiện trong thẻ Trung gian thông thường đã được chuyển đổi
Ngôn ngữ (CIL)):
(allow source_foo_vN target_bar_vN (class (perm)))
Vì chính sách nhà cung cấp không bao giờ đi trước nền tảng, nên bạn không cần quan tâm đến các phiên bản trước. Tuy nhiên, chính sách nền tảng sẽ cần biết thông tin về nhà cung cấp chính sách là đưa thuộc tính vào các loại của chính sách và đặt chính sách tương ứng với thuộc tính có phiên bản.
Điểm khác biệt về chính sách
Tự động tạo thuộc tính bằng cách thêm _vN
vào cuối
của mỗi loại không làm gì cả nếu không liên kết thuộc tính với các loại trên phiên bản
khác biệt. Android duy trì mối liên kết giữa các phiên bản cho các thuộc tính và một
ánh xạ các loại đến các thuộc tính đó. Điều này được thực hiện trong ánh xạ nêu trên
tệp có các câu lệnh, chẳng hạn như (CIL):
(typeattributeset foo_vN (foo))
Nâng cấp nền tảng
Phần sau đây trình bày chi tiết các trường hợp nâng cấp nền tảng.
Cùng loại
Trường hợp này xảy ra khi một đối tượng không thay đổi nhãn trong các phiên bản chính sách.
Điều này tương tự với loại nguồn và loại mục tiêu và có thể thấy được với
/dev/binder
, được gắn nhãn binder_device
trên tất cả
bản phát hành. Chính sách này được thể hiện trong chính sách đã chuyển đổi như sau:
binder_device_v1 … binder_device_vN
Khi nâng cấp từ v1
→ v2
, chính sách nền tảng phải
chứa:
type binder_device; -> (type binder_device) (in CIL)
Trong tệp ánh xạ v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
Trong tệp ánh xạ v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
Trong chính sách dành cho nhà cung cấp (CIL) v1:
(typeattribute binder_device_v1) (allow binder_device_v1 …)
Trong chính sách dành cho nhà cung cấp (CIL) v2:
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Loại mới
Trường hợp này xảy ra khi nền tảng đã thêm một loại mới (có thể xảy ra) khi thêm tính năng mới hoặc trong quá trình củng cố chính sách.
- Tính năng mới. Khi loại này gắn nhãn một đối tượng không tồn tại trước đây (chẳng hạn như quy trình dịch vụ mới), mã nhà cung cấp không tương tác trực tiếp với chính sách đó trước đó nên không tồn tại chính sách tương ứng nào. Gói thuê bao mới tương ứng với loại không có thuộc tính nào trong nên sẽ không cần mục nhập trong nhắm mục tiêu tệp ánh xạ .
- Củng cố chính sách. Khi loại biểu thị chính sách
tăng cường, thuộc tính loại mới phải liên kết trở lại với một chuỗi thuộc tính
tương ứng với ví dụ trước (tương tự như trong ví dụ trước
/sys/A
từsysfs
đếnsysfs_A
). Nhà cung cấp mã dựa vào quy tắc cho phép truy cập vàosysfs
và cần để đưa quy tắc đó vào dưới dạng thuộc tính của loại mới.
Khi nâng cấp từ v1
→ v2
, chính sách nền tảng phải
chứa:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
Trong tệp ánh xạ v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
Trong tệp ánh xạ v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
Trong chính sách dành cho nhà cung cấp (CIL) v1:
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Trong chính sách dành cho nhà cung cấp (CIL) v2:
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Các loại đã xoá
Trường hợp (hiếm gặp) này xảy ra khi một loại bị xoá, có thể xảy ra khi đối tượng cơ bản:
- Vẫn còn nhưng nhận được một nhãn khác.
- Nền tảng đã xoá.
Trong quá trình nới lỏng chính sách, một loại dữ liệu sẽ bị xoá và đối tượng được gắn nhãn thuộc loại đó được gán một nhãn khác, đã có sẵn. Điều này thể hiện sự hợp nhất của ánh xạ thuộc tính: Mã nhà cung cấp vẫn phải truy cập được vào dữ liệu cơ bản đối tượng theo thuộc tính nó từng sở hữu nhưng phần còn lại của hệ thống giờ đây phải có thể truy cập vào tệp đó nhờ thuộc tính mới.
Nếu thuộc tính mà thuộc tính đó được chuyển sang là thuộc tính mới, thì việc gắn nhãn lại là giống như trong trường hợp loại mới, ngoại trừ khi nhãn hiện có được sử dụng, thêm thuộc tính cũ vào loại mới sẽ khiến các đối tượng khác cũng bị gắn nhãn với loại này để có thể truy cập mới được. Về cơ bản, đây là những gì được thực hiện bởi nền tảng và được coi là sự đánh đổi có thể chấp nhận được để duy trì khả năng tương thích.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Phiên bản Ví dụ 1: Các loại thu gọn (xoá sysfs_A)
Khi nâng cấp từ v1
→ v2
, chính sách nền tảng phải
chứa:
type sysfs; (type sysfs) (in CIL)
Trong tệp ánh xạ v1 (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
Trong tệp ánh xạ v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
Trong chính sách dành cho nhà cung cấp (CIL) v1:
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
Trong chính sách dành cho nhà cung cấp (CIL) v2:
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Ví dụ 2: Xoá hoàn toàn (loại foo)
Khi nâng cấp từ v1
→ v2
, chính sách nền tảng phải
chứa:
# nothing - we got rid of the type
Trong tệp ánh xạ v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
Trong tệp ánh xạ v2 (CIL):
# nothing - get rid of it
Trong chính sách dành cho nhà cung cấp (CIL) v1:
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
Trong chính sách dành cho nhà cung cấp (CIL) v2:
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Lớp học/quyền mới
Trường hợp này xảy ra khi quá trình nâng cấp nền tảng dẫn đến các thành phần chính sách mới
không có trong các phiên bản trước. Ví dụ: khi Android thêm thuộc tính
Trình quản lý đối tượng servicemanager
đã tạo các thao tác thêm, tìm và danh sách
các quyền, trình nền của nhà cung cấp muốn đăng ký với
servicemanager
cần quyền nhưng không
sẵn có. Trong Android 8.0, chỉ chính sách nền tảng mới có thể thêm các lớp và
quyền truy cập.
Để cho phép tất cả các miền có thể đã được tạo hoặc mở rộng theo chính sách của nhà cung cấp để sử dụng lớp mới mà không gây trở ngại, chính sách nền tảng cần bao gồm một quy tắc tương tự như:
allow {domain -coredomain} *:new_class perm;
Thậm chí, việc này có thể yêu cầu chính sách cho phép truy cập vào tất cả giao diện (chính sách công khai) để đảm bảo hình ảnh của nhà cung cấp có quyền truy cập. Nếu kết quả là không được chấp nhận chính sách bảo mật (có thể có khi thay đổi về trình quản lý dịch vụ), một nhà cung cấp có thể buộc phải nâng cấp.
Đã xoá lớp/quyền
Trường hợp này xảy ra khi trình quản lý đối tượng bị xoá (chẳng hạn như
ZygoteConnection
trình quản lý đối tượng) và không được gây ra sự cố. Chiến lược phát hành đĩa đơn
lớp trình quản lý đối tượng và quyền có thể vẫn được xác định trong chính sách cho đến khi
phiên bản của nhà cung cấp không còn sử dụng định dạng đó nữa. Bạn có thể thực hiện việc này bằng cách thêm các định nghĩa
vào tệp ánh xạ tương ứng.
Tuỳ chỉnh nhà cung cấp cho loại mới/được gắn nhãn lại
Các loại nhà cung cấp mới là trọng tâm trong quá trình phát triển chính sách dành cho nhà cung cấp khi cần thiết để mô tả các quy trình mới, tệp nhị phân, thiết bị, hệ thống con và dữ liệu được lưu trữ. Như do đó, bạn bắt buộc phải cho phép tạo các loại do nhà cung cấp xác định.
Vì chính sách nhà cung cấp luôn là chính sách cũ nhất trên thiết bị, nên không cần
tự động chuyển đổi tất cả các loại nhà cung cấp thành thuộc tính trong chính sách. Nền tảng
không dựa vào bất kỳ nội dung nào được gắn nhãn trong chính sách của nhà cung cấp vì nền tảng này không
kiến thức về sản phẩm đó; Tuy nhiên, nền tảng sẽ cung cấp các thuộc tính và thông tin
loại dữ liệu tương tác với các đối tượng được gắn nhãn là các loại này (chẳng hạn như
domain
, sysfs_type
, v.v.). Để nền tảng
tiếp tục tương tác chính xác với các đối tượng, thuộc tính và loại này
phải được áp dụng thích hợp và có thể cần thêm các quy tắc cụ thể vào
các miền có thể tuỳ chỉnh (chẳng hạn như init
).
Các thay đổi về thuộc tính cho Android 9
Thiết bị nâng cấp lên Android 9 có thể sử dụng các thuộc tính sau, nhưng thiết bị chạy bằng Android 9 thì không được.
Thuộc tính của người vi phạm
Android 9 có các thuộc tính liên quan đến miền sau đây:
data_between_core_and_vendor_violators
. Thuộc tính cho tất cả những miền vi phạm yêu cầu không chia sẻ tệp bằng đường dẫn giữavendor
vàcoredomains
. Nền tảng và quy trình của nhà cung cấp không nên sử dụng các tệp trên ổ đĩa để giao tiếp (ABI không ổn định). Nội dung đề xuất:- Mã nhà cung cấp phải sử dụng
/data/vendor
. - Hệ thống không được sử dụng
/data/vendor
.
- Mã nhà cung cấp phải sử dụng
system_executes_vendor_violators
. Thuộc tính cho tất cả các miền hệ thống (ngoại trừinit
vàshell domains
) vi phạm yêu cầu không thực thi tệp nhị phân của nhà cung cấp. Thực hiện Tệp nhị phân của nhà cung cấp có API không ổn định. Nền tảng không được thực thi tệp nhị phân của nhà cung cấp trực tiếp. Nội dung đề xuất:- Các phần phụ thuộc như vậy của nền tảng trên tệp nhị phân của nhà cung cấp phải nằm sau HAL HIDL.
HOẶC
coredomains
cần quyền truy cập vào tệp nhị phân của nhà cung cấp phải được chuyển sang phân vùng nhà cung cấp, do đó không còn làcoredomain
.
- Các phần phụ thuộc như vậy của nền tảng trên tệp nhị phân của nhà cung cấp phải nằm sau HAL HIDL.
Thuộc tính không đáng tin cậy
Các ứng dụng không đáng tin cậy lưu trữ mã tuỳ ý không được có quyền truy cập vào HwBinder ngoại trừ những dịch vụ được coi là đủ an toàn để truy cập từ các ứng dụng đó (xem các dịch vụ an toàn bên dưới). Hai lý do chính dẫn đến điều này là:
- Máy chủ HwBinder không thực hiện xác thực ứng dụng vì HIDL hiện không hiển thị thông tin UID của phương thức gọi. Ngay cả khi HIDL tiết lộ dữ liệu như vậy, nhiều Dịch vụ HwBinder hoạt động ở cấp thấp hơn cấp của ứng dụng (chẳng hạn như HAL) hoặc không được dựa vào danh tính ứng dụng để uỷ quyền. Do đó, để đảm bảo an toàn, chế độ mặc định giả định là mọi dịch vụ HwBinder đối xử với mọi ứng dụng khách như nhau được phép thực hiện các thao tác do dịch vụ cung cấp.
- Máy chủ HAL (một tập hợp con của các dịch vụ HwBinder) chứa mã có
tỷ lệ gặp sự cố bảo mật so với
system/core
thành phần và có quyền truy cập vào các lớp thấp hơn của ngăn xếp (xuống đến phần cứng), do đó làm tăng cơ hội bỏ qua mô hình bảo mật của Android.
Dịch vụ an toàn
Các dịch vụ an toàn bao gồm:
same_process_hwservice
. Các dịch vụ này (theo định nghĩa) chạy trong quy trình của máy khách và do đó có quyền truy cập giống như miền máy khách trong mà quy trình chạy.coredomain_hwservice
. Các dịch vụ này không gây rủi ro được liên kết với lý do số 2.hal_configstore_ISurfaceFlingerConfigs
. Dịch vụ này được thiết kế đặc biệt để bất kỳ miền nào sử dụng.hal_graphics_allocator_hwservice
. Các thao tác này cũng do dịch vụsurfaceflinger
Binder cung cấp, ứng dụng được phép để truy cập.hal_omx_hwservice
. Đây là phiên bản HwBinder củamediacodec
Dịch vụ Binder mà ứng dụng được phép truy cập.hal_codec2_hwservice
. Đây là phiên bản mới hơn củahal_omx_hwservice
Thuộc tính có thể sử dụng
Tất cả hwservices
được coi là không an toàn đều có thuộc tính
untrusted_app_visible_hwservice
Các máy chủ HAL tương ứng có
thuộc tính untrusted_app_visible_halserver
. Thiết bị đang chạy
với Android 9 KHÔNG ĐƯỢC sử dụng
Thuộc tính untrusted
.
Việc nên làm:
- Thay vào đó, các ứng dụng không đáng tin cậy phải trò chuyện với một dịch vụ hệ thống giao tiếp với
HIDL HAL của nhà cung cấp. Ví dụ: các ứng dụng có thể giao tiếp với
binderservicedomain
, sau đó giao tiếp vớimediaserver
(làbinderservicedomain
) giao tiếp vớihal_graphics_allocator
.HOẶC
- Các ứng dụng cần quyền truy cập trực tiếp vào HAL
vendor
phải có miền sepolicy do nhà cung cấp xác định của riêng bạn.
Kiểm tra thuộc tính tệp
Android 9 bao gồm các bài kiểm thử thời gian xây dựng để đảm bảo tất cả các tệp cụ thể
vị trí có các thuộc tính thích hợp (chẳng hạn như tất cả các tệp trong
sysfs
có thuộc tính sysfs_type
bắt buộc).
Chính sách công khai về nền tảng
Chính sách công khai về nền tảng là yếu tố cốt lõi để tuân thủ Android 8.0
mô hình kiến trúc mà không chỉ duy trì sự hợp nhất giữa các chính sách nền tảng
từ phiên bản 1 và phiên bản 2. Nhà cung cấp phải tuân thủ một số chính sách của nền tảng
chứa các loại, thuộc tính và quy tắc hữu dụng đối với các loại và thuộc tính đó
mà sau đó trở thành một phần trong chính sách của nhà cung cấp (ví dụ:
vendor_sepolicy.cil
).
Các loại và quy tắc được dịch tự động trong chính sách do nhà cung cấp tạo
vào attribute_vN
để tất cả các loại do nền tảng cung cấp
là các thuộc tính có tạo phiên bản (tuy nhiên, các thuộc tính không có phiên bản). Nền tảng này
chịu trách nhiệm lập bản đồ các loại cụ thể mà nó cung cấp vào
để đảm bảo rằng chính sách của nhà cung cấp tiếp tục hoạt động và các quy tắc
được cung cấp cho một phiên bản cụ thể. Kết hợp
chính sách công khai trên nền tảng và chính sách dành cho nhà cung cấp đáp ứng kiến trúc Android 8.0
mô hình cho phép các nhà cung cấp và nền tảng độc lập tạo bản dựng.
Liên kết đến chuỗi thuộc tính
Khi sử dụng thuộc tính để liên kết với các phiên bản chính sách, một loại sẽ liên kết với một thuộc tính hoặc nhiều thuộc tính, đảm bảo các đối tượng được gắn nhãn cùng với loại có thể truy cập được qua tương ứng với các loại trước đó của chúng.
Việc duy trì mục tiêu ẩn thông tin phiên bản với người viết chính sách có nghĩa là
tự động tạo các thuộc tính có phiên bản và gán chúng cho
phù hợp. Trong trường hợp phổ biến là các kiểu tĩnh, sau đây là đơn giản:
type_foo
ánh xạ tới type_foo_v1
.
Để thay đổi nhãn đối tượng, chẳng hạn như sysfs
→ sysfs_A
hoặc
mediaserver
→ audioserver
, việc tạo mối liên kết này đang
không nhỏ (và được mô tả trong các ví dụ ở trên). Đơn vị duy trì chính sách của nền tảng
phải xác định cách tạo ánh xạ tại các điểm chuyển tiếp cho đối tượng, điều này
đòi hỏi phải hiểu mối quan hệ giữa các đối tượng và các đối tượng được chỉ định
nhãn và xác định thời điểm điều này xảy ra. Để có khả năng tương thích ngược,
cần quản lý sự phức tạp ở phía nền tảng, đây là phân vùng duy nhất
có thể tăng lên.
Số lần cải thiện phiên bản
Để đơn giản, nền tảng Android sẽ phát hành một phiên bản sepolicy khi một
nhánh phát hành bị cắt. Như được mô tả ở trên, số phiên bản có trong
PLATFORM_SEPOLICY_VERSION
và có dạng MM.nn
,
trong đó MM
tương ứng với giá trị SDK và nn
là
giá trị riêng tư được duy trì trong /platform/system/sepolicy.
Đối với
ví dụ: 19.0
cho Kitkat, 21.0
cho Lollipop,
22.0
cho Lollipop-MR1 23.0
cho Marshmallow,
24.0
cho Nougat, 25.0
cho Nougat-MR1,
26.0
cho Oreo, 27.0
cho Oreo-MR1 và
28.0
cho Android 9.
Số lượt tăng lên không phải lúc nào cũng là số nguyên. Cho
ví dụ: nếu việc tăng MR lên một phiên bản đòi hỏi phải thay đổi không tương thích trong
system/sepolicy/public
nhưng không phải là API tăng, thì chính sách đó
phiên bản có thể là: vN.1
. Phiên bản có trong một quá trình phát triển
nhánh là một 10000.0
thiết bị không bao giờ sử dụng trong hàng vận chuyển.
Android có thể sẽ ngừng sử dụng phiên bản cũ nhất khi nâng cấp. Để nhập thông tin về thời điểm không dùng một phiên bản nữa, Android có thể thu thập số lượng thiết bị cùng nhà cung cấp các chính sách chạy phiên bản Android đó mà vẫn nhận được nền tảng chính bản cập nhật. Nếu con số này thấp hơn một ngưỡng nhất định, thì phiên bản đó không dùng nữa.
Tác động đến hiệu suất của nhiều thuộc tính
Như được mô tả trong https://github.com/SELinuxProject/cil/issues/9, một số lượng lớn thuộc tính được gán cho một loại dẫn đến vấn đề về hiệu suất trong thiếu bộ nhớ đệm chính sách.
Đây được xác nhận là một vấn đề trong Android, vì vậy, các thay đổi được thực hiện trên Android 8.0 để xoá các thuộc tính mà trình biên dịch chính sách cũng như xoá các thuộc tính không dùng đến. Những thay đổi này đã được giải quyết hồi quy hiệu suất.
Chính sách công khai của hệ thống và chính sách công khai của sản phẩm System_ext
Kể từ Android 11, phần system_ext và phân vùng sản phẩm được phép
xuất các loại công khai được chỉ định của họ sang phân vùng nhà cung cấp. Thích nền tảng
chính sách công khai, nhà cung cấp sẽ sử dụng
các loại và quy tắc được tự động chuyển đổi thành
các thuộc tính có phiên bản, ví dụ: từ type
sang
type_N
, trong đó N
là phiên bản
của nền tảng mà phân vùng nhà cung cấp được xây dựng.
Khi hệ thống_ext và phân vùng sản phẩm dựa trên cùng một phiên bản nền tảng
N
, hệ thống xây dựng sẽ tạo các tệp ánh xạ cơ sở để
system_ext/etc/selinux/mapping/N.cil
và
product/etc/selinux/mapping/N.cil
, chứa danh tính
ánh xạ từ type
đến type_N
. Nhà cung cấp có thể
truy cập type
bằng thuộc tính đã tạo phiên bản type_N
.
Trong trường hợp chỉ cập nhật phân vùng system_ext và phân vùng sản phẩm, giả sử
N
đến N+1
(hoặc cao hơn), trong khi
khi nhà cung cấp vẫn ở mức N
, thì nhà cung cấp có thể mất quyền truy cập vào
các loại phân vùng system_ext và phân vùng sản phẩm. Để ngăn chặn sự cố,
system_ext và phân vùng sản phẩm phải cung cấp tệp ánh xạ từ bê tông
nhập vào các thuộc tính type_N
. Mỗi đối tác
chịu trách nhiệm duy trì các tệp ánh xạ, nếu chúng có hỗ trợ
Nhà cung cấp N
có N+1
(trở lên)
system_ext và phân vùng sản phẩm.
Để làm được việc đó, đối tác cần:
- Sao chép các tệp ánh xạ cơ sở đã tạo từ
N
system_ext và phân vùng sản phẩm vào cây nguồn. - Sửa đổi tệp liên kết nếu cần.
-
Cài đặt
tệp ánh xạ đến
N+1
(hoặc phiên bản cao hơn) system_ext và phân vùng sản phẩm.
Ví dụ: giả sử N
system_ext có một thuộc tính công khai
loại có tên foo_type
. Sau đó system_ext/etc/selinux/mapping/N.cil
trong phân vùng system_ext N
sẽ có dạng như sau:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
Nếu bar_type
được thêm vào system_ext của N+1
và
nếu cần ánh xạ bar_type
tới foo_type
cho
Nhà cung cấp N
, có thể cập nhật N.cil
từ
(typeattributeset foo_type_N (foo_type))
tới
(typeattributeset foo_type_N (foo_type bar_type))
và sau đó được cài đặt vào phân vùng của system_ext N+1
.
Nhà cung cấp N
có thể tiếp tục truy cập vào N+1
foo_type
và bar_type
của system_ext.
Gắn nhãn ngữ cảnh SELinux
Để hỗ trợ việc phân biệt giữa nền tảng và chính sách của nhà cung cấp, hệ thống xây dựng các tệp ngữ cảnh SELinux theo cách khác để tách biệt chúng.
Bối cảnh của tệp
Android 8.0 đã cho ra mắt các thay đổi sau cho file_contexts
:
- Để tránh hao tổn thêm quá trình biên dịch trên thiết bị trong quá trình khởi động,
file_contexts
không còn tồn tại ở dạng nhị phân. Thay vào đó, là tệp văn bản biểu thức chính quy, có thể đọc được như{property, service}_contexts
(như trước phiên bản 7.0). file_contexts
được chia thành 2 tệp:plat_file_contexts
- Nền tảng Android
file_context
không có các nhãn dành riêng cho thiết bị, ngoại trừ việc gắn nhãn các phần của Phân vùng/vendor
phải được gắn nhãn chính xác là đảm bảo các tệp sepolicy hoạt động bình thường. - Phải nằm trong phân vùng
system
tại/system/etc/selinux/plat_file_contexts
trên thiết bị và được tải bởiinit
ngay từ đầu cùng vớifile_context
.
- Nền tảng Android
vendor_file_contexts
file_context
dành riêng cho thiết bị được tạo bằng cách kết hợp Tìm thấyfile_contexts
trong các thư mục được trỏ tớiBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
tệp.- Phải được cài đặt lúc
/vendor/etc/selinux/vendor_file_contexts
inch phân vùngvendor
và được tải bởiinit
lúc khởi đầu cùng với nền tảngfile_context
.
Bối cảnh của cơ sở lưu trú
Trong Android 8.0, property_contexts
được chia thành 2 tệp:
plat_property_contexts
- Nền tảng Android
property_context
không có nhãn dành riêng cho thiết bị. - Phải nằm trong phân vùng
system
tại/system/etc/selinux/plat_property_contexts
và sẽ được tải bởiinit
lúc bắt đầu cùng với nhà cung cấpproperty_contexts
.
- Nền tảng Android
vendor_property_contexts
property_context
dành riêng cho thiết bị được tạo bằng cách kết hợp Tìm thấyproperty_contexts
trong các thư mục được trỏ tớiBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
tệp.- Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_property_contexts
và sẽ được tải bởiinit
lúc bắt đầu cùng với nền tảngproperty_context
Ngữ cảnh dịch vụ
Trong Android 8.0, service_contexts
được phân chia giữa các phần tử sau:
tệp:
plat_service_contexts
service_context
dành riêng cho nền tảng Android cho giá trịservicemanager
service_context
không có nhãn dành riêng cho thiết bị.- Phải nằm trong phân vùng
system
tại/system/etc/selinux/plat_service_contexts
và được tải bởiservicemanager
khi bắt đầu cùng với nhà cung cấpservice_contexts
.
vendor_service_contexts
service_context
dành riêng cho thiết bị được tạo bằng cách kết hợp Tìm thấyservice_contexts
trong các thư mục được trỏ tớiBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
tệp.- Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_service_contexts
và sẽ được tải củaservicemanager
lúc bắt đầu cùng với nền tảngservice_contexts
. - Mặc dù
servicemanager
sẽ tìm tệp này tại thời điểm khởi động, cho thiết bịTREBLE
hoàn toàn tương thích,vendor_service_contexts
KHÔNG ĐƯỢC tồn tại. Điều này là do tất cả tương tác giữavendor
vàsystem
các quy trình PHẢI trải quahwservicemanager
/hwbinder
.
plat_hwservice_contexts
hwservice_context
của Nền tảng Android dành chohwservicemanager
không có nhãn dành riêng cho thiết bị.- Phải nằm trong phân vùng
system
tại/system/etc/selinux/plat_hwservice_contexts
và được tải bởihwservicemanager
ở đầu cùng vớivendor_hwservice_contexts
.
vendor_hwservice_contexts
hwservice_context
dành riêng cho thiết bị được tạo bằng cách kết hợp Tìm thấyhwservice_contexts
trong các thư mục được trỏ tớiBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
tệp.- Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_hwservice_contexts
và sẽ được tải bởihwservicemanager
lúc bắt đầu cùng vớiplat_service_contexts
.
vndservice_contexts
service_context
dành riêng cho thiết bị đểvndservicemanager
được tạo bằng cách kết hợp Đã tìm thấyvndservice_contexts
trong các thư mục được trỏ tớiBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
.- Tệp này phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vndservice_contexts
và được tải bởivndservicemanager
ở đầu.
Ngữ cảnh seapp
Trong Android 8.0, seapp_contexts
được chia thành 2 tệp:
plat_seapp_contexts
- Nền tảng Android
seapp_context
không dành riêng cho thiết bị thay đổi. - Phải nằm trong phân vùng
system
tại/system/etc/selinux/plat_seapp_contexts.
- Nền tảng Android
vendor_seapp_contexts
- Đã tạo tiện ích dành riêng cho thiết bị cho nền tảng
seapp_context
bằng cách kết hợpseapp_contexts
tìm thấy trong các thư mục doBOARD_SEPOLICY_DIRS
trỏ đến trongBoardconfig.mk
tệp. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_seapp_contexts
- Đã tạo tiện ích dành riêng cho thiết bị cho nền tảng
Quyền truy cập MAC
Trong Android 8.0, mac_permissions.xml
được chia thành 2 tệp:
- Sân ga
mac_permissions.xml
- Nền tảng Android
mac_permissions.xml
không có các thay đổi theo thiết bị cụ thể. - Phải nằm trong phân vùng
system
tại/system/etc/selinux/.
- Nền tảng Android
mac_permissions.xml
không phải nền tảng- Tiện ích dành riêng cho thiết bị tới nền tảng
mac_permissions.xml
được xây dựng từ Tìm thấymac_permissions.xml
trong các thư mục được trỏ đếnBOARD_SEPOLICY_DIRS
trong thiết bịBoardconfig.mk
tệp. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/.
- Tiện ích dành riêng cho thiết bị tới nền tảng