Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Android Live-LocK Daemon (llkd)

Android 10 termasuk Android Live-Lock Daemon ( llkd ), yang dirancang untuk menangkap dan mengurangi kernel kebuntuan. The llkd komponen menyediakan implementasi standar mandiri, tetapi Anda dapat alternatif mengintegrasikan llkd kode ke layanan lain, baik sebagai bagian dari lingkaran utama atau sebagai thread terpisah.

Skenario deteksi

The llkd memiliki dua skenario deteksi: Persistent D atau negara Z, dan tanda tangan tumpukan persisten.

Status D atau Z yang persisten

Jika sebuah thread di D (uninterruptible tidur) atau Z (zombie) negara dengan tidak ada kemajuan ke depan selama lebih dari ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms , yang llkd membunuh proses (atau proses induk ). Jika scan menunjukkan selanjutnya proses yang sama terus ada, llkd menegaskan kondisi hidup-lock dan panik kernel dengan cara yang memberikan laporan bug yang paling rinci untuk kondisi tersebut.

The llkd termasuk pengawas diri yang alarm jika llkd terkunci; pengawas adalah ganda waktu yang diharapkan mengalir melalui mainloop dan sampling setiap ro.llk_sample_ms .

Tanda tangan tumpukan persisten

Untuk rilis userdebug, yang llkd dapat mendeteksi kernel live-kunci menggunakan persistent memeriksa tumpukan tanda tangan. Jika thread di setiap negara kecuali Z memiliki gigih terdaftar ro.llk.stack simbol kernel yang dilaporkan selama lebih dari ro.llk.timeout_ms atau ro.llk.stack.timeout_ms , yang llkd membunuh proses (bahkan jika ada maju kemajuan penjadwalan). Jika scan menunjukkan selanjutnya proses yang sama terus ada, llkd menegaskan kondisi hidup-lock dan panik kernel dengan cara yang memberikan laporan bug yang paling rinci untuk kondisi tersebut.

The lldk cek tetap berlangsung terus menerus saat kondisi kunci hidup ada dan terlihat untuk string terdiri " symbol+0x" atau " symbol.cfi+0x" di /proc/pid/stack file di Linux. Daftar simbol dalam ro.llk.stack dan default ke daftar dipisahkan koma " cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable ".

Simbol harus langka dan berumur pendek cukup bahwa pada sistem yang khas fungsi terlihat hanya sekali dalam sampel selama periode batas waktu ro.llk.stack.timeout_ms (sampel terjadi 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.

Cakupan

Implementasi standar dari llkd tidak memonitor init , [kthreadd] , atau [kthreadd] menumbuhkan. Untuk llkd untuk penutup [kthreadd] benang -spawned:

  • Pengemudi tidak boleh tetap dalam status D yang persisten,

ATAU

  • Pengemudi harus memiliki mekanisme untuk memulihkan utas jika dimatikan secara eksternal. Sebagai contoh, penggunaan wait_event_interruptible() bukan wait_event() .

Jika salah satu kondisi di atas terpenuhi, llkd blacklist bisa disesuaikan dengan komponen penutup kernel. Stack memeriksa simbol melibatkan proses blacklist tambahan untuk mencegah pelanggaran sepolicy pada layanan yang blok ptrace operasi.

properti Android

The llkd merespon untuk beberapa properti Android (tercantum di bawah).

  • Properti bernama prop_ms berada di 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 properti adalah "eng", default tidak ro.config.low_ram atau ro.debuggable . Jika benar, dump semua thread ( sysrq t ).

ro.llk.enable

Izinkan daemon kunci langsung diaktifkan. Standarnya salah.

llk.enable

Dievaluasi untuk eng build. Default adalah ro.llk.enable .

ro.khungtask.enable

Memungkinkan [khungtask] daemon diaktifkan. Standarnya salah.

khungtask.enable

Dievaluasi untuk eng build. Default adalah ro.khungtask.enable .

ro.llk.mlockall

Aktifkan panggilan untuk mlockall() . Standarnya salah.

ro.khungtask.timeout

[khungtask] maksimum batas waktu. Standarnya adalah 12 menit.

ro.llk.timeout_ms

Batas waktu maksimum D atau Z. Standarnya adalah 10 menit. Dua kali lipat nilai ini untuk mengatur pengawas alarm untuk llkd .

ro.llk.D.timeout_ms

D. Batas waktu maksimum. Default adalah ro.llk.timeout_ms .

ro.llk.Z.timeout_ms

Z batas waktu maksimum. Default adalah ro.llk.timeout_ms .

ro.llk.stack.timeout_ms

Memeriksa batas waktu maksimum simbol tumpukan persisten. Default adalah ro.llk.timeout_ms . Aktif hanya pada userdebug atau eng membangun.

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. Default adalah cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable daftar dipisahkan koma simbol kernel. Cek tidak melakukan maju penjadwalan ABA kecuali dengan pemungutan suara setiap ro.llk_check_ms selama periode ro.llk.stack.timeout_ms , sehingga simbol tumpukan harus sangat langka dan sekilas (sangat tidak mungkin untuk simbol muncul terus menerus di semua sampel tumpukan). Cek untuk pertandingan untuk " symbol+0x" atau " symbol.cfi+0x" dalam ekspansi stack. Tersedia hanya pada userdebug atau eng membangun; masalah keamanan pada build pengguna mengakibatkan hak istimewa terbatas yang mencegah pemeriksaan ini.

ro.llk.blacklist.process

The llkd tidak menonton proses ditentukan. Default adalah 0,1,2 ( kernel , init , dan [kthreadd] ) ditambah nama proses init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1] . Sebuah proses dapat menjadi comm , cmdline , atau pid referensi. Default otomatis bisa lebih besar dari ukuran properti maksimum saat ini sebesar 92.

ro.llk.blacklist.parent

The llkd tidak menonton proses yang memiliki orang tua yang ditentukan (s). Default 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, sebuah setprop di shell membutuhkan ampersand akan melarikan diri atau dikutip, meskipun init rc file di mana ini biasanya ditentukan tidak memiliki masalah ini. Sebuah proses induk atau target bisa menjadi comm , cmdline , atau pid referensi.

ro.llk.blacklist.uid

The llkd tidak menonton proses yang cocok dengan yang ditentukan uid (s). Daftar nomor atau nama uid yang dipisahkan koma. Defaultnya kosong atau salah.

ro.llk.blacklist.process.stack

The llkd tidak memonitor bagian tertentu dari proses untuk tanda tangan tumpukan kunci hidup. Default adalah nama proses init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd . Mencegah pelanggaran sepolicy terkait dengan proses yang blok ptrace (karena ini tidak dapat diperiksa). Aktif hanya pada userdebug dan eng membangun. Untuk rincian tentang jenis build, lihat Building Android .

Masalah arsitektur

  • Sifat terbatas untuk 92 karakter (Namun, hal ini diabaikan untuk default didefinisikan dalam include/llkd.h file dalam sumber).
  • Built-in [khungtask] daemon terlalu generik dan perjalanan di kode driver yang duduk di dalam negara D terlalu banyak. Beralih ke S akan membuat tugas dapat dimatikan (dan dapat dihidupkan kembali oleh driver jika diperlukan).

Antarmuka perpustakaan (opsional)

Anda dapat menggabungkan llkd ke daemon istimewa lain menggunakan antarmuka C berikut dari libllkd komponen:

#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void)   /* ms to sleep for next check */

Jika threadname disediakan, benang otomatis menumbuhkan, jika si penelepon harus memanggil llkCheckMilliseconds dalam lingkaran utama. Fungsi mengembalikan periode waktu sebelum panggilan yang diharapkan berikutnya ke handler ini.