Android Live-LocK Daemon (llkd)

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_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.