Android लाइव-लॉक डीमन (llkd)

Android 10 में Android का लाइव-लॉक डीमन शामिल है (llkd), जिसे कर्नेल डेडलॉक को पकड़ने और उन्हें कम करने के लिए डिज़ाइन किया गया है. llkd कॉम्पोनेंट एक डिफ़ॉल्ट स्टैंडअलोन इंप्लिमेंटेशन देता है, लेकिन इसके अलावा, llkd कोड को किसी दूसरी सेवा में इंटिग्रेट किया जा सकता है. ऐसा या तो इसके हिस्से के तौर पर किया जा सकता है मुख्य लूप या अलग थ्रेड के रूप में

पहचान करने की स्थितियां

llkd में पहचान की पुष्टि की दो स्थितियां होती हैं: परसिस्टेंट D या Z स्टेट और परसिस्टेंट स्टैक सिग्नेचर.

परसिस्टेंट D या Z स्टेट

अगर कोई थ्रेड D (बिना रुकावट स्लीप मोड) या Z (ज़ॉम्बी) स्टेटस में है, लेकिन फ़ॉरवर्ड नहीं किया जा सकता ro.llk.timeout_ms or ro.llk.[D|Z].timeout_ms से ज़्यादा समय तक चले, llkd इस प्रोसेस को बंद कर देता है या पैरंट प्रोसेस को बंद कर देता है. अगर बाद में स्कैन करने पर, वही प्रोसेस जारी है. llkd, लाइव लॉक की स्थिति की पुष्टि करता है और कर्नेल को इस तरह पैन करता है कि स्थिति.

llkd में एक सेल्फ़ वॉच डॉग है, जो llkd के लॉक होने पर अलार्म बजाता है; वॉचडॉग है मेनलूप से होकर गुज़रने के लिए अनुमानित समय दोगुना होता है और सैंपलिंग हर ro.llk_sample_ms.

स्थायी स्टैक सिग्नेचर

उपयोगकर्ता डीबग रिलीज़ के लिए, llkd स्थायी यूआरएल का इस्तेमाल करके कर्नेल लाइव-लॉक का पता लगा सकता है हस्ताक्षर की जांच करने के लिए. अगर Z को छोड़कर किसी भी राज्य में थ्रेड स्थायी है सूचीबद्ध ro.llk.stack कर्नेल प्रतीक जो से ज़्यादा समय के लिए रिपोर्ट किया जाता है ro.llk.timeout_ms या ro.llk.stack.timeout_ms, llkd इस प्रोसेस को खत्म कर देता है (भले ही, फ़ॉरवर्ड को शेड्यूल किया जा रहा हो). अगर बाद में स्कैन करने पर, वही प्रोसेस जारी है. llkd, लाइव लॉक की स्थिति की पुष्टि करता है और कर्नेल को इस तरह पैन करता है कि स्थिति.

लाइव लॉक की स्थिति में बदलाव होने पर और lldk की जांच लगातार जारी रहती है यह बनाई गई स्ट्रिंग symbol+0x या symbol.cfi+0x Linux पर /proc/pid/stack फ़ाइल है. प्रतीकों की सूची ro.llk.stack और यह डिफ़ॉल्ट रूप से कॉमा लगाकर अलग की गई सूची पर सेट होती है cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable.

प्रतीक इतने कम और अल्पकालिक होने चाहिए कि किसी सामान्य प्रणाली में फ़ंक्शन को टाइम आउट की अवधि में, सैंपल में सिर्फ़ एक बार देखा जाता है ro.llk.stack.timeout_ms (नमूने हर ro.llk.check_ms में दिखते हैं). कमी की वजह से अगर है, तो गलत ट्रिगर को रोकने का सिर्फ़ यही एक तरीका है. प्रतीक फ़ंक्शन को लॉक करने वाले फ़ंक्शन के नीचे दिखना चाहिए. अगर आपने लॉक नीचे या सिम्बॉल फ़ंक्शन में होता है, जो कि पूरी तरह से प्रभावित जगहों पर दिखता है प्रोसेस नहीं करेगा, न कि सिर्फ़ वह जिसकी वजह से लॉकअप हुआ है.

कवरेज

llkd को डिफ़ॉल्ट रूप से लागू करने की प्रोसेस, init, [kthreadd] या [kthreadd] स्पॉन्स. [kthreadd]-स्पॉन्ड धागे को कवर करने के लिए, llkd के लिए:

  • ड्राइवर को लगातार D स्थिति में नहीं रहना चाहिए,

या

  • अगर थ्रेड खत्म हो जाए, तो ड्राइवर के पास उसे रिकवर करने का तरीका होना चाहिए बाहर से ऐसा कर सकें. उदाहरण के लिए, इसके बजाय wait_event_interruptible() का इस्तेमाल करें wait_event().

अगर ऊपर दी गई शर्तों में से कोई एक पूरी होती है, तो llkd ब्लॉकलिस्ट में बदलाव किया जा सकता है कर्नेल कॉम्पोनेंट को कवर करता है. स्टैक सिंबल की जांच करने के लिए एक अन्य प्रोसेस को पूरा करना पड़ता है ptrace को ब्लॉक करने वाली सेवाओं पर, नीति के उल्लंघन को रोकने के लिए ब्लॉकलिस्ट कार्रवाइयां.

Android प्रॉपर्टी

llkd, कई Android प्रॉपर्टी (नीचे दी गई सूची) के बारे में बताता है.

  • prop_ms नाम की प्रॉपर्टी मिलीसेकंड में होती हैं.
  • जिन प्रॉपर्टी में सूचियों के लिए कॉमा (,) सेपरेटर का इस्तेमाल किया जाता है वे सेपरेटर का इस्तेमाल किया जाता है डिफ़ॉल्ट एंट्री को सुरक्षित रखें, फिर वैकल्पिक प्लस वाली एंट्री को जोड़ें या घटाएं प्रीफ़िक्स (+) और माइनस (-) के चिह्न होते हैं. इन सूचियों के लिए, स्ट्रिंग false खाली सूची का समानार्थी है, और खाली या छूटी हुई एंट्री का रिज़ॉर्ट डिफ़ॉल्ट मान सेट किया गया हो.

ro.config.low_ram

डिवाइस को सीमित मेमोरी के साथ कॉन्फ़िगर किया गया है.

ro.debuggable

डिवाइस को userdebug या eng बिल्ड के लिए कॉन्फ़िगर किया गया है.

Ro.llk.sysrq_t

अगर प्रॉपर्टी eng है, तो ro.config.low_ram या ro.debuggable डिफ़ॉल्ट नहीं है. अगर true है, तो सभी थ्रेड (sysrq t) डंप करें.

ro.llk.enable

लाइव-लॉक डीमन को चालू करने की अनुमति दें. डिफ़ॉल्ट वैल्यू false है.

llk.enable

इंजीनियरिंग बिल्ड के लिए आकलन किया गया. डिफ़ॉल्ट वैल्यू ro.llk.enable है.

ro.kungtask.enable

[khungtask] डीमन को चालू करने की अनुमति दें. डिफ़ॉल्ट वैल्यू false है.

kungtask.enable

इंजीनियरिंग बिल्ड के लिए आकलन किया गया. डिफ़ॉल्ट वैल्यू ro.khungtask.enable है.

ro.llk.mlockall

mlockall() पर कॉल करने की सुविधा चालू करें. डिफ़ॉल्ट वैल्यू false है.

CANNOT TRANSLATE

ज़्यादा से ज़्यादा [khungtask] समय सीमा. डिफ़ॉल्ट अवधि 12 मिनट है.

ro.llk.timeout_ms

D या Z की ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट अवधि 10 मिनट है. वैल्यू को सेट करने के लिए, इस वैल्यू को दोगुना करें llkd के लिए अलार्म वॉचडॉग.

ro.llk.D.timeout_ms

D ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट वैल्यू ro.llk.timeout_ms है.

ro.llk.Z.timeout_ms

Z की ज़्यादा से ज़्यादा समयसीमा. डिफ़ॉल्ट वैल्यू ro.llk.timeout_ms है.

ro.llk.stack.timeout_ms

यह जांच करके स्थायी स्टैक सिंबल की ज़्यादा से ज़्यादा समयसीमा की जांच की जाती है. डिफ़ॉल्ट है ro.llk.timeout_ms. यह सुविधा सिर्फ़ userdebug या eng बिल्ड पर ऐक्टिव है.

ro.llk.check_ms

D या Z के लिए थ्रेड के सैंपल. डिफ़ॉल्ट सेटिंग दो मिनट है.

ro.llk.stack

कर्नेल स्टैक सिंबल की जांच करता है, जो लगातार मौजूद होने पर यह दिखाता है कि सबसिस्टम लॉक है. डिफ़ॉल्ट है cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है कर्नेल सिंबल की कॉमा-सेपरेटेड लिस्ट. इस जांच से, शेड्यूल किए गए अपॉइंटमेंट को शेड्यूल नहीं किया जा सकता इस अवधि के दौरान हर ro.llk_check_ms में होने वाले पोल को छोड़कर, एबीए ro.llk.stack.timeout_ms है, इसलिए स्टैक सिंबल बहुत कम होने चाहिए और यह थोड़े समय के लिए ही दिखता है (किसी सिंबल के दिखने की संभावना बेहद कम है) सैंपल). symbol+0x के लिए मैच की जांच करता है या स्टैक एक्सपैंशन में symbol.cfi+0x. यह सुविधा सिर्फ़ userdebug या eng पर उपलब्ध है बिल्ड; उपयोगकर्ताओं के सभी बिल्ड पर सुरक्षा से जुड़ी चिंताओं का असर इस जाँच को रोकें.

ro.llk.black.process

llkd तय प्रोसेस को नहीं देखता है. डिफ़ॉल्ट सेटिंग 0,1,2 (kernel, init और [kthreadd]) और प्रोसेस के नाम init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd, [watchdogd],[watchdogd/0],...,[watchdogd/get_nprocs-1]. प्रोसेस, comm, cmdline या pid पहचान फ़ाइल हो सकती है. अपने-आप काम करने वाली डिफ़ॉल्ट सेटिंग यह संख्या, प्रॉपर्टी के मौजूदा साइज़ 92 से ज़्यादा हो सकती है.

ro.llk.black.पैरंट

llkd उन प्रक्रियाओं को नहीं देखता है जिनमें बताए गए अभिभावक होते हैं. डिफ़ॉल्ट 0,2,adbd&[setsid] है (kernel, [kthreadd], और ज़ॉम्बी के लिए सिर्फ़ adbd) setsid) के साथ काम करता है. एंपरसैंड (&) सेपरेटर से पता चलता है कि पैरंट को सिर्फ़ अनदेखा किया गया है टारगेट चाइल्ड प्रोसेस के साथ हो सकता है. ऐंपरसेंड को चुना गया, क्योंकि यह किसी प्रोसेस के नाम का कभी हिस्सा न हो; हालांकि, शेल में setprop की ज़रूरत होती है ऐंपरसेंड को एस्केप या कोट किया जाना चाहिए, हालांकि init rc फ़ाइल जहां यह है सामान्य रूप से बताया गया है तो में यह समस्या नहीं है. पैरंट या टारगेट प्रोसेस के तहत, comm, cmdline या pid रेफ़रंस.

Ro.llk.black.uid

llkd, बताए गए यूआईडी से मेल खाने वाली प्रोसेस नहीं देखता. यूआईएस नंबर या नामों की कॉमा-सेपरेटेड लिस्ट. डिफ़ॉल्ट वैल्यू, false या खाली है.

ro.llk.black.process.stack

llkd, लाइव लॉक स्टैक के लिए तय की गई प्रोसेस के सबसेट को मॉनिटर नहीं करता हस्ताक्षर. प्रोसेस के नाम डिफ़ॉल्ट तौर पर सेट होते हैं init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd. से-नीति को रोकता है ptrace को ब्लॉक करने वाली प्रोसेस से जुड़ा उल्लंघन. इसकी वजह यह है कि चुना गया है). यह सुविधा सिर्फ़ userdebug और eng बिल्ड पर ऐक्टिव है. बिल्ड के बारे में जानकारी के लिए टाइप के लिए, बिल्डिंग Android देखें.

वास्तुकला से जुड़ी समस्याएं

  • प्रॉपर्टी में ज़्यादा से ज़्यादा 92 वर्ण हो सकते हैं. हालांकि, डिफ़ॉल्ट रूप से इसे अनदेखा किया जाता है (सोर्स में) include/llkd.h फ़ाइल में बताई गई है).
  • पहले से मौजूद [khungtask] डीमन बहुत जेनरिक है. यह ड्राइवर कोड का इस्तेमाल करके बनाया गया है D स्थिति में बहुत ज़्यादा मौजूद है. S का इस्तेमाल करने पर, टास्क के खत्म होने की संभावना बढ़ जाती है (और ज़रूरत पड़ने पर ड्राइवर फिर से इस्तेमाल कर सकते हैं).

लाइब्रेरी इंटरफ़ेस (ज़रूरी नहीं)

आपके पास विकल्प के तौर पर, llkd को किसी अन्य खास अधिकार वाले डीमन के तौर पर शामिल करने का विकल्प होता है. इसके लिए, libllkd कॉम्पोनेंट से नीचे दिया गया सी इंटरफ़ेस:

#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void)   /* ms to sleep for next check */

अगर थ्रेड का नाम दिया जाता है, तो एक थ्रेड अपने-आप जनरेट होता है. अगर ऐसा नहीं होता है, तो कॉलर llkCheckMilliseconds को उसके मुख्य लूप में कॉल करना चाहिए. फ़ंक्शन, इस हैंडलर को अगली अनुमानित कॉल मिलने से पहले की समयावधि.