Android 10 menyertakan Android Live-LocK Daemon ( llkd
), yang dirancang untuk menangkap dan mengurangi kebuntuan kernel. Komponen llkd
menyediakan implementasi mandiri default, tetapi Anda juga dapat mengintegrasikan kode llkd
ke layanan lain, baik sebagai bagian dari loop utama atau sebagai utas terpisah.
Skenario deteksi
llkd
memiliki dua skenario deteksi: status D atau Z yang persisten, dan tanda tangan tumpukan yang persisten.
Status D atau Z yang persisten
Jika utas dalam status D (tidur tidak terputus) atau Z (zombie) tanpa kemajuan maju lebih lama dari ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms
, llkd
mematikan proses (atau proses induk ). Jika pemindaian berikutnya menunjukkan proses yang sama terus ada, llkd
mengonfirmasi kondisi penguncian langsung dan membuat panik kernel dengan cara yang memberikan laporan bug paling rinci untuk kondisi tersebut.
llkd
termasuk pengawas diri yang memberi alarm jika llkd
terkunci; watchdog menggandakan waktu yang diharapkan untuk mengalir melalui mainloop dan pengambilan sampel adalah setiap ro.llk_sample_ms
.
Tanda tangan tumpukan persisten
Untuk rilis debug pengguna, llkd
dapat mendeteksi penguncian langsung kernel menggunakan pemeriksaan tanda tangan tumpukan persisten. Jika sebuah utas dalam status apa pun kecuali Z memiliki simbol kernel ro.llk.stack
terdaftar yang terus-menerus yang dilaporkan lebih lama dari ro.llk.timeout_ms
atau ro.llk.stack.timeout_ms
, llkd
mematikan proses (bahkan jika ada penerusan kemajuan penjadwalan). Jika pemindaian berikutnya menunjukkan proses yang sama terus ada, llkd
mengonfirmasi kondisi penguncian langsung dan membuat panik kernel dengan cara yang memberikan laporan bug paling rinci untuk kondisi tersebut.
Pemeriksaan lldk
berlanjut terus menerus ketika kondisi kunci langsung ada dan mencari string yang disusun " symbol+0x"
atau " symbol.cfi+0x"
di file /proc/pid/stack
di Linux. Daftar simbol ada di ro.llk.stack
dan default ke daftar yang dipisahkan koma dari " cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
".
Simbol harus langka dan berumur pendek sehingga pada sistem tipikal fungsi hanya terlihat sekali dalam sampel selama periode waktu habis ro.llk.stack.timeout_ms
(sampel muncul setiap ro.llk.check_ms
). Karena kurangnya perlindungan ABA, ini adalah satu-satunya cara untuk mencegah pemicu palsu. Fungsi simbol harus muncul di bawah fungsi yang memanggil kunci yang dapat bersaing. Jika kunci berada di bawah atau dalam fungsi simbol, simbol akan muncul di semua proses yang terpengaruh, bukan hanya proses yang menyebabkan penguncian.
liputan
Implementasi default llkd
tidak memonitor init
, [kthreadd]
, atau [kthreadd]
memunculkan. Untuk llkd
untuk menutupi [kthreadd]
-spawned threads:
- Pengemudi tidak boleh tetap dalam status D yang persisten,
ATAU
- Pengemudi harus memiliki mekanisme untuk memulihkan utas jika dimatikan secara eksternal. Misalnya, gunakan
wait_event_interruptible()
alih-alihwait_event()
.
Jika salah satu kondisi di atas terpenuhi, daftar hitam llkd
dapat disesuaikan untuk mencakup komponen kernel. Pemeriksaan simbol tumpukan melibatkan daftar hitam proses tambahan untuk mencegah pelanggaran kebijakan pada layanan yang memblokir operasi ptrace
.
properti Android
llkd
merespons beberapa properti Android (tercantum di bawah).
- Properti bernama
prop_ms
dalam milidetik. - Properti yang menggunakan pemisah koma (,) untuk daftar menggunakan pemisah awal untuk mempertahankan entri default, lalu menambah atau mengurangi entri dengan prefiks plus (+) dan minus (-) opsional masing-masing. Untuk daftar ini, string "false" identik dengan daftar kosong, dan entri kosong atau hilang menggunakan nilai default yang ditentukan.
ro.config.low_ram
Perangkat dikonfigurasi dengan memori terbatas.
ro.debuggable
Perangkat dikonfigurasi untuk userdebug atau eng build.
ro.llk.sysrq_t
Jika propertinya adalah "eng", defaultnya bukan ro.config.low_ram
atau ro.debuggable
. Jika benar, buang semua utas ( sysrq t
).
ro.llk.enable
Izinkan daemon kunci langsung diaktifkan. Standarnya salah.
llk.enable
Dievaluasi untuk eng build. Standarnya adalah ro.llk.enable
.
ro.khungtask.enable
Izinkan daemon [khungtask]
diaktifkan. Standarnya salah.
khungtask.enable
Dievaluasi untuk eng build. Standarnya adalah ro.khungtask.enable
.
ro.llk.mlockall
Aktifkan panggilan ke mlockall()
. Standarnya salah.
ro.khungtask.timeout
[khungtask]
batas waktu maksimum. Standarnya adalah 12 menit.
ro.llk.timeout_ms
D atau Z batas waktu maksimum. Standarnya adalah 10 menit. Gandakan nilai ini untuk menyetel pengawas alarm untuk llkd
.
ro.llk.D.timeout_ms
D batas waktu maksimum. Standarnya adalah ro.llk.timeout_ms
.
ro.llk.Z.timeout_ms
Z batas waktu maksimum. Standarnya adalah ro.llk.timeout_ms
.
ro.llk.stack.timeout_ms
Memeriksa batas waktu maksimum simbol tumpukan persisten. Standarnya adalah ro.llk.timeout_ms
. Aktif hanya pada userdebug atau eng build .
ro.llk.check_ms
Contoh utas untuk D atau Z. Standarnya adalah dua menit.
ro.llk.stack
Memeriksa simbol tumpukan kernel yang jika terus ada dapat menunjukkan subsistem terkunci. Standarnya adalah cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
daftar simbol kernel yang dipisahkan koma. Pemeriksaan tidak melakukan penjadwalan maju ABA kecuali dengan polling setiap ro.llk_check_ms
selama periode ro.llk.stack.timeout_ms
, jadi simbol tumpukan harus sangat langka dan cepat berlalu (sangat tidak mungkin simbol muncul terus-menerus di semua sampel tumpukan). Memeriksa kecocokan untuk " symbol+0x"
atau " symbol.cfi+0x"
dalam ekspansi tumpukan. Hanya tersedia di userdebug atau eng build ; masalah keamanan pada build pengguna mengakibatkan hak istimewa terbatas yang mencegah pemeriksaan ini.
ro.llk.blacklist.process
llkd
tidak melihat proses yang ditentukan. Standarnya adalah 0,1,2
( kernel
, init
, dan [kthreadd]
) ditambah nama proses init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1]
. Suatu proses dapat berupa referensi comm
, cmdline
, atau pid
. Default otomatis dapat lebih besar dari ukuran properti maksimum saat ini sebesar 92.
ro.llk.blacklist.parent
llkd
tidak melihat proses yang memiliki induk yang ditentukan. Standarnya adalah 0,2,adbd&[setsid]
( kernel
, [kthreadd]
, dan adbd
hanya untuk zombie setsid
). Pemisah ampersand (&) menetapkan bahwa induk diabaikan hanya dalam kombinasi dengan proses anak target. Ampersand dipilih karena tidak pernah menjadi bagian dari nama proses; namun, setprop
di shell memerlukan ampersand untuk diloloskan atau dikutip, meskipun file init rc
di mana ini biasanya ditentukan tidak memiliki masalah ini. Proses induk atau target dapat berupa referensi comm
, cmdline
, atau pid
.
ro.llk.blacklist.uid
llkd
tidak melihat proses yang cocok dengan uid yang ditentukan. Daftar nomor atau nama uid yang dipisahkan koma. Defaultnya kosong atau salah.
ro.llk.blacklist.process.stack
llkd
tidak memantau subset proses yang ditentukan untuk tanda tangan tumpukan kunci langsung. Defaultnya adalah nama proses init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
. Mencegah pelanggaran kebijakan yang terkait dengan proses yang memblokir ptrace
(karena ini tidak dapat diperiksa). Aktif hanya pada userdebug dan eng build . Untuk detail tentang tipe build, lihat Membangun Android .
Masalah arsitektur
- Properti dibatasi hingga 92 karakter (namun, ini diabaikan untuk default yang ditentukan dalam file
include/llkd.h
di sources). - Daemon
[khungtask]
terlalu umum dan tersandung pada kode driver yang berada dalam status D terlalu banyak. Beralih ke S akan membuat tugas dapat dimatikan (dan dapat dihidupkan kembali oleh driver jika diperlukan).
Antarmuka perpustakaan (opsional)
Anda dapat secara opsional memasukkan llkd
ke daemon istimewa lainnya menggunakan antarmuka C berikut dari komponen libllkd
:
#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
Jika nama utas diberikan, utas secara otomatis muncul, jika tidak, pemanggil harus memanggil llkCheckMilliseconds
di loop utamanya. Fungsi mengembalikan periode waktu sebelum panggilan yang diharapkan berikutnya ke handler ini.