Android 10 có trình nền Android-lock
(llkd
), được thiết kế để phát hiện và giảm thiểu tình trạng tắc nghẽn hạt nhân. llkd
thành phần này sẽ cung cấp cách triển khai độc lập mặc định, nhưng bạn có thể
ngoài ra, tích hợp mã llkd
vào một dịch vụ khác, dưới dạng một phần của
vòng lặp chính hoặc dưới dạng một luồng riêng biệt.
Các trường hợp phát hiện
llkd
có 2 tình huống phát hiện: Trạng thái D hoặc Z liên tục và liên tục
chữ ký của ngăn xếp.
Trạng thái D hoặc Z ổn định
Nếu một luồng ở trạng thái D (ngủ không gián đoạn) hoặc Z (thây ma) không chuyển tiếp
tiến trình dài hơn ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms
, thì
llkd
tắt quy trình (hoặc tiến trình mẹ). Nếu lần quét tiếp theo hiển thị
quy trình tương tự vẫn tiếp tục, llkd
sẽ xác nhận điều kiện khoá trực tiếp và
làm hoảng loạn nhân hệ điều hành theo cách cung cấp báo cáo lỗi chi tiết nhất cho
.
llkd
có một bộ đếm giờ tự giám sát sẽ báo động nếu llkd
khoá; bộ đếm giờ phòng vệ là
gấp đôi thời gian dự kiến để luồng chính qua vòng lặp chính và việc lấy mẫu là mỗi
ro.llk_sample_ms
.
Chữ ký ngăn xếp cố định
Đối với bản phát hành userdebug, llkd
có thể phát hiện khoá trực tiếp của hạt nhân bằng cách sử dụng liên tục
kiểm tra chữ ký ngăn xếp. Nếu một luồng ở bất kỳ trạng thái nào ngoại trừ Z có
được liệt kê biểu tượng hạt nhân ro.llk.stack
được báo cáo dài hơn
ro.llk.timeout_ms
hoặc ro.llk.stack.timeout_ms
, llkd
sẽ tắt quy trình
(ngay cả khi có tiến trình lên lịch chuyển tiếp). Nếu lần quét tiếp theo hiển thị
quy trình tương tự vẫn tiếp tục, llkd
sẽ xác nhận điều kiện khoá trực tiếp và
làm hoảng loạn nhân hệ điều hành theo cách cung cấp báo cáo lỗi chi tiết nhất cho
.
Quá trình kiểm tra lldk
sẽ liên tục khi có điều kiện khoá trực tiếp và
hãy tìm các chuỗi đã soạn symbol+0x
hoặc symbol.cfi+0x
trong
/proc/pid/stack
trên Linux. Danh sách các biểu tượng có trong ro.llk.stack
và
mặc định thành danh sách được phân tách bằng dấu phẩy
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
.
Các biểu tượng phải hiếm và tồn tại trong thời gian ngắn để trên một hệ thống thông thường,
chỉ được nhìn thấy một lần trong mẫu trong khoảng thời gian chờ
ro.llk.stack.timeout_ms
(lấy mẫu xảy ra mỗi ro.llk.check_ms
). Do thiếu
của tính năng bảo vệ ABA, đây là cách duy nhất để ngăn chặn trình kích hoạt giả mạo. Biểu tượng
phải xuất hiện bên dưới hàm gọi khoá có thể cạnh tranh. Nếu
khoá ở bên dưới hoặc trong hàm biểu tượng, biểu tượng sẽ xuất hiện trong tất cả các
chứ không chỉ là quá trình gây ra khoá.
Độ bao phủ
Phương thức triển khai mặc định của llkd
không giám sát init
, [kthreadd]
hoặc
[kthreadd]
sẽ xuất hiện. Để llkd
bao gồm các luồng đã được [kthreadd]
tạo:
- Trình điều khiển không được duy trì trạng thái D liên tục,
HOẶC
- Trình điều khiển phải có cơ chế khôi phục luồng nếu luồng đó bị vô hiệu hoá
bên ngoài. Ví dụ: sử dụng
wait_event_interruptible()
thay vìwait_event()
.
Nếu đáp ứng một trong các điều kiện trên, bạn có thể điều chỉnh danh sách từ chối llkd
thành
bao gồm các thành phần nhân hệ điều hành. Kiểm tra biểu tượng ngăn xếp bao gồm một quy trình bổ sung
danh sách từ chối để ngăn chặn các lỗi vi phạm sepolicy trên các dịch vụ chặn ptrace
các toán tử.
Thuộc tính Android
llkd
phản hồi một số thuộc tính Android (liệt kê dưới đây).
- Các thuộc tính có tên
prop_ms
có kích thước tính bằng mili giây. - Những tài sản sử dụng dấu phân cách (,) cho danh sách sử dụng dấu phân cách phía trước để
giữ nguyên mục nhập mặc định, sau đó cộng hoặc trừ các mục nhập bằng dấu cộng tuỳ ý
Các tiền tố (+) và trừ (-) tương ứng. Đối với các danh sách này, chuỗi
false
đồng nghĩa với danh sách trống và mục nhập trống hoặc bị thiếu cần phải giá trị mặc định được chỉ định.
ro.config.low_ram
Thiết bị được định cấu hình có bộ nhớ giới hạn.
ro.có thể gỡ lỗi
Thiết bị được định cấu hình cho bản dựng userdebug hoặc eng.
ro.llk.sysrq_t
Nếu thuộc tính là eng
, giá trị mặc định không phải là ro.config.low_ram
hoặc ro.debuggable
.
Nếu là true
, hãy kết xuất tất cả các luồng (sysrq t
).
ro.llk.enable
Cho phép bật trình nền khoá trực tiếp. Mặc định là false
.
llk.enable
Được đánh giá theo bản dựng eng. Mặc định là ro.llk.enable
.
ro.khungtask.enable
Cho phép bật trình nền [khungtask]
. Mặc định là false
.
khungtask.enable
Được đánh giá theo bản dựng eng. Mặc định là ro.khungtask.enable
.
ro.llk.mlockall
Bật lệnh gọi đến mlockall()
. Mặc định là false
.
ro.khungtask.timeout
Giới hạn thời gian tối đa là [khungtask]
. Mặc định là 12 phút.
ro.llk.timeout_ms
Giới hạn thời gian tối đa D hoặc Z. Mặc định là 10 phút. Nhân đôi giá trị này để đặt
bộ đếm giờ phòng vệ của chuông báo cho llkd
.
ro.llk.D.timeout_ms
Giới hạn thời gian tối đa của D. Mặc định là ro.llk.timeout_ms
.
ro.llk.Z.timeout_ms
Giới hạn thời gian tối đa Z. Mặc định là ro.llk.timeout_ms
.
ro.llk.stack.timeout_ms
Kiểm tra giới hạn thời gian tối đa của biểu tượng ngăn xếp cố định. Mặc định là
ro.llk.timeout_ms
. Chỉ hoạt động trên bản dựng userdebug hoặc eng.
ro.llk.check_ms
Mẫu luồng cho D hoặc Z. Mặc định là 2 phút.
ro.llk.stack
Kiểm tra các biểu tượng ngăn xếp hạt nhân mà nếu sự tồn tại liên tục có thể cho biết
hệ thống con đã bị khoá. Mặc định là
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
danh sách ký hiệu hạt nhân được phân tách bằng dấu phẩy. Bước kiểm tra này không thực hiện việc lên lịch chuyển tiếp
ABA, ngoại trừ bằng cách thăm dò ý kiến ro.llk_check_ms
một lần trong khoảng thời gian
ro.llk.stack.timeout_ms
nên biểu tượng ngăn xếp phải cực kỳ hiếm và
thoáng qua (rất khó có khả năng một biểu tượng xuất hiện liên tục trong tất cả
mẫu của ngăn xếp). Kiểm tra kết quả trùng khớp cho symbol+0x
hoặc
symbol.cfi+0x
trong ngăn xếp mở rộng. Chỉ có khi dùng userdebug hoặc eng
bản dựng; các vấn đề về bảo mật trên bản dựng của người dùng sẽ khiến đặc quyền bị hạn chế
ngăn chặn việc kiểm tra này.
ro.llk.black.process
llkd
không theo dõi các quy trình được chỉ định. Mặc định là 0,1,2
(kernel
,
init
và [kthreadd]
) cùng với tên quy trình
init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1]
.
Quy trình có thể là tham chiếu comm
, cmdline
hoặc pid
. Chế độ mặc định tự động
có thể lớn hơn kích thước tài sản tối đa hiện tại là 92.
ro.llk.black.parent
llkd
không theo dõi các quy trình có phần tử mẹ được chỉ định. Mặc định
là 0,2,adbd&[setsid]
(kernel
, [kthreadd]
và adbd
chỉ đối với thây ma
setsid
). Dấu phân cách (&) chỉ định rằng thành phần mẹ chỉ bị bỏ qua
kết hợp với quy trình con mục tiêu. Dấu "và" đã được chọn vì nó
không bao giờ là một phần của tên quy trình; tuy nhiên, setprop
trong shell yêu cầu
ký hiệu "&" để thoát hoặc được đóng dấu ngoặc kép, mặc dù tệp init rc
có chứa ký tự này
thường được chỉ định không có vấn đề này. Quá trình mẹ hoặc quá trình nhắm mục tiêu có thể là một
Tham chiếu comm
, cmdline
hoặc pid
.
ro.llk.black.uid
llkd
không theo dõi các quy trình khớp với UID được chỉ định.
Danh sách được phân tách bằng dấu phẩy gồm số hoặc tên UIS. Mặc định là trống hoặc false
.
ro.llk.black.process.stack
llkd
không giám sát tập hợp con quy trình được chỉ định đối với ngăn xếp khoá trực tiếp
chữ ký. Mặc định là tên quy trình
init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
. Ngăn chặn sepolicy
lỗi vi phạm liên quan đến các quy trình chặn ptrace
(vì những quy trình này không được
đã chọn). Chỉ hoạt động trên các bản dựng userdebug và eng. Thông tin chi tiết về bản dựng
hãy tham khảo nội dung Xây dựng Android.
Vấn đề về kiến trúc
- Thuộc tính được giới hạn trong 92 ký tự (tuy nhiên, thuộc tính này sẽ bị bỏ qua đối với giá trị mặc định
đã xác định trong tệp
include/llkd.h
trong các nguồn). - Daemon
[khungtask]
tích hợp sẵn quá chung chung và các chuyến đi trên mã trình điều khiển ngồi quá nhiều ở trạng thái D. Nếu bạn chuyển sang S sẽ khiến các nhiệm vụ có thể tắt (và tài xế có thể gọi lại nếu cần).
Giao diện thư viện (không bắt buộc)
Bạn có thể tuỳ ý kết hợp llkd
vào một trình nền đặc quyền khác bằng cách sử dụng
giao diện C sau đây từ thành phần libllkd
:
#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
Nếu tên luồng được cung cấp, thì một luồng sẽ tự động tạo, nếu không thì phương thức gọi
phải gọi llkCheckMilliseconds
trong vòng lặp chính. Hàm trả về giá trị
khoảng thời gian trước khi thực hiện lệnh gọi dự kiến tiếp theo đến trình xử lý này.