एंड्रॉइड लाइव-लॉक डेमॉन (llkd)

एंड्रॉइड 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 कॉल करना होगा। फ़ंक्शन इस हैंडलर को अगली अपेक्षित कॉल से पहले की समयावधि लौटाता है।