एंड्रॉइड 10 में एंड्रॉइड लाइव-लॉक डेमॉन ( llkd
) शामिल है, जिसे कर्नेल गतिरोध को पकड़ने और कम करने के लिए डिज़ाइन किया गया है। llkd
घटक एक डिफ़ॉल्ट स्टैंडअलोन कार्यान्वयन प्रदान करता है, लेकिन आप वैकल्पिक रूप से llkd
कोड को किसी अन्य सेवा में एकीकृत कर सकते हैं, या तो मुख्य लूप के भाग के रूप में या एक अलग थ्रेड के रूप में।
पता लगाने के परिदृश्य
llkd
में दो डिटेक्शन परिदृश्य हैं: परसिस्टेंट 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
चेक लगातार तब भी जारी रहता है जब लाइव लॉक की स्थिति मौजूद होती है और लिनक्स पर /proc/pid/stack
फ़ाइल में कंपोज़ किए गए स्ट्रिंग्स " symbol+0x"
या " symbol.cfi+0x"
की तलाश करता है। प्रतीकों की सूची 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]
स्पॉन की निगरानी नहीं करता है। llkd
के लिए [kthreadd]
-स्पॉन्डेड थ्रेड्स को कवर करने के लिए:
- ड्राइवरों को लगातार डी स्थिति में नहीं रहना चाहिए,
या
- यदि बाहरी रूप से इसे मारा जाना चाहिए तो ड्राइवरों के पास थ्रेड को पुनर्प्राप्त करने के लिए तंत्र होना चाहिए। उदाहरण के लिए,
wait_event_interruptible()
wait_event()
उपयोग करें।
यदि उपरोक्त में से कोई एक शर्त पूरी होती है, तो llkd
ब्लैकलिस्ट को कर्नेल घटकों को कवर करने के लिए समायोजित किया जा सकता है। स्टैक सिंबल चेकिंग में ptrace
ऑपरेशंस को ब्लॉक करने वाली सेवाओं पर सेपॉलिसी उल्लंघनों को रोकने के लिए एक अतिरिक्त प्रक्रिया ब्लैकलिस्ट शामिल है।
Android गुण
llkd
कई Android गुणों (नीचे सूचीबद्ध) के प्रति प्रतिक्रिया करता है।
-
prop_ms
नाम के गुण मिलीसेकंड में हैं। - गुण जो सूचियों के लिए अल्पविराम (,) विभाजक का उपयोग करते हैं, डिफ़ॉल्ट प्रविष्टि को संरक्षित करने के लिए एक अग्रणी विभाजक का उपयोग करते हैं, फिर क्रमशः वैकल्पिक प्लस (+) और माइनस (-) उपसर्गों के साथ प्रविष्टियां जोड़ते या घटाते हैं। इन सूचियों के लिए, स्ट्रिंग "गलत" एक खाली सूची का पर्याय है, और रिक्त या अनुपलब्ध प्रविष्टियाँ निर्दिष्ट डिफ़ॉल्ट मान का सहारा लेती हैं।
ro.config.low_ram
डिवाइस सीमित मेमोरी के साथ कॉन्फ़िगर किया गया है।
आरओ.डीबग करने योग्य
डिवाइस को userdebug या eng बिल्ड के लिए कॉन्फ़िगर किया गया है।
ro.llk.sysrq_t
यदि गुण "eng" है, तो डिफ़ॉल्ट ro.config.low_ram
या ro.debuggable
नहीं है। यदि सही है, तो सभी थ्रेड्स को डंप करें ( sysrq t
)।
ro.llk.enable
लाइव-लॉक डेमॉन को सक्षम होने दें। डिफ़ॉल्ट गलत है।
llk.enable
इंजी बिल्ड के लिए मूल्यांकन किया गया। डिफ़ॉल्ट ro.llk.enable
है।
ro.khungtask.enable
[khungtask]
डेमॉन को सक्षम होने दें। डिफ़ॉल्ट गलत है।
खुंगटास्क.सक्षम
इंजी बिल्ड के लिए मूल्यांकन किया गया। डिफ़ॉल्ट ro.khungtask.enable
है।
ro.llk.mlockall
कॉल को mlockall()
पर सक्षम करें। डिफ़ॉल्ट गलत है।
ro.khungtask.timeout
[khungtask]
अधिकतम समय सीमा। डिफ़ॉल्ट 12 मिनट है।
ro.llk.timeout_ms
डी या जेड अधिकतम समय सीमा। डिफ़ॉल्ट 10 मिनट है। llkd
के लिए अलार्म वॉचडॉग सेट करने के लिए इस मान को दोगुना करें।
ro.llk.D.timeout_ms
डी अधिकतम समय सीमा। डिफ़ॉल्ट 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 के लिए थ्रेड्स के नमूने। डिफ़ॉल्ट दो मिनट है।
आरओ.एलएलके.स्टैक
कर्नेल स्टैक प्रतीकों के लिए जाँच करता है कि यदि लगातार मौजूद है तो यह संकेत कर सकता है कि एक सबसिस्टम लॉक हो गया है। डिफ़ॉल्ट cma_alloc,__get_user_pages,bit_wait_io,wait_on_page_bit_killable
अल्पविराम से अलग कर्नेल प्रतीकों की सूची है। ro.llk.stack.timeout_ms
अवधि के दौरान प्रत्येक ro.llk_check_ms
को मतदान के अलावा चेक अग्रेषित शेड्यूलिंग ABA नहीं करता है, इसलिए स्टैक प्रतीक असाधारण रूप से दुर्लभ और क्षणभंगुर होने चाहिए (किसी प्रतीक के सभी में लगातार दिखाई देने की अत्यधिक संभावना नहीं है) ढेर के नमूने)। स्टैक विस्तार में " symbol+0x"
+0x" या " symbol.cfi+0x"
के लिए एक मैच के लिए जाँच करता है। केवल userdebug या eng बिल्ड पर उपलब्ध है ; उपयोगकर्ता बिल्ड पर सुरक्षा चिंताओं का परिणाम सीमित विशेषाधिकारों में होता है जो इस चेक को रोकते हैं।
ro.llk.ब्लैकलिस्ट.प्रोसेस
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.ब्लैकलिस्ट.पैरेंट
llkd
प्रक्रियाओं को नहीं देखता है जिनमें निर्दिष्ट माता-पिता हैं। डिफ़ॉल्ट 0,2,adbd&[setsid]
( kernel
, [kthreadd]
और adbd
केवल ज़ॉम्बी setsid
के लिए है)। एक एम्परसेंड (&) विभाजक निर्दिष्ट करता है कि माता-पिता को केवल लक्ष्य चाइल्ड प्रक्रिया के संयोजन में अनदेखा किया जाता है। एम्परसेंड को इसलिए चुना गया क्योंकि यह कभी भी किसी प्रक्रिया के नाम का हिस्सा नहीं होता है; हालांकि, खोल में एक setprop
को एम्परसेंड से बचने या उद्धृत करने की आवश्यकता होती है, हालांकि init rc
आरसी फ़ाइल जहां इसे सामान्य रूप से निर्दिष्ट किया जाता है, में यह समस्या नहीं होती है। माता-पिता या लक्ष्य प्रक्रिया एक comm
, cmdline
, या pid
संदर्भ हो सकती है।
ro.llk.blacklist.uid
llkd
निर्दिष्ट यूआईडी से मेल खाने वाली प्रक्रियाओं को नहीं देखता है। यूआईडी नंबरों या नामों की अल्पविराम से अलग की गई सूची। डिफ़ॉल्ट खाली या गलत है।
ro.llk.blacklist.process.stack
llkd
लाइव लॉक स्टैक हस्ताक्षर के लिए प्रक्रियाओं के निर्दिष्ट सबसेट की निगरानी नहीं करता है। डिफ़ॉल्ट प्रक्रिया नाम है init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd
। ptrace
को ब्लॉक करने वाली प्रक्रियाओं से जुड़े सेपॉलिसी उल्लंघन को रोकता है (क्योंकि इन्हें चेक नहीं किया जा सकता है)। केवल userdebug और eng बिल्ड पर सक्रिय है । बिल्ड प्रकारों के विवरण के लिए, बिल्डिंग एंड्रॉइड देखें।
वास्तु संबंधी चिंताएं
- गुण 92 वर्णों तक सीमित हैं (हालांकि, स्रोतों में
include/llkd.h
फ़ाइल में परिभाषित डिफ़ॉल्ट के लिए इसे अनदेखा किया जाता है)। - बिल्ट-इन
[khungtask]
डेमॉन बहुत सामान्य है और ड्राइवर कोड पर यात्राएं करता है जो डी राज्य में बहुत अधिक बैठता है। S पर स्विच करने से कार्य (ओं) को मार डाला जा सकता है (और यदि आवश्यक हो तो ड्राइवरों द्वारा पुनरुत्थित)।
लाइब्रेरी इंटरफ़ेस (वैकल्पिक)
आप libllkd
घटक से निम्नलिखित C इंटरफ़ेस का उपयोग करके वैकल्पिक रूप से llkd
को किसी अन्य विशेषाधिकार प्राप्त डेमॉन में शामिल कर सकते हैं:
#include "llkd.h"
bool llkInit(const char* threadname) /* return true if enabled */
unsigned llkCheckMillseconds(void) /* ms to sleep for next check */
यदि एक थ्रेडनाम प्रदान किया जाता है, तो एक थ्रेड स्वचालित रूप से उत्पन्न होता है, अन्यथा कॉलर को अपने मुख्य लूप में llkCheckMilliseconds
को कॉल करना होगा। फ़ंक्शन इस हैंडलर को अगली अपेक्षित कॉल से पहले की अवधि लौटाता है।