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()
yerinewait_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_ms
adlı ö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.h
dosyası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.