हार्डवेयर की मदद से काम करने वाला AddressSanitizer

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 की सुविधा टॉप बाइट इग्नोर (टीबीआई) पर निर्भर करता है. इसे वर्चुअल पता टैगिंग भी कहा जाता है.

Clang के दस्तावेज़ों की साइट पर, HWASan के डिज़ाइन के बारे में ज़्यादा पढ़ा जा सकता है.

डिज़ाइन के हिसाब से, HWASan में ASan के सीमित साइज़ वाले रेडज़ोन नहीं होते, ताकि ज़्यादा मेमोरी इस्तेमाल होने का पता लगाया जा सके. इसके अलावा, इसमें ASan के सीमित क्षमता वाले क्वॉरंटीन भी नहीं होते, ताकि मेमोरी खाली होने के बाद भी उसका इस्तेमाल होने का पता लगाया जा सके. इस वजह से, HWASan किसी गड़बड़ी का पता लगा सकता है, भले ही ओवरफ़्लो कितना भी बड़ा हो या मेमोरी को कितने समय पहले डिएलोकेट किया गया हो. इससे, ASan की तुलना में HWASan को काफ़ी फ़ायदा मिलता है.

हालांकि, HWASan में टैग की संभावित वैल्यू की संख्या सीमित (256) होती है. इसका मतलब है कि प्रोग्राम के एक बार चलने के दौरान, किसी बग को न मिलने की संभावना 0.4% होती है.

ज़रूरी शर्तें

सामान्य Android kernel के नए वर्शन (4.14 और उसके बाद के वर्शन), बिना किसी बदलाव के HWASan के साथ काम करते हैं. Android 10 के लिए बनी खास शाखाओं में, HWASan की सुविधा काम नहीं करती.

HWASan के लिए, Userspace की सुविधा Android 11 से उपलब्ध है.

अगर किसी दूसरे कर्नेल का इस्तेमाल किया जा रहा है, तो HWASan के लिए ज़रूरी है कि Linux कर्नेल, सिस्टम कॉल के आर्ग्युमेंट में टैग किए गए पॉइंटर स्वीकार करे. इसके लिए, अपस्ट्रीम पैचसेट में यह सुविधा लागू की गई थी:

अगर कस्टम टूलचैन का इस्तेमाल करके बिल्ड किया जा रहा है, तो पक्का करें कि इसमें LLVM के c336557f तक के सभी बदलाव शामिल हों.

HWASan का इस्तेमाल करना

HWASan का इस्तेमाल करके पूरा प्लैटफ़ॉर्म बनाने के लिए, इन निर्देशों का पालन करें:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

आसानी के लिए, किसी प्रॉडक्ट की परिभाषा में SANITIZE_TARGET सेटिंग जोड़ी जा सकती है. यह सेटिंग, aosp_coral_hwasan जैसी ही होती है.

AddressSanitizer के बारे में जानने वाले उपयोगकर्ताओं के लिए, अब बिल्ड करने में ज़्यादा मुश्किल नहीं होती:

  • make को दो बार चलाने की ज़रूरत नहीं है.
  • इंक्रीमेंटल बिल्ड, बिना किसी सेटअप के काम करते हैं.
  • उपयोगकर्ता के डेटा को फ़्लैश करने की ज़रूरत नहीं है.

AddressSanitizer की कुछ पाबंदियां भी हटा दी गई हैं:

  • स्टैटिक एक्सीक्यूटेबल काम करते हैं.
  • libc को छोड़कर, किसी भी टारगेट को साफ़ करने की प्रोसेस को छोड़ा जा सकता है. ASan के उलट, यह ज़रूरी नहीं है कि अगर किसी लाइब्रेरी को सैनिटाइज़ किया गया है, तो उससे लिंक की गई किसी भी एक्सीक्यूटेबल को भी सैनिटाइज़ करना होगा.

एक ही (या उससे ज़्यादा) बिल्ड नंबर पर, HWASan और सामान्य इमेज के बीच स्विच किया जा सकता है. डिवाइस को मिटाने की ज़रूरत नहीं है.

किसी मॉड्यूल को साफ़ न करने के लिए, LOCAL_NOSANITIZE := hwaddress (Android.mk) या sanitize: { hwaddress: false } (Android.bp) का इस्तेमाल करें.

अलग-अलग टारगेट को साफ़ करना

HWASan को सामान्य (बिना साफ़ किए गए) बिल्ड में हर टारगेट के लिए चालू किया जा सकता है. हालांकि, इसके लिए ज़रूरी है कि libc.so को भी साफ़ किया गया हो. bionic/libc/Android.bp में, "libc_defaults" के hwaddress: true में मौजूद sanitize ब्लॉक में hwaddress: true जोड़ें. इसके बाद, उस टारगेट में भी ऐसा ही करें जिस पर काम किया जा रहा है.

ध्यान दें कि libc को साफ़ करने से, सिस्टम-वाइड हेप मेमोरी के ऐलोकेशन को टैग करने की सुविधा मिलती है. साथ ही, libc.so में मेमोरी ऑपरेशन के लिए टैग की जांच की जा सकती है. इससे उन बाइनरी में भी गड़बड़ियां पकड़ी जा सकती हैं जिनमें HWASan चालू नहीं था. ऐसा तब होता है, जब गलत मेमोरी ऐक्सेस libc.so में हो. उदाहरण के लिए, pthread_mutex_unlock() पर delete() किया गया म्यूटेक्स).

अगर पूरा प्लैटफ़ॉर्म 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 को जोड़ना होगा. ज़्यादा जानकारी के लिए, ऐप्लिकेशन डेवलपर के लिए दस्तावेज़ देखें.