Scudo, डाइनैमिक उपयोगकर्ता-मोड मेमोरी ऐलोकेटर या हीप ऐलोकेटर है. इसे परफ़ॉर्मेंस बनाए रखते हुए, हीप से जुड़ी कमजोरियों (जैसे कि हीप पर आधारित बफ़र का ओवरफ़्लो, खाली करने के बाद इस्तेमाल करना, और दो बार खाली करना) के लिए डिज़ाइन किया गया है. यह स्टैंडर्ड C एलोकेशन और डिएलोकेशन प्राइमिटिव (जैसे, malloc और free) के साथ-साथ C++ प्राइमिटिव (जैसे, new और delete) भी उपलब्ध कराता है.
Scudo, AddressSanitizer (ASan) जैसे मेमोरी की गड़बड़ी का पता लगाने वाले टूल की तुलना में, गड़बड़ी को कम करने वाला टूल है.
Android 11 के रिलीज़ होने के बाद से, सभी नेटिव कोड के लिए scudo का इस्तेमाल किया जाता है. हालांकि, कम मेमोरी वाले डिवाइसों पर अब भी jemalloc का इस्तेमाल किया जाता है. रनटाइम के दौरान, सभी नेटिव हेप के ऐलोकेशन और डिऐलोकेशन की सेवा, Scudo सभी एक्सीक्यूटेबल और उनकी लाइब्रेरी डिपेंडेंसी के लिए करता है. अगर हेप में कोई गड़बड़ी या संदिग्ध व्यवहार का पता चलता है, तो प्रोसेस को रोक दिया जाता है.
Scudo ओपन सोर्स है और यह LLVM के compiler-rt प्रोजेक्ट का हिस्सा है. दस्तावेज़ https://llvm.org/docs/ScudoHardenedAllocator.html पर उपलब्ध है. Scudo रनटाइम, Android टूलचैन का हिस्सा है. साथ ही, Soong और Make में भी इसकी सुविधा जोड़ी गई है, ताकि किसी बाइनरी में एलोकेटर को आसानी से चालू किया जा सके.
नीचे दिए गए विकल्पों का इस्तेमाल करके, ऐलोकेटर में अतिरिक्त मटिगेशन को चालू या बंद किया जा सकता है.
पसंद के मुताबिक बनाएं
एलोकेटर के कुछ पैरामीटर को हर प्रोसेस के हिसाब से कई तरीकों से तय किया जा सकता है:
- स्टैटिक तरीके से: प्रोग्राम में
__scudo_default_options
फ़ंक्शन तय करें, जो पार्स करने के लिए विकल्प स्ट्रिंग दिखाता है. इस फ़ंक्शन के पास यह प्रोटोटाइप होना चाहिए:extern "C" const char *__scudo_default_options()
. - डाइनैमिक तौर पर: एनवायरमेंट वैरिएबल
SCUDO_OPTIONS
का इस्तेमाल करें, जिसमें पार्स की जाने वाली विकल्प स्ट्रिंग शामिल हो. इस तरह से तय किए गए विकल्प,__scudo_default_options
के ज़रिए तय की गई किसी भी परिभाषा को बदल देते हैं.
ये विकल्प उपलब्ध हैं.
विकल्प | 64-बिट डिफ़ॉल्ट | डिफ़ॉल्ट रूप से 32-बिट | ब्यौरा |
---|---|---|---|
QuarantineSizeKb |
256 |
64 |
क्वॉरंटीन का साइज़ (केबी में), जिसका इस्तेमाल चंक को डिअललोकेट करने में देरी करने के लिए किया जाता है. कम वैल्यू से मेमोरी का इस्तेमाल कम हो सकता है. हालांकि, इससे होने वाले असर को कम करने में मदद मिलती है. वहीं, नेगेटिव वैल्यू को फिर से डिफ़ॉल्ट वैल्यू पर सेट कर दिया जाता है. इसे और ThreadLocalQuarantineSizeKb , दोनों को शून्य पर सेट करने से, क्वॉरंटीन की सुविधा पूरी तरह से बंद हो जाती है. |
QuarantineChunksUpToSize |
2048 |
512 |
डेटा के किस हिस्से (बाइट में) तक क्वॉरंटीन किए जा सकते हैं. |
ThreadLocalQuarantineSizeKb |
64 |
16 |
ग्लोबल क्वॉरंटीन को ऑफ़लोड करने के लिए, हर थ्रेड के कैश मेमोरी का साइज़ (केबी में).
कम वैल्यू से मेमोरी का इस्तेमाल कम हो सकता है, लेकिन ग्लोबल क्वॉरंटीन पर कॉन्टेंटेशन बढ़ सकता है. इसे और QuarantineSizeKb , दोनों को शून्य पर सेट करने से क्वॉरंटीन पूरी तरह से बंद हो जाता है. |
DeallocationTypeMismatch |
false |
false |
malloc/delete, new/free, new/delete[] पर गड़बड़ी की रिपोर्टिंग की सुविधा चालू करता है |
DeleteSizeMismatch |
true |
true |
नए और मिटाए गए डेटा के साइज़ के मेल न खाने पर, गड़बड़ी की रिपोर्टिंग की सुविधा चालू करता है. |
ZeroContents |
false |
false |
यह एट्रिब्यूट, एलोकेशन और डिएलोकेशन के दौरान, शून्य चंक वाले कॉन्टेंट को चालू करता है. |
allocator_may_return_null |
false |
false |
इससे पता चलता है कि प्रोसेस को खत्म करने के बजाय, ठीक की जा सकने वाली गड़बड़ी होने पर, एलोकेटर null दिखा सकता है. |
hard_rss_limit_mb |
0 |
0 |
आरएसएस फ़ीड के ज़रिए इस सीमा तक पहुंचने पर, यह प्रोसेस खत्म हो जाती है. |
soft_rss_limit_mb |
0 |
0 |
जब प्रोसेस की आरएसएस इस सीमा तक पहुंच जाती है, तो allocator_may_return_null की वैल्यू के आधार पर, अगला बंटवारा फ़ेल हो जाता है या null दिखता है. ऐसा तब तक होता है, जब तक नए ऐलोकेशन को अनुमति देने के लिए आरएसएस वापस नीचे नहीं जाता. |
allocator_release_to_os_interval_ms |
लागू नहीं | 5000 |
सिर्फ़ 64-बिट ऐलोकेटर पर असर डालता है. अगर यह सेट है, तो ओएस को इस्तेमाल न की गई मेमोरी रिलीज़ करने की कोशिश की जाती है. हालांकि, यह इस इंटरवल (मिलीसेकंड में) से ज़्यादा बार नहीं की जाती. अगर वैल्यू नेगेटिव है, तो ओएस को मेमोरी रिलीज़ नहीं की जाती. |
abort_on_error |
true |
true |
अगर इस नीति को सेट किया जाता है, तो गड़बड़ी का मैसेज प्रिंट करने के बाद, टूल _exit() के बजाय abort() को कॉल करता है. |
पुष्टि करें
फ़िलहाल, Scudo के लिए खास तौर पर कोई सीटीएस टेस्ट नहीं है. इसके बजाय, पक्का करें कि किसी बाइनरी के लिए, Scudo की सुविधा चालू होने या न होने के बावजूद, सीटीएस टेस्ट पास हो जाएं. इससे यह पुष्टि की जा सकेगी कि बाइनरी का डिवाइस पर कोई असर नहीं पड़ेगा.
समस्या का हल
अगर कोई ऐसी समस्या का पता चलती है जिसे ठीक नहीं किया जा सकता, तो एलोकेटर, स्टैंडर्ड गड़बड़ी के ब्यौरे में गड़बड़ी का मैसेज दिखाता है. इसके बाद, वह प्रोसेस को बंद कर देता है.
प्रोसेस के बंद होने की वजह बताने वाले स्टैक ट्रेस, सिस्टम लॉग में जोड़े जाते हैं.
आम तौर पर, आउटपुट Scudo ERROR:
से शुरू होता है. इसके बाद, पॉइंटर के साथ समस्या की खास जानकारी दी जाती है.
गड़बड़ी के मौजूदा मैसेज और उनकी संभावित वजहों की सूची यहां दी गई है:
corrupted chunk header
: चंक हेडर के चेकसम की पुष्टि नहीं हो सकी. ऐसा दो वजहों से हो सकता है: हेडर को कुछ हद तक या पूरी तरह से बदल दिया गया हो या फ़ंक्शन में पास किया गया पॉइंटर कोई चंक न हो.race on chunk header
: दो अलग-अलग थ्रेड, एक ही समय पर एक ही हेडर में बदलाव करने की कोशिश कर रही हैं. आम तौर पर, यह रेस-कंडीशन या उस चंक पर कार्रवाइयां करते समय लॉकिंग की सामान्य कमी का लक्षण होता है.invalid chunk state
: किसी खास कार्रवाई के लिए डेटा का हिस्सा उम्मीद के मुताबिक नहीं है. उदाहरण के लिए, उसे हटाने की कोशिश करते समय उसे असाइन नहीं किया जाता या उसे रीसाइकल करते समय क्वॉरंटीन नहीं किया जाता. आम तौर पर, इस गड़बड़ी की वजह यह होती है कि किसी ऑब्जेक्ट को दो बार फ़्री किया गया हो.misaligned pointer
: अलाइनमेंट की बुनियादी ज़रूरी शर्तों को सख्ती से लागू किया जाता है: 32-बिट प्लैटफ़ॉर्म पर 8 बाइट और 64-बिट प्लैटफ़ॉर्म पर 16 बाइट. अगर हमारे फ़ंक्शन को पास किया गया कोई पॉइंटर उन चीज़ों के लिए सही नहीं है, तो किसी एक फ़ंक्शन को पास किया गया पॉइंटर, अलाइनमेंट से बाहर है.allocation type mismatch
: इस विकल्प के चालू होने पर, किसी डेटा ग्रुप को असाइन किए जाने वाले डीललोकेशन फ़ंक्शन को उस फ़ंक्शन से मेल खाना चाहिए जिसे उसे असाइन करने के लिए कॉल किया गया था. इस तरह के मैच न होने की वजह से, सुरक्षा से जुड़ी समस्याएं आ सकती हैं.invalid sized delete
: C++14 के साइज़ वाले delete ऑपरेटर का इस्तेमाल करने और ज़रूरी नहीं की जाने वाली जांच चालू होने पर, किसी चंक को डिअललोकेट करते समय दिए गए साइज़ और उसे ऐलोकेट करते समय दिए गए साइज़ में अंतर होता है. आम तौर पर, यह कंपाइलर की समस्या होती है या डिएलोकेट किए जा रहे ऑब्जेक्ट के लिए टाइप का भ्रम होता है.RSS limit exhausted
: आरएसएस फ़ीड की तय सीमा से ज़्यादा फ़ीड सबमिट किए गए हैं.
अगर आपको OS में क्रैश की समस्या को डीबग करना है, तो HWASan OS बिल्ड का इस्तेमाल किया जा सकता है. अगर किसी ऐप्लिकेशन में क्रैश को डीबग किया जा रहा है, तो HWASan ऐप्लिकेशन बिल्ड का भी इस्तेमाल किया जा सकता है.