Android 10, çekirdek kilitlenmelerini yakalamak ve azaltmak için tasarlanmış Android Live-LocK Daemon'u (
llkd ) içerir.
llkd bileşeni varsayılan bağımsız bir uygulama sağlar, ancak alternatif olarak
llkd kodunu ana döngünün bir parçası olarak veya ayrı bir iş parçacığı olarak başka bir hizmete entegre edebilirsiniz.
Algılama senaryoları
llkd iki algılama senaryosu vardır: Kalıcı D veya Z durumu ve kalıcı yığın imzası.
Kalıcı D veya Z durumu
Bir iş parçacığı D (kesintisiz uyku) veya Z (zombi) durumundaysa ve
ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms daha uzun bir süre ilerlemezse,
llkd işlemi (veya ana işlemi) öldürür ). Sonraki bir tarama aynı işlemin devam ettiğini gösterirse,
llkd bir canlı kilit koşulunu onaylar ve durum için en ayrıntılı hata raporunu sağlayacak şekilde çekirdeği panikler.
llkd ,
llkd kilitlenirse alarm veren bir kendi kendine bekçi köpeği içerir; watchdog, ana döngüden geçmesi beklenen sürenin iki katıdır ve örnekleme her
ro.llk_sample_ms .
Kalıcı yığın imzası
Kullanıcı hata ayıklama sürümleri için,
llkd , kalıcı yığın imza denetimi kullanarak çekirdek canlı kilitlerini algılayabilir. Z dışında herhangi bir durumdaki bir iş parçacığı,
ro.llk.timeout_ms veya
ro.llk.stack.timeout_ms daha uzun süre boyunca bildirilen kalıcı bir
ro.llk.stack çekirdek sembolüne sahipse,
llkd işlemi durdurur (ileri planlama ilerlemesi). Sonraki bir tarama aynı işlemin devam ettiğini gösterirse,
llkd bir canlı kilit koşulunu onaylar ve durum için en ayrıntılı hata raporunu sağlayacak şekilde çekirdeği panikler.
lldk denetimi, canlı kilit koşulu mevcut olduğunda sürekli olarak devam eder ve Linux'ta
/proc/pid/stack dosyasında oluşan
" symbol+0x" veya
" symbol.cfi+0x" dizelerini arar. Sembol listesi
ro.llk.stack ve varsayılan olarak virgülle ayrılmış "
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable " listesine göredir.
Semboller, tipik bir sistemde işlevin
ro.llk.stack.timeout_ms zaman aşımı süresi boyunca bir örnekte yalnızca bir kez görülebileceği kadar nadir ve kısa ömürlü olmalıdır (örnekler her
ro.llk.check_ms gerçekleşir). ABA korumasının olmaması nedeniyle, yanlış bir tetikleyiciyi önlemenin tek yolu budur. Sembol işlevi, çakışabilecek kilidi çağıran işlevin altında görünmelidir. Kilit, sembol işlevinin altında veya içindeyse, yalnızca kilitlenmeye neden olan işlemde değil, etkilenen tüm işlemlerde sembol görünür.
Kapsam
llkd varsayılan uygulaması
init ,
[kthreadd] veya
[kthreadd] .
llkd
[kthreadd] - ortaya çıkan konuları kapsaması için:
- Sürücüler kalıcı bir D durumunda kalmamalıdır,
VEYA
- Sürücüler, harici olarak öldürülmesi durumunda iş parçacığını kurtarmak için mekanizmalara sahip olmalıdır. Örneğin,
wait_event_interruptible()yerine
wait_event()() kullanın.
Yukarıdaki koşullardan biri karşılanırsa,
llkd kara listesi çekirdek bileşenlerini kapsayacak şekilde ayarlanabilir. Yığın sembolü denetimi,
ptrace işlemlerini engelleyen hizmetlerde sepolicy ihlallerini önlemek için ek bir işlem kara listesi içerir.
Android özellikleri
llkd , birkaç Android özelliğine yanıt verir (aşağıda listelenmiştir).
-
prop_msadlı özellikler milisaniye cinsindendir.
- Listeler için virgül (,) ayırıcı kullanan özellikler, varsayılan girişi korumak için önde gelen bir ayırıcı kullanır, ardından sırasıyla isteğe bağlı artı (+) ve eksi (-) önekleriyle girişleri ekler veya çıkarır. Bu listeler için, "false" dizgisi boş bir liste ile eş anlamlıdır ve boş veya eksik girişler, belirtilen varsayılan değere başvurur.
ro.config.low_ram
Cihaz sınırlı bellekle yapılandırılmış.
ro.hata ayıklanabilir
Cihaz, userdebug veya eng build için yapılandırıldı.
ro.llk.sysrq_t
Özellik "eng" ise, varsayılan
ro.config.low_ram veya
ro.debuggable değildir. Doğruysa, tüm konuları boşaltın (
sysrq t ).
ro.llk.etkinleştir
Canlı kilit arka plan programının etkinleştirilmesine izin verin. Varsayılan yanlıştır.
llk.enable
Eng derlemeleri için değerlendirildi. Varsayılan,
ro.llk.enable .
ro.khungtask.enable
[khungtask] arka plan programının etkinleştirilmesine izin verin. Varsayılan yanlıştır.
khungtask.enable
Eng derlemeleri için değerlendirildi. Varsayılan,
ro.khungtask.enable .
ro.llk.mlockall
mlockall() çağrısını etkinleştirin. Varsayılan yanlıştır.
ro.khungtask.zaman aşımı
[khungtask] maksimum zaman sınırı. Varsayılan 12 dakikadır.
ro.llk.timeout_ms
D veya Z maksimum zaman sınırı. Varsayılan 10 dakikadır.
llkd için alarm bekçisini ayarlamak için bu değeri ikiye katlayın.
ro.llk.D.timeout_ms
D maksimum zaman sınırı. Varsayılan,
ro.llk.timeout_ms .
ro.llk.Z.timeout_ms
Z maksimum zaman sınırı. Varsayılan,
ro.llk.timeout_ms .
ro.llk.stack.timeout_ms
Kalıcı yığın sembolleri maksimum zaman sınırını kontrol eder. Varsayılan,
ro.llk.timeout_ms . Yalnızca userdebug veya eng buildlerinde etkindir .
ro.llk.check_ms
D veya Z için iş parçacığı örnekleri. Varsayılan iki dakikadır.
ro.llk.yığın
Sürekli olarak mevcutsa, bir alt sistemin kilitli olduğunu gösterebilecek çekirdek yığını sembollerini kontrol eder. Varsayılan,
cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable virgülle ayrılmış çekirdek sembolleri listesidir. Kontrol, ro.llk.stack.timeout_ms periyodu boyunca her
ro.llk_check_ms yoklama dışında, ABA programlamasını ileriye
ro.llk.stack.timeout_ms , bu nedenle yığın sembolleri son derece nadir ve geçici olmalıdır (bir sembolün tümünde kalıcı olarak görünmesi pek olası değildir). yığın örnekleri). Yığın genişletmede
" symbol+0x" veya
" symbol.cfi+0x" için eşleşme olup olmadığını kontrol eder. Yalnızca userdebug veya eng yapılarında kullanılabilir ; kullanıcı yapılarındaki güvenlik endişeleri, bu kontrolü engelleyen sınırlı ayrıcalıklarla sonuçlanır.
ro.llk.kara liste.işlem
llkd belirtilen işlemleri izlemez. Varsayılan
0,1,2 (
kernel ,
init ve
[kthreadd] ) artı işlem adları
init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1] . Bir işlem bir
comm ,
cmdline veya
pid referansı olabilir. Otomatik bir varsayılan, mevcut maksimum özellik boyutu olan 92'den daha büyük olabilir.
ro.llk.kara liste.ebeveyn
llkd , belirtilen ebeveyn(ler)e sahip işlemleri izlemez. Varsayılan
0,2,adbd&[setsid] 'dir (
kernel ,
[kthreadd]
setsid
adbd yalnızca zombi setleri için). Bir ve işareti (&) ayırıcısı, üst öğenin yalnızca hedef alt süreçle birlikte yoksayıldığını belirtir. Ve işareti hiçbir zaman bir işlem adının parçası olmadığı için seçilmiştir; bununla birlikte, kabuktaki bir
setprop , ve işaretinin kaçmasını veya alıntılanmasını gerektirir, ancak bunun normalde belirtildiği
init rc dosyasında bu sorun yoktur. Bir ebeveyn veya hedef süreç bir
comm ,
cmdline veya
pid referansı olabilir.
ro.llk.kara liste.uid
llkd , belirtilen kullanıcı kimlikleri ile eşleşen işlemleri izlemez. Kullanıcı kimliği numaraları veya adlarının virgülle ayrılmış listesi. Varsayılan boş veya yanlıştır.
ro.llk.blacklist.process.stack
llkd , canlı kilit yığın imzaları için belirtilen işlem alt kümesini izlemez. Varsayılan süreç isimleri
init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd . Ptrace'i engelleyen işlemlerle ilişkili
ptrace ihlalini önler (bunlar kontrol edilemediğinden). Yalnızca userdebug ve eng buildlerinde etkindir . Yapı türleriyle ilgili ayrıntılar için, Android Oluşturma bölümüne bakın.
Mimari kaygılar
- Özellikler 92 karakterle sınırlıdır (ancak kaynaklarda
include/llkd.hdosyasında tanımlanan varsayılanlar için bu yok sayılır).
-
[khungtask]arka plan programı çok genel ve D durumunda çok fazla oturan sürücü kodunda geziniyor. S'ye geçmek, görev(ler)i öldürebilir (ve gerekirse sürücüler tarafından yeniden diriltilebilir) yapar.
Kütüphane arayüzü (isteğe bağlı)
libllkd bileşeninden aşağıdaki C arabirimini kullanarak isteğe bağlı olarak
llkd başka bir ayrıcalıklı arka plan programına dahil edebilirsiniz:
#include "llkd.h" bool llkInit(const char* threadname) /* return true if enabled */ unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
Bir iş parçacığı adı sağlanmışsa, bir iş parçacığı otomatik olarak ortaya çıkar, aksi takdirde arayan kişinin ana döngüsünde
llkCheckMilliseconds gerekir. İşlev, bu işleyiciye bir sonraki beklenen çağrıdan önceki süreyi döndürür.