Android 10 zawiera demona aktywnej blokady Androida
(llkd
), która służy do wychwytywania i ograniczania wzajemnych blokad jądra. llkd
udostępnia domyślną, samodzielną implementację, ale możesz
możesz też zintegrować kod llkd
z inną usługą, jako część
w ramach pętli głównej lub osobnego wątku.
Scenariusze wykrywania
llkd
ma 2 scenariusze wykrywania: stały D lub stan Z oraz trwały
podpis stosu.
Stały stan D lub Z
Jeśli wątek jest w stanie D (uśpienie niezakłócone) lub Z (zombie) bez przekierowania
postęp w czasie dłuższym niż ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms
,
llkd
kończy proces (lub proces nadrzędny). Jeśli podczas kolejnego skanowania zobaczysz
nadal trwa ten sam proces, llkd
potwierdza warunek blokady transmisji na żywo, a następnie
panuje w jądrze w sposób, który dostarcza najdokładniejszego raportu o błędach
.
Urządzenie llkd
zawiera własny watchdog, który alarmuje, gdy llkd
się blokuje. watchdog to
dwukrotnie wydłuża spodziewany czas przepływania przez pętlę główną, a próbkowanie
ro.llk_sample_ms
Podpis trwałego stosu
W przypadku wersji do debugowania użytkownika llkd
może wykrywać blokady aktywnego jądra systemu za pomocą trwałych
na stosie kont. Jeśli wątek w dowolnym stanie innym niż Z ma trwały
został podany symbol jądra systemu ro.llk.stack
, który jest zgłaszany od okresu dłuższego niż
ro.llk.timeout_ms
lub ro.llk.stack.timeout_ms
, llkd
eliminuje proces
(nawet jeśli trwa planowanie do przodu). Jeśli podczas kolejnego skanowania zobaczysz
nadal trwa ten sam proces, llkd
potwierdza warunek blokady transmisji na żywo, a następnie
panuje w jądrze w sposób, który dostarcza najdokładniejszego raportu o błędach
.
Kontrola lldk
jest kontynuowana bez przerwy, gdy istnieje warunek aktywnej blokady.
wyszukuje utworzone ciągi znaków symbol+0x
lub symbol.cfi+0x
w funkcji
/proc/pid/stack
w systemie Linux. Lista symboli znajduje się w językach: ro.llk.stack
i
domyślnie przyjmuje wartość rozdzielaną przecinkami listę
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
Symbole powinny być rzadkie i wystarczająco krótkie, aby w typowym systemie
jest występująca tylko raz w próbce po upływie limitu czasu wynoszącego
ro.llk.stack.timeout_ms
(próbki pojawiają się co ro.llk.check_ms
). Z powodu braku
ochrony ABA, to jedyny sposób zapobiegania błędnemu wywołaniu. Symbol
musi być widoczna pod funkcją wywołującą blokadę, która może konkurować. Jeśli
kłódka znajduje się poniżej lub w funkcji symboli, symbol jest widoczny we wszystkich odpowiednich
z procesów, a nie tylko tych, które doprowadziły do powstania układu.
Pokrycie
Domyślna implementacja llkd
nie monitoruje init
, [kthreadd]
ani
Pojawia się [kthreadd]
. Aby element llkd
obejmował [kthreadd]
wątków utworzonych przez użytkownika:
- Sterowniki nie mogą pozostawać w trwałym stanie D.
LUB
- Sterowniki muszą mieć mechanizmy umożliwiające odzyskanie wątku w przypadku jego utracenia
na zewnątrz. Na przykład użyj
wait_event_interruptible()
zamiastwait_event()
Jeśli spełniony jest jeden z powyższych warunków, listę odrzuconych llkd
można dostosować do:
i uwzględniają komponenty jądra. Sprawdzanie symbolu stosu wiąże się z dodatkowym procesem
lista odrzuconych, aby zapobiec naruszeniom zasad w usługach, które blokują ptrace
operacji.
Usługi na Androida
llkd
działa w przypadku kilku usług na Androidzie (wymienionych poniżej).
- Właściwości o nazwie
prop_ms
są podane w milisekundach. - Właściwości, które używają separatora przecinka (,) w przypadku list, używają separatora wiodącego, aby
zachowaj domyślną pozycję, a następnie dodaj lub odejmij wpisy z opcjonalnym plusem
prefiksy (+) i minus (-). W przypadku tych list ciąg
false
jest synonimem pustej listy, a puste lub brakujące wpisy odwołują się do określoną wartość domyślną.
ro.config.low_ram
Urządzenie jest skonfigurowane z ograniczoną pamięcią.
ro.debuggable
Urządzenie jest skonfigurowane na potrzeby debugowania użytkowników lub kompilacji angielskiej.
ro.llk.sysrq_t,
Jeśli właściwość to eng
, wartość domyślna nie jest wartością ro.config.low_ram
ani ro.debuggable
.
Jeśli zasada true
, powoduje wykonanie zrzutu wszystkich wątków (sysrq t
).
ro.llk.enable
Zezwól na włączanie demona aktywnej blokady. Domyślna wartość to false
.
llk.enable
Oceniane pod kątem kompilacji rozszerzonych. Domyślna wartość to ro.llk.enable
.
ro.khungtask.enable
Zezwalaj na włączanie demona [khungtask]
. Wartość domyślna to false
.
khungtask.enable
Oceniane pod kątem kompilacji rozszerzonych. Domyślna wartość to ro.khungtask.enable
.
ro.llk.mlockall
Włącz połączenie z numerem mlockall()
. Wartość domyślna to false
.
ro.khungtask.timeout
Maksymalny limit czasu: [khungtask]
. Wartość domyślna to 12 minut.
ro.llk.timeout_ms
Maksymalny limit czasu D lub Z. Wartość domyślna to 10 minut. Podwój tę wartość, aby ustawić
watchdoga alarmu na llkd
.
ro.llk.D.timeout_ms
Maksymalny limit czasu D. Domyślna wartość to ro.llk.timeout_ms
.
ro.llk.Z.timeout_ms
Maksymalny limit czasu Z. Domyślna wartość to ro.llk.timeout_ms
.
ro.llk.stack.timeout_ms,
Sprawdza maksymalny limit czasu symboli trwałego stosu. Wartość domyślna to
ro.llk.timeout_ms
Aktywna tylko w przypadku debugowania użytkowników i kompilacji angielskich.
ro.llk.check_ms
Przykłady wątków dla D lub Z. Wartość domyślna to 2 minuty.
ro.llk.stack,
Sprawdza, czy występują symbole stosu jądra, które jeśli są stale obecne, mogą wskazywać
podsystem jest zablokowany. Wartość domyślna to
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
rozdzielana przecinkami lista symboli jądra. Sprawdzenie nie powoduje skierowania do przodu
ABA z wyjątkiem sondy co ro.llk_check_ms
w danym okresie
ro.llk.stack.timeout_ms
, dlatego symbole stosu powinny być wyjątkowo rzadkie,
przelotne (jest mało prawdopodobne, aby symbol był stale widoczny w całym miejscu)
przykłady stosu). Sprawdza, czy symbol+0x
pasuje do dopasowania lub
symbol.cfi+0x
w rozwinięciu stosu. Dostępne tylko w przypadku debugowania użytkownika lub instrukcji
kompilacje; obawy związane z zabezpieczeniami kompilacji użytkownika skutkują ograniczonymi uprawnieniami,
zapobiec tej kontroli.
ro.llk.blacklist.process,
llkd
nie obserwuje określonych procesów. Wartość domyślna to 0,1,2
(kernel
,
init
i [kthreadd]
) oraz nazwy procesów
init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1]
.
Proces może być odwołaniem do comm
, cmdline
lub pid
. Automatyczna wartość domyślna
może być większy niż bieżący maksymalny rozmiar usługi wynoszący 92.
ro.llk.blacklist.parent,
llkd
nie obserwuje procesów, w których są określone elementy nadrzędne. Domyślne
to 0,2,adbd&[setsid]
(kernel
, [kthreadd]
i adbd
tylko dla zombie
setsid
). Separator „&” oznacza, że element nadrzędny jest tylko ignorowany
w połączeniu z docelowym procesem podrzędnym. Wybrano znak „ampersand”, ponieważ
nie jest nigdy częścią nazwy procesu; jednak setprop
w powłoce wymaga
ampersand, w którym ma być cudzysłowy lub cudzysłowu, ale w przypadku pliku init rc
, w którym
zwykle nie występuje. Proces nadrzędny lub docelowy może być
Odwołanie do: comm
, cmdline
lub pid
.
ro.llk.blacklist.uid,
llkd
nie obserwuje procesów pasujących do określonych identyfikatorów UID.
Lista rozdzielonych przecinkami numerów lub nazw UIS. Wartość domyślna jest pusta lub false
.
ro.llk.blacklist.process.stack,
llkd
nie monitoruje określonego podzbioru procesów na potrzeby bieżącego stosu blokady
podpisy. Domyślnie są to nazwy procesów
init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
Zapobiega sepolicy
naruszenie związane z procesami, które blokują ptrace
(ponieważ nie można ich
zaznaczono). Aktywna tylko w przypadku debugowania użytkowników i kompilacji angielskich. Szczegółowe informacje o kompilacji
można znaleźć w artykule o tworzeniu Androida.
Kwestie architektoniczne
- Właściwości mogą mieć maksymalnie 92 znaki (ale w przypadku wartości domyślnych są ignorowane).
zdefiniowane w pliku
include/llkd.h
w źródłach). - Wbudowany demon
[khungtask]
jest zbyt ogólny i korzysta z kodu kierowcy, który i za często są w stanie D. Przejście na S uniemożliwiłoby zakończenie zadań (w razie potrzeby być wznowiony przez kierowcę).
Interfejs biblioteki (opcjonalnie)
Opcjonalnie możesz włączyć llkd
do innego demona z podwyższonymi uprawnieniami, posługując się
ten interfejs C z komponentu libllkd
:
#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
Jeśli zostanie podana nazwa wątku, automatycznie pojawi się wątek. W przeciwnym razie obiekt wywołujący
musi wywołać funkcję llkCheckMilliseconds
w swojej głównej pętli. Funkcja zwraca
okres przed kolejnym spodziewanym wywołaniem tego modułu obsługi.