Android 10, çekirdek kilitlenmelerini yakalamak ve azaltmak için tasarlanmış Android Live-LocK Daemon'unu ( 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 ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms
daha uzun bir süre ileri ilerleme göstermiyorsa, llkd
işlemi (veya ana işlemi) öldürür ). Sonraki tarama aynı sürecin devam ettiğini gösterirse, llkd
bir canlı kilit koşulunu onaylar ve koşul için en ayrıntılı hata raporunu sağlayacak şekilde çekirdeği paniğe sokar.
llkd
, llkd
kilitlenmesi durumunda alarm veren bir kendi kendini izleyen 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 denetimini kullanarak çekirdek canlı kilitlerini algılayabilir. Z dışında herhangi bir durumdaki bir iş parçacığının, ro.llk.timeout_ms
veya ro.llk.stack.timeout_ms
daha uzun süre rapor edilen, kalıcı olarak listelenmiş bir ro.llk.stack
çekirdek sembolü varsa, llkd
işlemi sonlandırır (forward olsa bile) ilerlemenin planlanması). Sonraki tarama aynı sürecin devam ettiğini gösterirse, llkd
bir canlı kilit koşulunu onaylar ve koşul için en ayrıntılı hata raporunu sağlayacak şekilde çekirdeği paniğe sokar.
lldk
kontrolü, canlı kilit koşulu mevcut olduğunda sürekli olarak devam eder ve Linux'ta /proc/pid/stack
dosyasında " symbol+0x"
veya " symbol.cfi+0x"
oluşan dizeleri arar. Sembollerin listesi ro.llk.stack
dosyasındadır ve varsayılan olarak " cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
" virgülle ayrılmış listedir.
Semboller nadir olmalı ve tipik bir sistemde işlevin ro.llk.stack.timeout_ms
zaman aşımı süresi boyunca bir örnekte yalnızca bir kez görülmesini sağlayacak kadar kısa ömürlü olmalıdır (örnekler her ro.llk.check_ms
gerçekleşir). ABA korumasının olmaması nedeniyle yanlış tetiklemeyi önlemenin tek yolu budur. Sembol işlevi, mücadele edebilecek kilidi çağıran işlevin altında görünmelidir. Kilit, sembol fonksiyonunun altında veya içindeyse, sembol yalnızca kilitlenmeye neden olan proseste değil, etkilenen tüm proseslerde görünür.
Kapsam
llkd
varsayılan uygulaması init
, [kthreadd]
veya [kthreadd]
ortaya çıkışlarını izlemez. llkd
[kthreadd]
tarafından oluşturulan konuları kapsaması için:
- Sürücüler kalıcı D durumunda kalmamalı,
VEYA
- Sürücülerin, iş parçacığının harici olarak öldürülmesi durumunda onu kurtaracak mekanizmalara sahip olması gerekir. Örneğin
wait_event()
yerinewait_event_interruptible()
kullanın.
Yukarıdaki koşullardan biri karşılanırsa, llkd
kara listesi çekirdek bileşenlerini kapsayacak şekilde ayarlanabilir. Yığın sembolü kontrolü, ptrace
işlemlerini engelleyen hizmetlerde sepolicy ihlallerini önlemek için ek bir süreç kara listesi içerir.
Android özellikleri
llkd
çeşitli Android özelliklerine 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 bir satır başında 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, "yanlış" dizesi boş bir listeyle 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ıştır.
ro.debuggable
Cihaz, userdebug veya eng build için yapılandırılmıştır.
ro.llk.sysrq_t
Özellik "eng" ise, varsayılan ro.config.low_ram
veya ro.debuggable
değildir. Doğruysa, tüm iş parçacıklarını ( sysrq t
) boşaltın.
ro.llk.etkinleştir
Canlı kilit arka plan programının etkinleştirilmesine izin ver. Varsayılan yanlıştır.
llk.etkinleştir
Eng yapıları 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 yapıları 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.timeout
[khungtask]
maksimum süre sınırı. Varsayılan 12 dakikadır.
ro.llk.timeout_ms
D veya Z maksimum süre sınırı. Varsayılan 10 dakikadır. llkd
için alarm gözlemcisini ayarlamak için bu değeri iki katına çıkarı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 simgelerinin maksimum süre sınırını kontrol eder. Varsayılan ro.llk.timeout_ms
. Yalnızca userdebug veya eng derlemelerinde etkindir .
ro.llk.check_ms
D veya Z için iş parçacığı örnekleri. Varsayılan iki dakikadır.
ro.llk.stack
Sürekli olarak mevcut olması durumunda bir alt sistemin kilitlendiğini gösterebilecek çekirdek yığını sembollerini kontrol eder. Varsayılan, çekirdek sembollerinin cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
virgülle ayrılmış listesidir. Kontrol, ro.llk.stack.timeout_ms
dönemi boyunca her ro.llk_check_ms
yoklamak dışında ABA'yı ileriye doğru planlamaz, 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"
eşleşmesini kontrol eder. Yalnızca userdebug veya eng yapılarında mevcuttur ; Kullanıcı yapılarındaki güvenlik endişeleri, bu kontrolü engelleyen sınırlı ayrıcalıklara neden olur.
ro.llk.kara liste.işlemi
llkd
belirtilen işlemleri izlemiyor. 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 mülk boyutu olan 92'den daha büyük olabilir.
ro.llk.kara liste.parent
llkd
, belirtilen ebeveyn(ler)e sahip işlemleri izlemez. Varsayılan 0,2,adbd&[setsid]
dir ( kernel
, [kthreadd]
ve adbd
yalnızca zombi setsid
için). Ve işareti (&) ayırıcısı, üst öğenin yalnızca hedef alt süreçle birlikte göz ardı edildiğini belirtir. Ve işareti hiçbir zaman bir süreç adının parçası olmadığı için seçilmiştir; ancak kabuktaki bir setprop
, ve işaretinin atlanmasını veya tırnak içine alınmasını gerektirir, ancak normalde bunun belirtildiği init rc
dosyasında bu sorun yoktur. Bir üst veya hedef süreç bir comm
, cmdline
veya pid
referansı olabilir.
ro.llk.blacklist.uid
llkd
belirtilen kullanıcı kimlikleriyle eşleşen işlemleri izlemez. Kullanıcı kimlik numaralarının 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 işlem adları init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
. ptrace
engelleyen işlemlerle ilişkili sepolitik ihlallerini önler (bunlar kontrol edilemediğinden). Yalnızca userdebug ve eng derlemelerinde etkindir . Derleme türleriyle ilgili ayrıntılar için Android Oluşturma konusuna bakın.
Mimari kaygılar
- Özellikler 92 karakterle sınırlıdır (ancak kaynaklardaki
include/llkd.h
dosyasında tanımlanan varsayılanlar için bu dikkate alınmaz). - Yerleşik
[khungtask]
arka plan programı çok genel ve D durumunda çok fazla bulunan sürücü koduna takılıp kalıyor. S'ye geçiş, görevlerin sonlandırılabilir (ve gerekirse sürücüler tarafından yeniden diriltilebilir) olmasını sağlayacaktır.
Kütüphane arayüzü (isteğe bağlı)
İsteğe bağlı olarak libllkd
bileşenindeki aşağıdaki C arayüzünü kullanarak 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ğlanırsa, otomatik olarak bir iş parçacığı oluşturulur, aksi takdirde arayan kişinin ana döngüsünde llkCheckMilliseconds
çağırması gerekir. İşlev, bu işleyiciye yapılacak bir sonraki beklenen çağrıdan önceki süreyi döndürür.