एंड्रॉइड 10 में एंड्रॉइड लाइव-लॉक डेमॉन ( llkd
) शामिल है, जिसे कर्नेल गतिरोध को पकड़ने और कम करने के लिए डिज़ाइन किया गया है। llkd
घटक एक डिफ़ॉल्ट स्टैंडअलोन कार्यान्वयन प्रदान करता है, लेकिन आप वैकल्पिक रूप से llkd
कोड को किसी अन्य सेवा में एकीकृत कर सकते हैं, या तो मुख्य लूप के हिस्से के रूप में या एक अलग थ्रेड के रूप में।
पता लगाने के परिदृश्य
llkd
में दो पहचान परिदृश्य हैं: लगातार डी या जेड स्थिति, और लगातार स्टैक हस्ताक्षर।
लगातार डी या जेड अवस्था
यदि कोई थ्रेड 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()
के बजायwait_event_interruptible()
का उपयोग करें।
यदि उपरोक्त शर्तों में से एक पूरी हो जाती है, तो llkd
ब्लैकलिस्ट को कर्नेल घटकों को कवर करने के लिए समायोजित किया जा सकता है। स्टैक प्रतीक जाँच में ptrace
संचालन को अवरुद्ध करने वाली सेवाओं पर सेपॉलिसी उल्लंघन को रोकने के लिए एक अतिरिक्त प्रक्रिया ब्लैकलिस्ट शामिल है।
एंड्रॉइड गुण
llkd
कई एंड्रॉइड संपत्तियों पर प्रतिक्रिया करता है (नीचे सूचीबद्ध)।
-
prop_ms
नामक गुण मिलीसेकंड में हैं। - गुण जो सूचियों के लिए अल्पविराम (,) विभाजक का उपयोग करते हैं, डिफ़ॉल्ट प्रविष्टि को संरक्षित करने के लिए एक अग्रणी विभाजक का उपयोग करते हैं, फिर क्रमशः वैकल्पिक प्लस (+) और माइनस (-) उपसर्गों के साथ प्रविष्टियाँ जोड़ते या घटाते हैं। इन सूचियों के लिए, स्ट्रिंग "गलत" एक खाली सूची का पर्याय है, और रिक्त या अनुपलब्ध प्रविष्टियाँ निर्दिष्ट डिफ़ॉल्ट मान का सहारा लेती हैं।
ro.config.low_ram
डिवाइस को सीमित मेमोरी के साथ कॉन्फ़िगर किया गया है।
ro.डीबग करने योग्य
डिवाइस को userdebug या eng बिल्ड के लिए कॉन्फ़िगर किया गया है।
ro.llk.sysrq_t
यदि संपत्ति "eng" है, तो डिफ़ॉल्ट ro.config.low_ram
या ro.debuggable
नहीं है। यदि सत्य है, तो सभी थ्रेड्स ( sysrq t
) को डंप कर दें।
ro.llk.सक्षम
लाइव-लॉक डेमॉन को सक्षम करने की अनुमति दें। डिफ़ॉल्ट ग़लत है.
llk.सक्षम
अंग्रेजी बिल्ड के लिए मूल्यांकन किया गया। डिफ़ॉल्ट ro.llk.enable
है।
ro.khungtask.सक्षम
[khungtask]
डेमॉन को सक्षम करने की अनुमति दें। डिफ़ॉल्ट ग़लत है.
खुंगटास्क.सक्षम
अंग्रेजी बिल्ड के लिए मूल्यांकन किया गया। डिफ़ॉल्ट ro.khungtask.enable
है।
ro.llk.mlockall
mlockall()
पर कॉल सक्षम करें। डिफ़ॉल्ट ग़लत है.
ro.khungtask.timeout
[khungtask]
अधिकतम समय सीमा। डिफ़ॉल्ट 12 मिनट है.
ro.llk.timeout_ms
D या Z अधिकतम समय सीमा. डिफ़ॉल्ट 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
डी या जेड के लिए धागे के नमूने। डिफ़ॉल्ट दो मिनट है।
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
पोल करने के अलावा एबीए को फॉरवर्ड शेड्यूलिंग नहीं करता है, इसलिए स्टैक प्रतीक असाधारण रूप से दुर्लभ और क्षणभंगुर होने चाहिए (सभी में एक प्रतीक के लगातार दिखाई देने की अत्यधिक संभावना नहीं है) ढेर के नमूने)। स्टैक विस्तार में " symbol+0x"
या " symbol.cfi+0x"
के मिलान की जाँच करता है। केवल userdebug या eng बिल्ड पर उपलब्ध है ; उपयोगकर्ता बिल्ड पर सुरक्षा चिंताओं के परिणामस्वरूप सीमित विशेषाधिकार होते हैं जो इस जाँच को रोकते हैं।
ro.llk.blacklist.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.blacklist.parent
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]
डेमॉन बहुत सामान्य है और ड्राइवर कोड पर यात्रा करता है जो डी स्थिति में बहुत अधिक बैठता है। एस पर स्विच करने से कार्य(कार्यों) को ख़त्म किया जा सकेगा (और यदि आवश्यक हो तो ड्राइवरों द्वारा पुनर्जीवित किया जा सकेगा)।
लाइब्रेरी इंटरफ़ेस (वैकल्पिक)
आप वैकल्पिक रूप से 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
कॉल करना होगा। फ़ंक्शन इस हैंडलर को अगली अपेक्षित कॉल से पहले की समयावधि लौटाता है।