Android Live-LocK Arka Plan Programı (llkd)

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() yerine wait_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.