Android đặc biệt khuyến khích OEM kiểm thử hoạt động triển khai SELinux của họ một cách triệt để. Khi triển khai SELinux, nhà sản xuất phải áp dụng cho một nhóm thiết bị thử nghiệm trước.
Sau khi áp dụng chính sách mới, hãy đảm bảo SELinux đang chạy đúng
trên thiết bị bằng cách ra lệnh getenforce
.
Thao tác này sẽ in chế độ SELinux toàn cục: Thực thi hoặc Cho phép. Người nhận
cho mỗi miền, bạn phải kiểm tra chế độ SELinux tương ứng.
hoặc chạy phiên bản mới nhất của sepolicy-analyze
bằng
cờ thích hợp (-p
), hiển thị trong
/platform/system/sepolicy/tools/
.
Thông báo từ chối đọc
Kiểm tra lỗi. Các lỗi này được định tuyến dưới dạng nhật ký sự kiện đến dmesg
và logcat
và có thể xem được trên thiết bị. Nhà sản xuất
phải kiểm tra đầu ra SELinux sang dmesg
trên các thiết bị này và
tinh chỉnh chế độ cài đặt trước khi phát hành công khai ở chế độ không bắt buộc và chuyển đổi cuối cùng
sang chế độ thực thi. Thông điệp nhật ký SELinux chứa avc:
nên có thể
dễ dàng được tìm thấy nhờ grep
. Bạn có thể nắm bắt các
nhật ký từ chối bằng cách chạy cat /proc/kmsg
hoặc ghi lại nhật ký từ chối
từ lần khởi động trước bằng cách chạy
cat /sys/fs/pstore/console-ramoops
Thông báo lỗi SELinux bị giới hạn tỷ lệ sau khi khởi động xong để tránh tình trạng tràn ngập
nhật ký. Để đảm bảo bạn thấy tất cả các thông báo có liên quan, bạn có thể tắt tính năng này
bằng cách chạy adb shell auditctl -r 0
.
Với kết quả này, nhà sản xuất có thể dễ dàng xác định thời điểm người dùng hệ thống hoặc thành phần nào vi phạm chính sách SELinux. Sau đó, nhà sản xuất có thể sửa chữa hành vi xấu này, do thay đổi đối với phần mềm, chính sách SELinux hoặc cả hai.
Cụ thể, những thông điệp nhật ký này cho biết những quy trình sẽ không thành công trong chế độ thực thi và lý do. Dưới đây là ví dụ:
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
Diễn giải kết quả này như sau:
-
{ connectto }
ở trên cho thấy hành động đang được thực hiện. Cùng vớitclass
ở cuối (unix_stream_socket
), dữ liệu đó cho bạn biết sơ lược những việc đã làm về cái gì. Trong trường hợp này, đã xảy ra sự cố nào đó đang cố kết nối với một ổ cắm luồng Unix. -
scontext (u:r:shell:s0)
cho bạn biết bối cảnh nào đã khởi tạo hành động đó. Trong trong trường hợp này, đây là một thứ gì đó chạy dưới dạng shell. -
tcontext (u:r:netd:s0)
cho bạn biết bối cảnh của mục tiêu của hành động. Trong trong trường hợp này, đó là một unix_stream_socket thuộc sở hữu củanetd
. -
comm="ping"
ở trên cùng cung cấp cho bạn thêm gợi ý về những gì đang được chạy tại thời điểm tạo thông báo từ chối. Trong trường hợp này thì đây là một gợi ý khá tốt.
Ví dụ khác:
adb shell su root dmesg | grep 'avc: '
Kết quả:
<5> type=1400 audit: avc: denied { read write } for pid=177 comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 tcontext=u:object_r:kmem_device:s0 tclass=chr_file
Dưới đây là các yếu tố chính trong quyết định từ chối này:
- Hành động – hành động đã thử được đánh dấu trong dấu ngoặc đơn,
read write
hoặcsetenforce
. - Actor (Tác nhân) – Mục
scontext
(ngữ cảnh nguồn) biểu thị tác nhân, trong trường hợp này là trình nềnrmt_storage
. - Object (Đối tượng) – Mục nhập
tcontext
(ngữ cảnh mục tiêu) biểu thị đối tượng đang được tác dụng, trong trường hợp này là kmem. - Kết quả – Mục
tclass
(lớp mục tiêu) cho biết loại của đối tượng đang được thực hiện, trong trường hợp này làchr_file
(thiết bị ký tự).
Kết xuất ngăn xếp người dùng và ngăn xếp hạt nhân
Trong một số trường hợp, thông tin trong nhật ký sự kiện không đủ để xác định nguồn gốc của thông báo từ chối. Thường thì bạn nên thu thập chuỗi lệnh gọi, bao gồm cả kernel và người dùng, để hiểu rõ hơn lý do từ chối.
Các hạt nhân gần đây xác định một điểm theo dõi có tên avc:selinux_audited
. Dùng Android
simpleperf
để bật điểm theo dõi này và ghi lại chuỗi lệnh gọi.
Cấu hình được hỗ trợ
- Nhân Linux >= 5.10, cụ thể là các nhánh Hạt nhân phổ biến của Android
đường chính
và
android12 – 5.10
được hỗ trợ.
android12-5.4
nhánh cũng được hỗ trợ. Bạn có thể dùng
simpleperf
để xác định xem điểm theo dõi có đang được xác định trên thiết bị của bạn:adb root && adb shell simpleperf list | grep avc:selinux_audited
Đối với các phiên bản kernel khác, bạn có thể chọn cam kết dd81662 và 30969bc. - Có thể tái tạo sự kiện mà bạn đang gỡ lỗi. Sự kiện thời gian khởi động không được hỗ trợ sử dụng Simpleperf; tuy nhiên, bạn vẫn có thể khởi động lại dịch vụ để kích hoạt sự kiện.
Ghi lại chuỗi lệnh gọi
Bước đầu tiên là ghi lại sự kiện bằng simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
Sau đó, sự kiện dẫn đến việc từ chối sẽ được kích hoạt. Sau đó, bản ghi sẽ
bị dừng. Trong ví dụ này, bằng cách sử dụng Ctrl-c
, mẫu sẽ được thu thập:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Cuối cùng, bạn có thể dùng simpleperf report
để kiểm tra dấu vết ngăn xếp đã thu thập.
Ví dụ:
adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph" [...] Children Self Command Pid Tid Shared Object Symbol 100.00% 0.00% dmesg 3318 3318 /apex/com.android.runtime/lib64/bionic/libc.so __libc_init | -- __libc_init | -- main toybox_main toy_exec_which dmesg_main klogctl entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_syslog do_syslog selinux_syslog slow_avc_audit common_lsm_audit avc_audit_post_callback avc_audit_post_callback
Chuỗi lệnh gọi ở trên là một chuỗi lệnh gọi hạt nhân và chuỗi lệnh gọi không gian người dùng hợp nhất. Tính năng này cung cấp cho bạn
chế độ xem luồng mã bằng cách bắt đầu dấu vết từ không gian người dùng cho đến nhân hệ điều hành mà
việc từ chối xảy ra. Để biết thêm thông tin về simpleperf
, hãy xem
Tài liệu tham khảo về các lệnh có thể thực thi của Simpleperf
Đang chuyển sang quyền tự do
Bạn có thể tắt quá trình thực thi SELinux qua ADB trên các bản dựng userdebug hoặc eng. Để làm như vậy,
trước tiên, hãy chuyển ADB sang thư mục gốc bằng cách chạy adb root
. Sau đó, để vô hiệu hoá SELinux
thực thi, chạy:
adb shell setenforce 0
Hoặc tại dòng lệnh kernel (trong thời gian thiết bị xuất hiện sớm):
androidboot.selinux=permissive
androidboot.selinux=enforcing
Hoặc thông qua bootconfig trong Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
Sử dụng audit2allow
Công cụ audit2allow
nhận dmesg
từ chối và
chuyển đổi chúng thành các câu lệnh chính sách SELinux tương ứng. Như vậy, tính năng này có thể
giúp tăng tốc độ phát triển SELinux.
Để sử dụng trình tạo này, hãy chạy:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
Tuy nhiên, phải thận trọng để xem xét từng lần bổ sung tiềm năng cho
quyền truy cập quá cao. Ví dụ: cấp dữ liệu cho audit2allow
rmt_storage
từ chối được hiển thị trước đó dẫn đến kết quả sau
tuyên bố chính sách SELinux được đề xuất:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Thao tác này sẽ cấp cho rmt
khả năng ghi bộ nhớ hạt nhân, một
lỗ hổng bảo mật rõ ràng này. Thường các câu lệnh audit2allow
chỉ là
điểm xuất phát. Sau khi sử dụng các tuyên bố này, bạn có thể cần thay đổi
miền nguồn và nhãn của mục tiêu, cũng như kết hợp các
macro, để có chính sách phù hợp. Đôi khi, việc từ chối được kiểm tra nên
không dẫn đến bất kỳ thay đổi nào về chính sách; thay vì ứng dụng vi phạm
cần được thay đổi.