Bài viết này mô tả cách Android xử lý các vấn đề tương thích chính sách với OTA nền tảng, trong đó cài đặt SELinux nền tảng mới có thể khác với cài đặt SELinux của nhà cung cấp cũ.
Thiết kế chính sách SELinux dựa trên Treble xem xét sự phân biệt nhị phân giữa chính sách nền tảng và nhà cung cấp ; lược đồ trở nên 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 toàn cầu của SELinux được chia thành các thành phần riêng tư và công khai. Các thành phần công khai bao gồm chính sách và cơ sở hạ tầng liên quan, được đảm bảo có sẵn cho phiên bản nền tảng. Chính sách này sẽ được cung cấp cho người viết chính sách của nhà cung cấp để cho phé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, sẽ tạo ra chính sách đầy đủ chức năng cho thiết bị.
- Để lập phiên bản, chính sách công khai nền tảng đã xuất sẽ được viết dưới dạng thuộc tính .
- Để dễ dàng viết chính sách, các loại đã xuất sẽ được chuyển đổi thành các thuộc tính được phiên bản như một phần của quy trình xây dựng chính sách. Các loại công khai cũng có thể được sử dụng trực tiếp trong các quyết định ghi nhãn do các tệp ngữ cảnh của nhà cung cấp cung cấp.
Android duy trì ánh xạ giữa các loại cụ thể được xuất trong chính sách nền tảng và các thuộc tính được phiên bản tương ứng cho từng phiên bản nền tảng . Điều này đảm bảo rằng khi các đối tượng được gắn nhãn một loại, nó không vi phạm hành vi được đảm bảo bởi chính sách công khai nền tảng trong phiên bản trước. Ánh xạ này được duy trì bằng cách cập nhật tệp ánh xạ cho từng phiên bản nền tảng , giúp lưu giữ thông tin thành viên thuộc tính cho từng loại được xuất trong chính sách công.
Quyền sở hữu và ghi nhãn đối tượng
Khi tùy chỉnh chính sách trong Android 8.0 trở lên, quyền sở hữu phải được xác định rõ ràng cho từng đối tượng để tách biệt chính sách nền tảng và nhà cung cấp. Ví dụ: nếu nhà cung cấp gắn nhãn /dev/foo
và nền tảng sau đó gắn nhãn /dev/foo
trong OTA tiếp theo, thì sẽ có hành vi không xác định. Đối với SELinux, điều này biểu hiện dưới dạng xung đột ghi nhãn. Nút thiết bị chỉ có thể có một nhãn duy nhất phân giải theo nhãn nào được áp dụng cuối cùng. Kết quả là:
- Các 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 quy trình giành quyền truy cập vào tệp có thể bị hỏng do tạo nút thiết bị sai.
Các thuộc tính hệ thống cũng có khả năng đặt tên cho các xung đột có thể dẫn đến hành vi không xác định trên hệ thống (cũng như đối với việc ghi nhãn SELinux). Xung đột giữa nhãn nền tảng và nhà cung cấp có thể xảy ra đối với bất kỳ đối tượng nào có nhãn SELinux, bao gồm các thuộc tính, dịch vụ, quy trình, tệp và ổ cắm. Để tránh những vấn đề này, hãy xác định rõ quyền sở hữu các đối tượng này.
Ngoài xung đột nhãn, tên loại/thuộc tính SELinux cũng có thể xung đột. Xung đột tên loại/thuộc tính sẽ luôn dẫn đến lỗi trình biên dịch chính sách.
Không gian tên loại/thuộc tính
SELinux không cho phép khai báo nhiều loại/thuộc tính giống nhau. Chính sách có khai báo trùng lặp sẽ không biên dịch được. Để tránh xung đột tên loại và thuộc tính, tất cả các khai báo của nhà cung cấp phải được đặt tên bắt đầu bằng np_
.
type foo, domain; → type np_foo, domain;
Quyền sở hữu ghi nhãn thuộc tính hệ thống và quy trình
Tránh xung đột ghi nhãn được giải quyết tốt nhất bằng cách sử dụng không gian tên thuộc tính. Để dễ dàng xác định các thuộc tính nền tảng và tránh xung đột tên khi đổi tên hoặc thêm thuộc tính nền tảng đã xuất, hãy đảm bảo tất cả thuộc tính của nhà cung cấp đều có tiền tố riêng:
Loại tài sản | Tiền tố được chấp nhận |
---|---|
thuộc tính điều khiển | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
có thể đọc và ghi | vendor. |
chỉ đọc | ro.vendor. ro.boot. ro.hardware. |
kiên trì | persist.vendor. |
Các nhà cung cấp có thể tiếp tục sử dụng ro.boot.*
(xuất phát từ cmdline kernel) và ro.hardware.*
(một thuộc tính rõ ràng liên quan đến phần cứng).
Tất cả các dịch vụ của nhà cung cấp trong tệp init RC phải có vendor.
dành cho các dịch vụ trong tệp init rc của các phân vùng không thuộc hệ thống. Các quy tắc tương tự được áp dụng cho nhãn SELinux cho thuộc tính nhà cung cấp ( vendor_
cho thuộc tính nhà cung cấp).
Quyền sở hữu tập tin
Việc ngăn chặn xung đột giữa các tệp là một thách thức vì cả chính sách nền tảng và nhà cung cấp đều thường cung cấp nhãn cho tất cả các hệ thống tệp. Không giống như cách đặt tên kiểu, việc đặt tên không gian tên của các tệp là không thực tế vì nhiều tệp trong số chúng được tạo bởi kernel. Để 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 tin trong phần này. Đối với Android 8.0, đây là những đề xuất không cần thực thi về mặt kỹ thuật. Trong tương lai, những đề xuất này sẽ được Bộ thử nghiệm nhà cung cấp (VTS) thực thi.
Hệ thống (/hệ thống)
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
thì bản cập nhật OTA chỉ dành cho khung có thể không thực hiện được.
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
mà nền tảng tương tác, cho phép viết các quy tắc SELinux cho các quy trình nền tảng để có thể nói chuyện và/hoặc truy cập các phần của phân vùng vendor
. Ví dụ:
/vendor | Nhãn do nền tảng cung cấp | Quy trình nền tảng tùy thuộc vào nhãn |
---|---|---|
/vendor(/. * )? | vendor_file | Tất cả các máy khách HAL trong framework, 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. |
Do đó, các quy tắc cụ thể phải được tuân theo (được thực thi thông qua neverallows
) khi gắn nhãn các tệp bổ sung trong phân vùng vendor
:
-
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 điều này để truy cập vào việc triển khai HAL chuyển tiếp. - Tất cả
exec_types
mới được thêm vào phân vùngvendor
thông qua SEPolicy của nhà cung cấp phải có thuộc tínhvendor_file_type
. Điều này được thực thi thông qua Neverallows. - Để 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 ngoài
exec_types
trong phân vùngvendor
. - Tất cả các phần phụ thuộc của thư viện cho các HAL của cùng một quy trình được AOSP xác định phải được gắn nhãn là
same_process_hal_file.
Procfs (/proc)
Các tệp trong /proc
có thể được gắn nhãn chỉ bằng nhãn genfscon
. Trong Android 7.0, cả chính sách nền tảng và nhà cung cấp đều sử dụng genfscon
để gắn nhãn các tệp trong procfs
.
Khuyến nghị: Chỉ có nhãn chính sách nền tảng /proc
. Nếu 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 mặc định ( proc
), chính sách của nhà cung cấp không nên gắn nhãn rõ ràng cho chúng và thay vào đó nên sử dụng loại proc
chung để thêm quy tắc cho miền của nhà cung cấp. Điều này cho phép các bản cập nhật nền tảng phù hợp với các giao diện hạt nhân 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)
Debugfs
có thể được gắn nhãn trong cả file_contexts
và genfscon
. Trong Android 7.0 đến Android 10, cả debugfs
nhãn nền tảng và nhà cung cấp .
Trong Android 11, không thể truy cập hoặc gắn debugfs
trên các thiết bị sản xuất. Các nhà sản xuất thiết bị nên loại bỏ debugfs
.
Tracefs (/sys/kernel/gỡ lỗi/truy tìm)
Tracefs
có thể được gắn nhãn trong cả file_contexts
và genfscon
. Trong Android 7.0, chỉ có nhãn nền tảng tracefs
.
Khuyến nghị: Chỉ nền tảng mới có thể gắn nhãn tracefs
.
Hệ thống (/sys)
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 tệp trong sysfs
.
Khuyến nghị: Nền tảng có thể gắn nhãn các nút sysfs
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 các tập tin.
tmpfs (/dev)
Các tệp trong /dev
có thể được gắn nhãn trong file_contexts
. Trong Android 7.0, cả tệp nhãn nền tảng và nhà cung cấp đều ở đây.
Khuyến nghị: 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
).
Rootf (/)
Các tệp trong /
có thể được gắn nhãn trong file_contexts
. Trong Android 7.0, cả tệp nhãn nền tảng và nhà cung cấp đều ở đây.
Khuyến nghị: Chỉ hệ thống mới có thể gắn nhãn các tệp trong /
.
Dữ liệu (/dữ liệu)
Dữ liệu được gắn nhãn thông qua sự kết hợp của file_contexts
và seapp_contexts
.
Khuyến nghị: Không cho phép ghi 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 các loại nguồn và đích đối với các lớp đối tượng và quyền cụ thể. Mọi đối tượng (quy trình, tệp, v.v.) bị ảnh hưởng bởi chính sách SELinux có thể chỉ có một loại, nhưng loại đó có thể có nhiều thuộc tính.
Chính sách được viết chủ yếu dưới dạng 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 với kiến thức về mọi loại. Tuy nhiên, nếu chính sách của nhà cung cấp và chính sách nền tảng sử dụng các loại cụ thể và nhãn của một đối tượng cụ thể chỉ thay đổi một trong các chính sách đó thì chính sách còn lại có thể chứa chính sách đã giành được hoặc mất quyền truy cập mà trước đó đã dựa vào. 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ể đổi thành:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Mặc dù chính sách của nhà cung cấp vẫn giữ nguyên nhưng v_domain
sẽ mất quyền truy cập do thiếu chính sách cho loại sysfs_A
mới.
Bằng cách xác định chính sách theo các thuộc tính, chúng ta có thể cung cấp cho đối tượng cơ bản một loại có thuộc tính tương ứng với chính sách cho cả nền tảng và mã nhà cung cấp. Điều này có thể được thực hiện cho tất cả các loại để tạo một chính sách thuộc tính một cách hiệu quả trong đó các loại cụ thể không bao giờ được sử dụng. Trong thực tế, điều này chỉ được yêu cầu đối với các phần chính sách chồng chéo giữa nền tảng và nhà cung cấp, được xác định và cung cấp dưới dạng chính sách công khai của nền tảng được xây dựng như một phần của chính sách nhà cung cấp.
Việc xác định chính sách công là các thuộc tính được phiên bản đáp ứng hai mục tiêu tương thích chính sách:
- Đảm bảo mã 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 các thuộc tính vào các loại cụ thể cho các đối tượng tương ứng với các thuộc tính mà mã nhà cung cấp dựa vào, duy trì quyền truy cập.
- Khả năng từ chối chính sách . Đạt được bằng cách phân định rõ ràng các bộ chính sách thành các thuộc tính có thể bị xóa ngay khi phiên bản tương ứng với chúng không còn được hỗ trợ. Quá trình phát triển có thể tiếp tục trên nền tảng vì biết rằng chính sách cũ vẫn còn trong chính sách của nhà cung cấp và sẽ tự động bị xóa khi/nếu nó nâng cấp.
Khả năng ghi chính sách
Để đáp ứng mục tiêu không yêu cầu kiến thức về các thay đổi phiên bản cụ thể để phát triển chính sách, Android 8.0 bao gồm ánh xạ giữa các loại chính sách nền tảng công cộng và thuộc tính của chúng. Loại foo
được ánh xạ tới thuộc tính foo_v N
, trong đó N
là phiên bản được nhắm mục tiêu. vN
tương ứng với biến xây dựng PLATFORM_SEPOLICY_VERSION
và có dạng MM.NN
, trong đó MM
tương ứng với số SDK nền tảng và NN
là phiên bản dành riêng cho chính sách nền tảng.
Các thuộc tính trong chính sách công không được lập 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 có thể xây dựng để giữ cho giao diện giữa hai phân vùng ổn định. Cả người viết chính sách nền tảng và nhà cung cấp đều có thể tiếp tục viết chính sách như được viết ngày nay.
Chính sách công khai nền tảng được xuất dưới dạng allow source_foo target_bar: class perm ;
được bao gồm như một phần của chính sách nhà cung cấp. Trong quá trình biên dịch (bao gồm phiên bản tương ứng), nó được chuyển thành chính sách sẽ chuyển đến phần nhà cung cấp của thiết bị (hiển thị bằng Ngôn ngữ trung gian chung (CIL) đã được chuyển đổi):
(allow source_foo_vN target_bar_vN (class (perm)))
Vì chính sách của nhà cung cấp không bao giờ đi trước nền tảng nên không nê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 chính sách của nhà cung cấp lùi xa đến mức nào, bao gồm các thuộc tính cho các loại của nó và đặt chính sách tương ứng với các thuộc tính được phiên bản.
Khác biệt về chính sách
Việc tự động tạo các thuộc tính bằng cách thêm _v N
vào cuối mỗi loại sẽ không có tác dụng gì nếu không ánh xạ các thuộc tính thành các loại trên các phiên bản khác nhau. Android duy trì ánh xạ giữa các phiên bản cho các thuộc tính và ánh xạ các loại cho các thuộc tính đó. Điều này được thực hiện trong các tệp ánh xạ nói trên bằng 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 tình huống nâng cấp nền tảng.
Cùng loại
Tình huống này xảy ra khi một đối tượng không thay đổi nhãn trong phiên bản chính sách. Điều này giống nhau đối với các loại nguồn và đích và có thể được nhìn thấy bằng /dev/binder
, được gắn nhãn binder_device
trên tất cả các bản phát hành. Nó đượ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 có:
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 nhà cung cấp v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
Trong chính sách nhà cung cấp v2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Các loại mới
Tình huống này xảy ra khi nền tảng đã thêm một loại mới, điều này có thể xảy ra khi thêm các tính năng mới hoặc trong quá trình thắt chặt chính sách.
- Tính năng mới . Khi loại này gắn nhãn cho một đối tượng mà trước đây không tồn tại (chẳng hạn như quy trình dịch vụ mới), mã nhà cung cấp trước đó không tương tác trực tiếp với đối tượng đó nên không tồn tại chính sách tương ứng. Thuộc tính mới tương ứng với loại không có thuộc tính trong phiên bản trước và do đó sẽ không cần mục nhập trong tệp ánh xạ nhắm mục tiêu phiên bản đó.
- Thắt chặt chính sách Khi loại thể hiện việc tăng cường chính sách, thuộc tính loại mới phải liên kết trở lại chuỗi thuộc tính tương ứng với thuộc tính trước đó (tương tự như ví dụ trước khi thay đổi
/sys/A
từsysfs
thànhsysfs_A
). Mã nhà cung cấp dựa trên quy tắc cho phép truy cập vàosysfs
và cần đưa quy tắc đó làm 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 có:
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 nhà cung cấp v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Trong chính sách nhà cung cấp v2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Các loại đã xóa
Tình huống (hiếm) này xảy ra khi một loại bị xóa, điều này có thể xảy ra khi đối tượng cơ bản:
- Vẫn còn nhưng có nhãn hiệu khác.
- Được loại bỏ bởi nền tảng.
Trong quá trình nới lỏng chính sách, một loại sẽ bị xóa và đối tượng được gắn nhãn loại đó sẽ được cấp một nhãn khác, đã tồn tại. Điều này thể hiện sự hợp nhất của các ánh xạ thuộc tính: Mã nhà cung cấp vẫn phải có khả năng truy cập vào đối tượng cơ bản bằng thuộc tính mà nó từng sở hữu, nhưng phần còn lại của hệ thống giờ đây phải có khả năng truy cập vào đối tượng đó bằng thuộc tính mới.
Nếu thuộc tính mà nó được chuyển sang là mới thì việc gắn nhãn lại cũng giống như trong trường hợp loại mới, ngoại trừ khi sử dụng nhãn hiện có, việc thêm thuộc tính cũ loại mới sẽ khiến các đối tượng khác cũng được gắn nhãn loại này. mới có thể truy cập được. Về cơ bản, đây là những gì nền tảng thực hiện 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 …)
Ví dụ Phiên bản 1: Thu gọn các loại (xóa sysfs_A)
Khi nâng cấp từ v1
→ v2
, chính sách nền tảng phải có:
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 nhà cung cấp v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
Trong chính sách nhà cung cấp v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Ví dụ Phiên bản 2: Loại bỏ 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 có:
# 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 nhà cung cấp v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
Trong chính sách nhà cung cấp v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Lớp/quyền mới
Tình huống này xảy ra khi nâng cấp nền tảng giới thiệu các thành phần chính sách mới không tồn tại trong các phiên bản trước. Ví dụ: khi Android thêm trình quản lý đối tượng servicemanager
đã tạo các quyền thêm, tìm và liệt kê, các trình nền của nhà cung cấp muốn đăng ký với servicemanager
cần có các quyền không có sẵn. 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 mới.
Để 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 bị cản trở, 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;
Điều này thậm chí có thể yêu cầu chính sách cho phép truy cập đối với tất cả các loại giao diện (chính sách công), để đảm bảo hình ảnh nhà cung cấp có được quyền truy cập. Nếu điều này dẫn đến chính sách bảo mật không được chấp nhận (vì nó có thể xảy ra với những thay đổi của trình quản lý dịch vụ), thì có thể buộc phải nâng cấp nhà cung cấp.
Đã xóa lớp/quyền
Tình huống này xảy ra khi trình quản lý đối tượng bị xóa (chẳng hạn như trình quản lý đối tượng ZygoteConnection
) và không gây ra sự cố. Lớp quản lý đối tượng và các quyền có thể vẫn được xác định trong chính sách cho đến khi phiên bản nhà cung cấp không còn sử dụng nó nữa. Điều này được thực hiện bằng cách thêm các định nghĩa vào tệp ánh xạ tương ứng.
Tùy chỉnh nhà cung cấp cho các loại mới/được dán nhãn lại
Các loại nhà cung cấp mới là cốt lõi của việc phát triển chính sách nhà cung cấp vì chúng cần thiết để mô tả các quy trình, nhị phân, thiết bị, hệ thống con và dữ liệu được lưu trữ mới. Vì vậy, 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 của 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 phải 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ỳ điều gì được gắn nhãn trong chính sách của nhà cung cấp vì nền tảng không biết gì về điều đó; tuy nhiên, nền tảng sẽ cung cấp các thuộc tính và loại công khai mà nó sử dụng để tương tác với các đối tượng được gắn nhãn 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 này, các thuộc tính và loại phải được áp dụng phù hợp và có thể cần thêm các quy tắc cụ thể vào các miền có thể tùy chỉnh (chẳng hạn như init
).
Thay đổi thuộc tính cho Android 9
Các 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 các thiết bị khởi chạy bằng Android 9 thì không được.
Thuộc tính vi phạm
Android 9 bao gồm các thuộc tính liên quan đến miền sau:
-
data_between_core_and_vendor_violators
. Thuộc tính dành cho tất cả các miền vi phạm yêu cầu không chia sẻ tệp theo đường dẫn giữavendor
vàcoredomains
. Các quy trình của nền tảng và nhà cung cấp không nên sử dụng các tệp trên đĩa để liên lạc (ABI không ổn định). Sự giới thiệu:- Mã nhà cung cấp nên sử dụng
/data/vendor
. - Hệ thống không nên sử dụng
/data/vendor
.
- Mã nhà cung cấp nên 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ừ miềninit
vàshell domains
) vi phạm yêu cầu không thực thi các tệp nhị phân của nhà cung cấp. Việc thực thi các tệp nhị phân của nhà cung cấp có API không ổn định. Nền tảng không nên thực thi trực tiếp các tệp nhị phân của nhà cung cấp. Sự giới thiệu:- Sự phụ thuộc nền tảng như vậy vào các tệp nhị phân của nhà cung cấp phải nằm sau HIDL HAL.
HOẶC
-
coredomains
cần quyền truy cập vào các tệp nhị phân của nhà cung cấp nên được chuyển sang phân vùng của nhà cung cấp và do đó, không còn làcoredomain
nữa.
- Sự phụ thuộc nền tảng như vậy vào các tệp nhị phân của nhà cung cấp phải nằm sau HIDL HAL.
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ã tùy ý sẽ không có quyền truy cập vào các dịch vụ HwBinder, ngoại trừ những ứng dụng đượ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 cho việc này là:
- Máy chủ HwBinder không thực hiện xác thực ứng dụng khách vì HIDL hiện không hiển thị thông tin UID của người gọi. Ngay cả khi HIDL tiết lộ dữ liệu đó, nhiều dịch vụ HwBinder vẫn hoạt động ở cấp độ thấp hơn ứng dụng (chẳng hạn như HAL) hoặc không được dựa vào danh tính ứng dụng để ủy quyền. Do đó, để an toàn, giả định mặc định là mọi dịch vụ HwBinder đều coi tất cả khách hàng của mình được ủy quyền như nhau để thực hiện các hoạt động do dịch vụ cung cấp.
- Máy chủ HAL (một tập hợp con của dịch vụ HwBinder) chứa mã có tỷ lệ xảy ra sự cố bảo mật cao hơn so với các thành phần
system/core
và có quyền truy cập vào các lớp thấp hơn của ngăn xếp (đến tận phần cứng), do đó tăng cơ hội vượt qua mô hình bảo mật 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ó cùng quyền truy cập với miền máy khách nơi quy trình chạy. -
coredomain_hwservice
. Những dịch vụ này không gây ra rủi ro liên quan đến lý do số 2. -
hal_configstore_ISurfaceFlingerConfigs
. Dịch vụ này được thiết kế đặc biệt để sử dụng bởi bất kỳ tên miền nào. -
hal_graphics_allocator_hwservice
. Các hoạt động này cũng được cung cấp bởi dịch vụsurfaceflinger
Binder, ứng dụng nào được phép truy cập. -
hal_omx_hwservice
. Đây là phiên bản HwBinder của dịch vụmediacodec
Binder mà các ứ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
không được coi là 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
. Các thiết bị khởi chạy với Android 9 KHÔNG PHẢI sử dụng thuộc tính untrusted
.
Sự giới thiệu:
- Thay vào đó, các ứng dụng không đáng tin cậy nên liên hệ với dịch vụ hệ thống liên hệ với nhà cung cấp HIDL HAL. Ví dụ: các ứng dụng có thể giao tiếp với
binderservicedomain
, sau đómediaserver
(là mộtbinderservicedomain
) lần lượt 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 riêng biệt do nhà cung cấp xác định.
Kiểm tra thuộc tính tệp
Android 9 bao gồm các thử nghiệm về thời gian xây dựng để đảm bảo tất cả các tệp ở các vị trí cụ thể đều có thuộc tính thích hợp (chẳng hạn như tất cả các tệp trong sysfs
đều có thuộc tính sysfs_type
bắt buộc).
Chính sách công-nền tảng
Chính sách công khai nền tảng là cốt lõi của việc tuân thủ mô hình kiến trúc Android 8.0 mà không chỉ duy trì sự thống nhất của các chính sách nền tảng từ v1 và v2. Nhà cung cấp được tiếp cận với một tập hợp con chính sách nền tảng chứa các loại và thuộc tính có thể sử dụng cũng như quy tắc đối với các loại và thuộc tính đó, sau đó trở thành một phần của chính sách nhà cung cấp (ví dụ: vendor_sepolicy.cil
).
Các loại và quy tắc được tự động dịch trong chính sách do nhà cung cấp tạo thành attribute_v N
sao cho tất cả các loại do nền tảng cung cấp đều là thuộc tính đã được phiên bản (tuy nhiên các thuộc tính không được phiên bản). Nền tảng chịu trách nhiệm ánh xạ các loại cụ thể mà nó cung cấp thành các thuộc tính thích hợp để đảm bảo rằng chính sách của nhà cung cấp tiếp tục hoạt động và bao gồm các quy tắc được cung cấp cho một phiên bản cụ thể. Sự kết hợp giữa chính sách công khai nền tảng và chính sách nhà cung cấp đáp ứng mục tiêu mô hình kiến trúc Android 8.0 là cho phép xây dựng nền tảng và nhà cung cấp độc lập.
Ánh xạ tới chuỗi thuộc tính
Khi sử dụng thuộc tính để ánh xạ tới các phiên bản chính sách, một loại sẽ ánh xạ tớ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 loại đó có thể truy cập được thông qua các thuộc tính tương ứng với loại trước đó của chúng.
Duy trì mục tiêu ẩn thông tin phiên bản khỏ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 các loại thích hợp. Trong trường hợp phổ biến của các loại tĩnh, điều này rất đơn giản: type_foo
ánh xạ tới type_foo_v1
.
Đối với thay đổi nhãn đối tượng, chẳng hạn như sysfs
→ sysfs_A
hoặc mediaserver
→ audioserver
, việc tạo ánh xạ này là không hề nhỏ (và được mô tả trong các ví dụ ở trên). Người duy trì chính sách 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 các đố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à nhãn được gán của chúng cũng như xác định thời điểm điều này xảy ra. Để có khả năng tương thích ngược, sự phức tạp này cần được quản lý ở phía nền tảng, đây là phân vùng duy nhất có thể nâng cấp.
Phiên bản nâng cấp
Để đơn giản, nền tảng Android phát hành phiên bản tách biệt khi nhánh phát hành mới bị cắt. Như đã mô tả ở trên, số phiên bản được chứa 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 được duy trì trong /platform/system/sepolicy.
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. Các bản nâng cấp thì không luôn là số nguyên. Ví dụ: nếu phần nâng cấp MR đối với một phiên bản yêu cầu thay đổi không tương thích trong system/sepolicy/public
nhưng không phải là phần nâng cấp API thì phiên bản sepolicy đó có thể là: vN.1
. Phiên bản có trong nhánh phát triển là thiết bị không bao giờ được sử dụng trong vận chuyển 10000.0
.
Android có thể không dùng phiên bản cũ nhất khi nâng cấp. Để biết thông tin về thời điểm ngừng sử dụng một phiên bản, Android có thể thu thập số lượng thiết bị có chính sách của nhà cung cấp đang chạy phiên bản Android đó và vẫn nhận được các bản cập nhật nền tảng chính. Nếu số lượng nhỏ hơn một ngưỡng nhất định thì phiên bản đó sẽ không được dùng nữa.
Tác động 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 sẽ dẫn đến các vấn đề về hiệu suất trong trường hợp thiếu bộ đệm chính sách.
Điều này đã được xác nhận là một sự cố trong Android, do đó, các thay đổi đã được thực hiện đối với Android 8.0 để xóa các thuộc tính được trình biên dịch chính sách thêm vào chính sách cũng như xóa các thuộc tính không được sử dụng. Những thay đổi này đã giải quyết tình trạng hồi quy hiệu suất.
Chính sách công khai của System_ext và sản phẩm
Bắt đầu từ Android 11, các phân vùng system_ext và sản phẩm được phép xuất các loại công khai được chỉ định sang phân vùng nhà cung cấp. Giống như chính sách công của nền tảng, nhà cung cấp sử dụng các loại và quy tắc được dịch tự động sang các thuộc tính được phiên bản, ví dụ: từ type
thành type_ N
, trong đó N
là phiên bản của nền tảng mà phân vùng của nhà cung cấp được xây dựng dựa trên đó.
Khi các phân vùng system_ext và 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ở tới system_ext/etc/selinux/mapping/ N .cil
và product/etc/selinux/mapping/ N .cil
, chứa danh tính ánh xạ từ type
sang type_ N
. Nhà cung cấp có thể truy cập type
với thuộc tính được phiên bản type_ N
.
Trong trường hợp chỉ có phân vùng system_ext và sản phẩm được cập nhật, chẳng hạn như N
đến N+1
(hoặc mới hơn), trong khi nhà cung cấp vẫn giữ nguyên N
, 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à sản phẩm. Để tránh bị hỏng, các phân vùng system_ext và sản phẩm phải cung cấp các tệp ánh xạ từ các loại cụ thể thành 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 họ định hỗ trợ nhà cung cấp N
với các phân vùng system_ext và sản phẩm N+1
(hoặc mới hơn).
Để làm được điều đó, các đối tác cần phải:
- Sao chép các tệp ánh xạ cơ sở được tạo từ
N
system_ext và phân vùng sản phẩm vào cây nguồn của chúng. - Sửa đổi các tập tin ánh xạ nếu cần.
- Cài đặt các tệp ánh xạ vào phân vùng system_ext và sản phẩm
N+1
(hoặc mới hơn).
Ví dụ: giả sử N
system_ext có một loại công khai có tên foo_type
. Sau đó system_ext/etc/selinux/mapping/ N .cil
trong phân vùng N
system_ext sẽ trô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 N+1
system_ext và nếu bar_type
phải được ánh xạ tới foo_type
cho nhà cung cấp N
, thì N .cil
có thể được cập nhật từ
(typeattributeset foo_type_N (foo_type))
ĐẾN
(typeattributeset foo_type_N (foo_type bar_type))
và sau đó được cài đặt vào phân vùng của N+1
system_ext. Nhà cung cấp N
có thể tiếp tục truy cập vào foo_type
và bar_type
của N+1
system_ext.
Ghi nhãn ngữ cảnh SELinux
Để hỗ trợ sự khác biệt giữa chính sách riêng biệt của nền tảng và nhà cung cấp, hệ thống xây dựng các tệp ngữ cảnh SELinux khác nhau để tách chúng ra.
Ngữ cảnh tập tin
Android 8.0 đã giới thiệu những thay đổi sau cho file_contexts
:
- Để tránh thêm chi phí biên dịch trên thiết bị trong khi khởi động,
file_contexts
không còn tồn tại ở dạng nhị phân. Thay vào đó, chúng là tệp văn bản biểu thức chính quy, có thể đọc được, chẳng hạn như{property, service}_contexts
(như trước phiên bản 7.0). -
file_contexts
được chia thành hai tệp:-
plat_file_contexts
-
file_context
nền tảng Android không 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 để đả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à đượcinit
tải khi bắt đầu cùng vớifile_context
của nhà cung cấp.
-
-
vendor_file_contexts
-
file_context
dành riêng cho thiết bị được tạo bằng cách kết hợpfile_contexts
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải được cài đặt tại
/vendor/etc/selinux/vendor_file_contexts
trong phân vùngvendor
và đượcinit
tải khi bắt đầu cùng với nền tảngfile_context
.
-
-
Bối cảnh thuộc tính
Trong Android 8.0, property_contexts
được chia thành hai tệp:
-
plat_property_contexts
-
property_context
của nền tảng Android 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à đượcinit
tải khi bắt đầu cùng vớiproperty_contexts
của nhà cung cấp.
-
-
vendor_property_contexts
- Thuộc
property_context
dành riêng cho thiết bị được tạo bằng cách kết hợpproperty_contexts
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_property_contexts
và đượcinit
tải khi bắt đầu cùng vớiproperty_context
nền tảng_context
- Thuộc
Bối cảnh dịch vụ
Trong Android 8.0, service_contexts
được phân chia giữa các tệp sau:
-
plat_service_contexts
-
service_context
dành riêng cho nền tảng Android dành choservicemanager
.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à đượcservicemanager
tải 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 xây dựng bằng cách kết hợpservice_contexts
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_service_contexts
và đượcservicemanager
tải khi bắt đầu cùng với nền tảngservice_contexts
. - Mặc dù
servicemanager
tìm kiếm tệp này khi khởi động, nhưng đối với thiết bịTREBLE
tuân thủ đầy đủ,vendor_service_contexts
KHÔNG PHẢI tồn tại. Điều này là do tất cả sự tương tác giữa cácsystem
trìnhvendor
và hệ thống PHẢI trải quahwservicemanager
/hwbinder
.
-
-
plat_hwservice_contexts
- Nền tảng Android
hwservice_context
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
khi bắt đầu cùng vớivendor_hwservice_contexts
.
- Nền tảng Android
-
vendor_hwservice_contexts
-
hwservice_context
dành riêng cho thiết bị được xây dựng bằng cách kết hợphwservice_contexts
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_hwservice_contexts
và đượchwservicemanager
tải khi bắt đầu cùng vớiplat_service_contexts
.
-
-
vndservice_contexts
-
service_context
dành riêng cho thiết bị dành chovndservicemanager
được xây dựng bằng cách kết hợpvndservice_contexts
được tìm thấy trong các thư mục được trỏ đến bởiBOARD_SEPOLICY_DIRS
trongBoardconfig.mk
của thiết bị. - Tệp này phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vndservice_contexts
và đượcvndservicemanager
tải ngay từ đầu.
-
Bối cảnh của Seapp
Trong Android 8.0, seapp_contexts
được chia thành hai tệp:
-
plat_seapp_contexts
- Nền tảng Android
seapp_context
không có thay đổi dành riêng cho thiết bị. - 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
- Tiện ích mở rộng dành riêng cho thiết bị cho nền tảng
seapp_context
được xây dựng bằng cách kết hợpseapp_contexts
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/vendor_seapp_contexts
.
- Tiện ích mở rộng dành riêng cho thiết bị cho nền tảng
Quyền MAC
Trong Android 8.0, mac_permissions.xml
được chia thành hai tệp:
- Nền tảng
mac_permissions.xml
- Nền tảng Android
mac_permissions.xml
không có thay đổi dành riêng cho thiết bị. - 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 mở rộng dành riêng cho thiết bị cho nền tảng
mac_permissions.xml
được xây dựng từmac_permissions.xml
được tìm thấy trong các thư mục đượcBOARD_SEPOLICY_DIRS
trỏ đến trong tệpBoardconfig.mk
của thiết bị. - Phải nằm trong phân vùng
vendor
tại/vendor/etc/selinux/.
- Tiện ích mở rộng dành riêng cho thiết bị cho nền tảng