SELinux được thiết lập để từ chối theo mặc định, nghĩa là mọi quyền truy cập mà SELinux có một móc trong nhân đều phải được chính sách cho phép rõ ràng. Điều này có nghĩa là tệp chính sách bao gồm một lượng lớn thông tin liên quan đến các quy tắc, loại, lớp, quyền và nhiều thông tin khác. Việc xem xét đầy đủ về SELinux nằm ngoài phạm vi của tài liệu này, nhưng bạn cần hiểu cách viết quy tắc chính sách khi khởi động thiết bị Android mới. Hiện đã có rất nhiều thông tin về SELinux. Hãy xem Tài liệu hỗ trợ để biết các tài nguyên được đề xuất.
Tệp khoá
Để bật SELinux, hãy tích hợp hạt nhân Android mới nhất, sau đó kết hợp các tệp có trong thư mục system/sepolicy. Khi được biên dịch, các tệp đó bao gồm chính sách bảo mật hạt nhân SELinux và bao gồm cả hệ điều hành Android thượng nguồn.
Nói chung, bạn không nên sửa đổi trực tiếp các tệp system/sepolicy
. Thay vào đó, hãy thêm hoặc chỉnh sửa các tệp chính sách dành riêng cho thiết bị của riêng bạn trong thư mục /device/manufacturer/device-name/sepolicy
. Trên Android 8.0 trở lên, những thay đổi bạn thực hiện đối với các tệp này chỉ ảnh hưởng đến chính sách trong thư mục nhà cung cấp. Để biết thêm thông tin chi tiết về việc phân tách chính sách bảo mật công khai trong Android 8.0 trở lên, hãy xem phần Tuỳ chỉnh SEPolicy trong Android 8.0 trở lên. Bất kể phiên bản Android nào, bạn vẫn sẽ sửa đổi các tệp sau:
Tệp chính sách
Các tệp kết thúc bằng *.te
là tệp nguồn chính sách SELinux, giúp xác định các miền và nhãn của các miền đó. Bạn có thể cần tạo tệp chính sách mới trong /device/manufacturer/device-name/sepolicy
, nhưng bạn nên cố gắng cập nhật các tệp hiện có nếu có thể.
Tệp ngữ cảnh
Tệp ngữ cảnh là nơi bạn chỉ định nhãn cho các đối tượng.
file_contexts
gán nhãn cho các tệp và được nhiều thành phần không gian người dùng sử dụng. Khi bạn tạo chính sách mới, hãy tạo hoặc cập nhật tệp này để chỉ định nhãn mới cho các tệp. Để áp dụngfile_contexts
mới, hãy tạo lại hình ảnh hệ thống tệp hoặc chạyrestorecon
trên tệp cần gắn nhãn lại. Trong quá trình nâng cấp, các thay đổi đối vớifile_contexts
sẽ tự động được áp dụng cho hệ thống và các phân vùng dữ liệu người dùng trong quá trình nâng cấp. Bạn cũng có thể tự động áp dụng các thay đổi khi nâng cấp lên các phân vùng khác bằng cách thêm các lệnh gọirestorecon_recursive
vào tệp init.board.rc sau khi phân vùng đã được gắn ở chế độ đọc-ghi.genfs_contexts
gán nhãn cho các hệ thống tệp, chẳng hạn nhưproc
hoặcvfat
không hỗ trợ các thuộc tính mở rộng. Cấu hình này được tải trong chính sách hạt nhân, nhưng các thay đổi có thể không có hiệu lực đối với các inode trong lõi, đòi hỏi phải khởi động lại hoặc tháo và gắn lại hệ thống tệp để áp dụng đầy đủ thay đổi. Bạn cũng có thể chỉ định các nhãn cụ thể cho các điểm gắn cụ thể, chẳng hạn nhưvfat
bằng cách sử dụng tuỳ chọncontext=mount
.property_contexts
gán nhãn cho các thuộc tính hệ thống Android để kiểm soát những quy trình có thể đặt các thuộc tính đó. Cấu hình này được quá trìnhinit
đọc trong quá trình khởi động.service_contexts
gán nhãn cho các dịch vụ liên kết Android để kiểm soát những quy trình có thể thêm (đăng ký) và tìm (tra cứu) tệp tham chiếu liên kết cho dịch vụ. Cấu hình này được quá trìnhservicemanager
đọc trong quá trình khởi động.seapp_contexts
gán nhãn cho các quy trình ứng dụng và thư mục/data/data
. Cấu hình này được quá trìnhzygote
đọc trong mỗi lần khởi chạy ứng dụng vàinstalld
trong quá trình khởi động.mac_permissions.xml
gán thẻseinfo
cho các ứng dụng dựa trên chữ ký và tên gói (không bắt buộc). Sau đó, bạn có thể sử dụng thẻseinfo
làm khoá trong tệpseapp_contexts
để chỉ định một nhãn cụ thể cho tất cả ứng dụng có thẻseinfo
đó. Cấu hình này đượcsystem_server
đọc trong quá trình khởi động.keystore2_key_contexts
gán nhãn cho các không gian tên của Keystore 2.0. Các không gian tên này được thực thi bởi trình nền keystore2. Kho khoá luôn cung cấp không gian tên dựa trên UID/AID. Kho khoá 2.0 cũng thực thi các không gian tên được xác định trong chính sách bảo mật. Bạn có thể xem nội dung mô tả chi tiết về định dạng và quy ước của tệp này tại đây.
Tệp makefile BoardConfig.mk
Sau khi chỉnh sửa hoặc thêm tệp chính sách và ngữ cảnh, hãy cập nhật tệp bản dựng /device/manufacturer/device-name/BoardConfig.mk
để tham chiếu thư mục con sepolicy
và từng tệp chính sách mới.
Để biết thêm thông tin về các biến BOARD_SEPOLICY
, hãy xem
tệp system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Sau khi tạo lại, thiết bị của bạn sẽ được bật SELinux. Giờ đây, bạn có thể tùy chỉnh các chính sách SELinux để điều chỉnh các nội dung bổ sung của riêng mình cho hệ điều hành Android như mô tả trong phần Tuỳ chỉnh hoặc xác minh chế độ thiết lập hiện có như trong phần Xác thực.
Khi các tệp chính sách mới và bản cập nhật BoardConfig.mk đã được triển khai, chế độ cài đặt chính sách mới sẽ tự động được đưa vào tệp chính sách nhân kernel cuối cùng. Để biết thêm thông tin về cách tạo sepolicy trên thiết bị, hãy xem phần Tạo sepolicy.
Triển khai
Cách bắt đầu sử dụng SELinux:
- Bật SELinux trong nhân:
CONFIG_SECURITY_SELINUX=y
- Thay đổi tham số kernel_cmdline hoặc bootconfig để:
hoặcBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
Đây chỉ là bước phát triển ban đầu của chính sách cho thiết bị. Sau khi bạn có chính sách khởi động ban đầu, hãy xoá tham số này để thiết bị của bạn thực thi hoặc không vượt qua được CTS.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- Khởi động hệ thống ở chế độ cho phép và xem những trường hợp từ chối gặp phải khi khởi động:
Trên Ubuntu 14.04 trở lên: Trên Ubuntu 12.04:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Đánh giá kết quả cho các cảnh báo tương tự như
init: Warning! Service name needs a SELinux domain defined; please fix!
Xem phần Xác thực để biết hướng dẫn và công cụ. - Xác định thiết bị và các tệp mới khác cần gắn nhãn.
- Sử dụng nhãn hiện có hoặc nhãn mới cho đối tượng. Hãy xem các tệp
*_contexts
để biết cách các thành phần được gắn nhãn trước đó và sử dụng kiến thức về ý nghĩa của nhãn để chỉ định nhãn mới. Lý tưởng nhất là đây là một nhãn hiện có phù hợp với chính sách, nhưng đôi khi bạn cần một nhãn mới và các quy tắc để truy cập vào nhãn đó. Thêm nhãn vào các tệp ngữ cảnh thích hợp. - Xác định những miền/quy trình cần có miền bảo mật riêng.
Bạn có thể cần phải viết một chính sách hoàn toàn mới cho từng tài sản. Ví dụ: tất cả các dịch vụ được tạo từ
init
phải có riêng. Các lệnh sau đây giúp tiết lộ những dịch vụ vẫn đang chạy (nhưng TẤT CẢ các dịch vụ đều cần được xử lý như vậy):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Xem lại
init.device.rc
để xác định mọi miền không có loại miền. Cung cấp cho chúng một miền sớm trong quá trình phát triển để tránh thêm quy tắc vàoinit
hoặc gây nhầm lẫn quyền truy cậpinit
với quyền truy cập trong chính sách của chúng. - Thiết lập
BOARD_CONFIG.mk
để sử dụng các biếnBOARD_SEPOLICY_*
. Hãy xem README trongsystem/sepolicy
để biết thông tin chi tiết về cách thiết lập. - Kiểm tra tệp init.device.rc và fstab.device và đảm bảo mọi lần sử dụng
mount
đều tương ứng với một hệ thống tệp được gắn nhãn đúng cách hoặc một tuỳ chọncontext= mount
được chỉ định. - Xem xét từng trường hợp từ chối và tạo chính sách SELinux để xử lý đúng cách từng trường hợp. Xem các ví dụ trong phần Tuỳ chỉnh.
Bạn nên bắt đầu với các chính sách trong AOSP, sau đó xây dựng dựa trên các chính sách đó để tuỳ chỉnh theo ý mình. Để biết thêm thông tin về chiến lược chính sách và tìm hiểu kỹ hơn về một số bước này, hãy xem phần Viết chính sách SELinux.
Trường hợp sử dụng
Sau đây là một số ví dụ cụ thể về các hành vi khai thác cần cân nhắc khi tạo phần mềm của riêng bạn và các chính sách SELinux liên quan:
Đường liên kết tượng trưng: Vì đường liên kết tượng trưng xuất hiện dưới dạng tệp, nên chúng thường được đọc dưới dạng tệp, điều này có thể dẫn đến hành vi khai thác. Ví dụ: một số thành phần đặc quyền, chẳng hạn như init
, thay đổi quyền của một số tệp nhất định, đôi khi mở quá mức.
Sau đó, kẻ tấn công có thể thay thế các tệp đó bằng đường liên kết tượng trưng đến mã mà chúng kiểm soát, cho phép kẻ tấn công ghi đè các tệp tuỳ ý. Tuy nhiên, nếu biết ứng dụng của mình không bao giờ truy cập vào đường liên kết tượng trưng, bạn có thể ngăn ứng dụng đó thực hiện việc này bằng SELinux.
Tệp hệ thống: Hãy xem xét lớp tệp hệ thống mà chỉ máy chủ hệ thống mới được sửa đổi. Tuy nhiên, vì netd
, init
và vold
chạy dưới dạng thư mục gốc, nên các thư mục này có thể truy cập vào các tệp hệ thống đó. Vì vậy, nếu netd
bị xâm phạm, thì tệp đó có thể bị xâm phạm và có thể là chính máy chủ hệ thống.
Với SELinux, bạn có thể xác định các tệp đó là tệp dữ liệu máy chủ hệ thống.
Do đó, miền duy nhất có quyền đọc/ghi vào các tệp này là máy chủ hệ thống.
Ngay cả khi netd
bị xâm phạm, nó cũng không thể chuyển miền sang miền máy chủ hệ thống và truy cập vào các tệp hệ thống đó mặc dù chạy dưới dạng thư mục gốc.
Dữ liệu ứng dụng: Một ví dụ khác là lớp hàm phải chạy dưới dạng thư mục gốc nhưng không được truy cập vào dữ liệu ứng dụng. Điều này cực kỳ hữu ích vì bạn có thể đưa ra các xác nhận trên nhiều phạm vi, chẳng hạn như một số miền không liên quan đến dữ liệu ứng dụng bị cấm truy cập Internet.
setattr: Đối với các lệnh như chmod
và chown
, bạn có thể xác định tập hợp tệp mà miền liên kết có thể thực hiện setattr
. Mọi thứ bên ngoài phạm vi đó có thể bị cấm thực hiện những thay đổi này, ngay cả khi có quyền truy cập thư mục gốc. Vì vậy, một ứng dụng có thể chạy chmod
và chown
so với các ứng dụng được gắn nhãn app_data_files
nhưng không phải shell_data_files
hoặc system_data_files
.