HWASan क्रैश को पढ़ने का तरीका जानने के लिए, एचडब्ल्यूएएसएन रिपोर्ट को समझना लेख पढ़ें!
हार्डवेयर की मदद से काम करने वाला AddressSanitizer (HWASan), मेमोरी में होने वाली गड़बड़ी का पता लगाने वाला टूल है. यह AddressSanitizer जैसा ही है. ASan की तुलना में, HWASan का इस्तेमाल करने पर, ज़्यादा रैम खर्च नहीं होती. इसलिए, यह पूरे सिस्टम को सुरक्षित बनाने के लिए सही है. HWASan सिर्फ़ Android 10 और उसके बाद के वर्शन पर उपलब्ध है. साथ ही, यह सिर्फ़ AArch64 हार्डवेयर पर काम करता है.
HWASan मुख्य रूप से C/C++ कोड के लिए फ़ायदेमंद है. हालांकि, यह Java इंटरफ़ेस को लागू करने के लिए इस्तेमाल किए जाने वाले C/C++ में क्रैश होने वाले Java कोड को डीबग करने में भी मदद कर सकता है. यह मददगार है, क्योंकि यह मेमोरी से जुड़ी गड़बड़ियां होने पर उन्हें पकड़ लेता है और आपको सीधे उस कोड पर ले जाता है जिसकी वजह से गड़बड़ी हुई है.
ci.android.com से, पहले से बने HWASan इमेज को उन Pixel डिवाइसों पर फ़्लैश किया जा सकता है जिन पर यह सुविधा काम करती है (सेटअप के बारे में ज़्यादा जानकारी).
क्लासिक ASan की तुलना में, HWASan में ये सुविधाएं हैं:
- सीपीयू का ओवरहेड मिलता-जुलता है (~2x)
- मिलते-जुलते कोड साइज़ का ओवरहेड (40 – 50%)
- ज़्यादा छोटा रैम ओवरहेड (10% – 35%)
HWASan, गड़बड़ी के उन सेट का पता लगाता है जो ASan के जैसे हैं:
- स्टैक और हीप बफ़र ओवरफ़्लो/अंडरफ़्लो
- फ़्री होने के बाद हीप का इस्तेमाल
- स्कोप के बाहर स्टैक का इस्तेमाल करना
- डबल फ़्री/वाइल्ड फ़्री
इसके अलावा, HWASan, स्टैक के इस्तेमाल का पता लगाता है.
HWASan (यह ASan जैसा ही है) और UBSan, दोनों एक साथ किसी टारगेट पर चालू किए जा सकते हैं.
लागू करने से जुड़ी जानकारी और सीमाएं
HWASan, मेमोरी टैगिंग के तरीके पर आधारित है. इसमें, पॉइंटर और मेमोरी पते की रेंज, दोनों के साथ एक छोटी रैंडम टैग वैल्यू जुड़ी होती है. किसी मेमोरी का ऐक्सेस मान्य हो, इसके लिए पॉइंटर और मेमोरी टैग का मेल खाना ज़रूरी है. HWASan, पॉइंटर टैग को पते के सबसे ऊपर वाले बिट में सेव करने के लिए, ARMv8 की सुविधा टॉप बाइट इग्नोर (टीबीआई) पर निर्भर करता है. इसे वर्चुअल पता टैग करना भी कहा जाता है.
HWASan के डिज़ाइन के बारे में ज़्यादा जानने के लिए, Clang दस्तावेज़ की साइट पर जाएं.
डिज़ाइन के हिसाब से, HWASan में ASan के सीमित साइज़ वाले रेडज़ोन नहीं होते, ताकि ज़्यादा मेमोरी इस्तेमाल होने का पता लगाया जा सके. इसके अलावा, इसमें ASan के सीमित क्षमता वाले क्वॉरंटीन भी नहीं होते, ताकि मेमोरी खाली होने के बाद भी उसका इस्तेमाल होने का पता लगाया जा सके. इस वजह से, HWASan किसी गड़बड़ी का पता लगा सकता है, भले ही ओवरफ़्लो कितना भी बड़ा हो या मेमोरी को कितने समय पहले डिएलोकेट किया गया हो. इससे HWASan को ASan से काफ़ी फ़ायदा मिलता है.
हालांकि, HWASan में टैग की संभावित वैल्यू की संख्या सीमित (256) होती है. इसका मतलब है कि प्रोग्राम के एक बार चलने के दौरान, किसी बग को न मिलने की संभावना 0.4% होती है.
ज़रूरी शर्तें
सामान्य Android kernel के नए वर्शन (4.14 और उसके बाद के वर्शन), बिना किसी बदलाव के HWASan के साथ काम करते हैं. Android 10 के लिए बनाई गई खास शाखाओं में, HWASan की सुविधा काम नहीं करती.
HWASan के लिए, Userspace की सुविधा Android 11 से उपलब्ध है.
अगर किसी दूसरे कर्नेल का इस्तेमाल किया जा रहा है, तो HWASan के लिए ज़रूरी है कि Linux कर्नेल, सिस्टम कॉल के आर्ग्युमेंट में टैग किए गए पॉइंटर स्वीकार करे. यह सुविधा, इन अपस्ट्रीम पैचसेट में लागू की गई थी:
- arm64 से टैग किया गया एबीआई पता
- arm64: kernel को पास किए गए यूज़र पॉइंटर को अनटैग करना
- mm: brk()/mmap()/mremap() में वर्चुअल पते के उपनाम बनाने से बचें
- arm64: kernel थ्रेड से कॉल किए गए access_ok() में, टैग किए गए पतों की पुष्टि करना
अगर कस्टम टूलचैन का इस्तेमाल करके बिल्ड किया जा रहा है, तो पक्का करें कि इसमें LLVM के c336557f तक के सभी बदलाव शामिल हों.
HWASan का इस्तेमाल करना
HWASan का इस्तेमाल करके पूरा प्लैटफ़ॉर्म बनाने के लिए, इन निर्देशों का पालन करें:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
सुविधा के लिए, आप प्रॉडक्ट की परिभाषा में SANITIZE_TARGET की सेटिंग जोड़ सकते हैं, जो aosp_coral_hvasan की तरह होती है.
AddressSanitizer की मदद से, उपयोगकर्ताओं के लिए बिल्ड काफ़ी मुश्किल हो गया है:
- make को दो बार चलाने की ज़रूरत नहीं है.
- इंक्रीमेंटल बिल्ड आसान तरीके से काम करता है.
- उपयोगकर्ता के डेटा को फ़्लैश करने की ज़रूरत नहीं है.
AddressSanitizer की कुछ पाबंदियां भी हटा दी गई हैं:
- स्टैटिक एक्सीक्यूटेबल काम करते हैं.
- libc को छोड़कर, किसी भी टारगेट को साफ़ करने की प्रोसेस को छोड़ा जा सकता है. ASan के उलट, यह ज़रूरी नहीं है कि अगर किसी लाइब्रेरी को सैनिटाइज़ किया गया है, तो उससे लिंक किए गए किसी भी एक्सीक्यूटेबल को भी सैनिटाइज़ करना ज़रूरी है.
एक ही (या उससे ज़्यादा) बिल्ड नंबर पर, HWASan और सामान्य इमेज के बीच स्विच किया जा सकता है. डिवाइस को मिटाने की ज़रूरत नहीं है.
किसी मॉड्यूल को साफ़ न करने के लिए,
LOCAL_NOSANITIZE := hwaddress
(Android.mk) या
sanitize: { hwaddress: false }
(Android.bp) का इस्तेमाल करें.
अलग-अलग टारगेट हटाएं
HWASan को सामान्य (बिना साफ़ किए गए) बिल्ड में हर टारगेट के लिए चालू किया जा सकता है. हालांकि, इसके लिए ज़रूरी है कि libc.so
को भी
साफ़ किया गया हो. बायोनिक/libc/Android.bp में मौजूद "libc_defaults"
के सैनिटाइज़ ब्लॉक में hwaddress: true
जोड़ें. इसके बाद, उस टारगेट में भी ऐसा ही करें जिस पर काम किया जा रहा है.
ध्यान दें कि libc को साफ़ करने से, सिस्टम-वाइड हेप मेमोरी के ऐलोकेशन को टैग करने की सुविधा मिलती है. साथ ही, libc.so
में मेमोरी ऑपरेशन के लिए टैग की जांच की जा सकती है. इससे उन बाइनरी में भी गड़बड़ियां पकड़ी जा सकती हैं जिनमें HWASan चालू नहीं था. ऐसा तब होता है, जब गलत मेमोरी ऐक्सेस libc.so
में हो. उदाहरण के लिए, delete()
वाले म्यूटेक्स पर pthread_mutex_unlock()
).
अगर पूरा प्लैटफ़ॉर्म HWASan का इस्तेमाल करके बनाया गया है, तो किसी भी बिल्ड फ़ाइल में बदलाव करने की ज़रूरत नहीं है.
Flashstation
डेवलपमेंट के मकसद से, Flashstation का इस्तेमाल करके, Pixel डिवाइस पर AOSP का HWASan की सुविधा वाला बिल्ड फ़्लैश किया जा सकता है. इसके लिए, डिवाइस का बूटलोडर अनलॉक होना ज़रूरी है. _hwasan टारगेट चुनें, जैसे कि aosp_flame_hwasan-userdebug. ज़्यादा जानकारी के लिए, ऐप्लिकेशन डेवलपर के लिए, HWASan के NDK दस्तावेज़ देखें.
बेहतर स्टैक ट्रेस
HWASan, प्रोग्राम में हर मेमोरी ऐलोकेशन और डिऐलोकेशन इवेंट के लिए, स्टैक ट्रैक रिकॉर्ड करने के लिए, फ़्रेम पॉइंटर पर आधारित तेज़ अनवाइंडर का इस्तेमाल करता है. Android, AArch64 कोड में फ़्रेम पॉइंटर को डिफ़ॉल्ट रूप से चालू करता है,
इसलिए यह सुविधा बेहतर तरीके से काम करती है. अगर आपको मैनेज किए जा रहे कोड के ज़रिए, प्रोसेस के एनवायरमेंट को अनवाइंड करना है, तो प्रोसेस के एनवायरमेंट में HWASAN_OPTIONS=fast_unwind_on_malloc=0
सेट करें. ध्यान दें कि खराब मेमोरी ऐक्सेस वाले स्टैक ट्रेस में डिफ़ॉल्ट रूप से, "धीमे" अनविंडर का इस्तेमाल किया जाता है. इस सेटिंग से सिर्फ़ ऐलोकेशन और डीललोकेशन ट्रेस पर असर पड़ता है. लोड के आधार पर, यह विकल्प बहुत ज़्यादा
सीपीयू का इस्तेमाल कर सकता है.
प्रतीक
"एचडब्ल्यूएएसएन रिपोर्ट को समझना" में, सिंबलाइज़ेशन देखें.
ऐप्लिकेशन में HWASan
AddressSanitizer की तरह, HWASan को Java कोड में नहीं देखा जा सकता. हालांकि, यह JNI लाइब्रेरी में गड़बड़ियों का पता लगा सकता है. Android 14 से पहले, HWASan डिवाइस पर HWASan ऐप्लिकेशन नहीं चलाए जा सकते थे.
HWASan डिवाइस पर, ऐप्लिकेशन की जांच HWASan की मदद से की जा सकती है. इसके लिए, Make में SANITIZE_TARGET:=hwaddress
या कंपाइलर फ़्लैग में -fsanitize=hwaddress
का इस्तेमाल करके, ऐप्लिकेशन का कोड बनाएं.
HWASan के बिना काम करने वाले डिवाइस (Android 14 या उसके बाद के वर्शन पर काम करने वाले डिवाइस) पर, wrap.sh फ़ाइल सेटिंग
LD_HWASAN=1
को जोड़ना होगा.
ज़्यादा जानकारी के लिए,
ऐप्लिकेशन डेवलपर के लिए दस्तावेज़
देखें.