टैग किए गए पॉइंटर

Android 11 से, 64-बिट प्रोसेस के लिए, सभी हेप ऐलोकेशन में, डिवाइसों पर पॉइंटर के सबसे ऊपर वाले बाइट में, लागू करने के लिए तय किया गया टैग सेट होता है. ऐसा उन डिवाइसों पर किया जाता है जिनमें ARM टॉप-बाइट इग्नोर (टीबीआई) के लिए, कर्नेल की सुविधा होती है. अगर कोई ऐप्लिकेशन इस टैग में बदलाव करता है, तो ऐप्लिकेशन को बंद कर दिया जाता है. ऐसा तब होता है, जब ऐप्लिकेशन को डिएलोकेट करने के दौरान टैग की जांच की जाती है. आने वाले समय में, ARM मेमोरी टैगिंग एक्सटेंशन (एमटीई) की सुविधा वाले हार्डवेयर के लिए, यह ज़रूरी है.

टॉप-बाइट को अनदेखा करना

ARM की टॉप-बाइट अनदेखा करने की सुविधा, सभी Armv8 AArch64 हार्डवेयर में 64-बिट कोड के लिए उपलब्ध है. इस सुविधा का मतलब है कि मेमोरी ऐक्सेस करते समय, हार्डवेयर किसी पॉइंटर के सबसे ऊपर वाले बाइट को अनदेखा करता है.

टीबीआई के लिए, काम करने वाले एक कोर की ज़रूरत होती है, जो यूज़रस्पेस से पास किए गए टैग किए गए पॉइंटर को सही तरीके से मैनेज करता हो. Android के 4.14 (Pixel 4) और उसके बाद के वर्शन के सामान्य कर्नेल में, ज़रूरी TBI पैच मौजूद होते हैं.

जिन डिवाइसों के कर्नेल में टीबीआई की सुविधा काम करती है उनका पता, प्रोसेस शुरू होने के समय डाइनैमिक तौर पर लगाया जाता है. साथ ही, सभी हेप एलोकेशन के लिए पॉइंटर के सबसे ऊपर वाले बाइट में, लागू करने के तरीके पर निर्भर टैग डाला जाता है. इसके बाद, यह जांच की जाती है कि मेमोरी को डिअलॉक करते समय, टैग को छोटा तो नहीं किया गया है.

मेमोरी टैगिंग एक्सटेंशन के इस्तेमाल के लिए ज़रूरी शर्तें

ARM का मेमोरी टैगिंग एक्सटेंशन (एमटीई), मेमोरी की सुरक्षा से जुड़ी समस्याओं को हल करने में मदद करता है. एमटीई, स्टैक, हेप, और ग्लोबल पर हर मेमोरी ऐलोकेशन के 56वें से 59वें ऐड्रेस बिट को टैग करके काम करता है. हार्डवेयर और निर्देश सेट, अपने-आप यह जांच करता है कि हर मेमोरी ऐक्सेस के लिए सही टैग का इस्तेमाल किया गया है या नहीं.

जिन Android ऐप्लिकेशन में पॉइंटर के सबसे ऊपर वाले बाइट में गलत तरीके से जानकारी सेव की जाती है वे MTE की सुविधा वाले डिवाइस पर काम नहीं करेंगे. टैग किए गए पॉइंटर की मदद से, MTE डिवाइसों के उपलब्ध होने से पहले, पॉइंटर के टॉप बाइट के गलत इस्तेमाल का पता लगाना और उसे अस्वीकार करना आसान हो जाता है.

डेवलपर सहायता

अगर आपका ऐप्लिकेशन क्रैश हो गया और आपको यह लिंक दिखाया गया, तो इसका मतलब इनमें से कोई एक हो सकता है:

  1. ऐप्लिकेशन ने ऐसे पॉइंटर को खाली करने की कोशिश की जिसे सिस्टम के ढेर के एलोकेटर ने ऐलोकेट नहीं किया था.
  2. आपके ऐप्लिकेशन में कुछ ऐसा हुआ है जिसकी वजह से पॉइंटर के सबसे ऊपर वाले बाइट में बदलाव हुआ है. पॉइंटर के सबसे ऊपर वाले बाइट में बदलाव नहीं किया जा सकता. इस समस्या को ठीक करने के लिए, आपको अपने कोड में बदलाव करना होगा.

टॉप बाइट पॉइंटर के गलत इस्तेमाल या उसमें बदलाव किए जाने के उदाहरण.

  • किसी खास टाइप के पॉइंटर में, ऐप्लिकेशन के हिसाब से मेटाडेटा होता है. यह मेटाडेटा, पते के सबसे ऊपर के 16 बिट में सेव होता है.
  • पॉइंटर को दोगुना करने के बाद वापस लाया गया, जिससे पता के निचले हिस्से के बिट हट गए.
  • कोड, अलग-अलग स्टैक फ़्रेम से स्थानीय वैरिएबल के पतों के बीच के अंतर का हिसाब लगाता है. ऐसा, रेक्यूर्सन की गहराई को मेज़र करने के लिए किया जाता है.

ऐसा हो सकता है कि कुछ ऐप्लिकेशन ऐसी लाइब्रेरी पर निर्भर हों जो पॉइंटर का टॉप बाइट सेट होने पर गलत तरीके से काम करती हों. हम समझते हैं कि लाइब्रेरी में मौजूद इन समस्याओं को जल्दी ठीक करना आसान नहीं है. इसलिए, targetSdkLevel < 30 का इस्तेमाल करने वाले ऐप्लिकेशन में, पॉइंटर टैगिंग की सुविधा डिफ़ॉल्ट रूप से चालू नहीं होगी. हम targetSdkLevel >= 30 के साथ बनाए गए ऐप्लिकेशन के लिए, ट्रांज़िशन की अवधि को आसान बनाने के लिए, एक 'एस्केप हैच' भी उपलब्ध कराते हैं.

अपनी AndroidManifest.xml फ़ाइल में ये चीज़ें जोड़कर, बचने के लिए इस्तेमाल किया जाता है:

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

इससे आपके ऐप्लिकेशन के लिए, पॉइंटर टैग करने की सुविधा बंद हो जाती है. हालांकि, इससे कोड की परफ़ॉर्मेंस से जुड़ी समस्या हल नहीं होती. Android के आने वाले वर्शन में यह सुविधा नहीं होगी. ऐसा इसलिए, क्योंकि इस तरह की समस्याएं MTE के साथ काम नहीं करेंगी.