आर्म मेमोरी टैगिंग एक्सटेंशन

आर्म वी9 आर्म मेमोरी टैगिंग एक्सटेंशन (एमटीई) पेश करता है, जो टैग की गई मेमोरी का एक हार्डवेयर कार्यान्वयन है

उच्च स्तर पर, एमटीई प्रत्येक मेमोरी आवंटन/डीललोकेशन को अतिरिक्त मेटाडेटा के साथ टैग करता है। यह मेमोरी लोकेशन के लिए एक टैग निर्दिष्ट करता है, जिसे फिर उस मेमोरी लोकेशन को संदर्भित करने वाले पॉइंटर्स के साथ जोड़ा जा सकता है। रनटाइम पर सीपीयू जाँचता है कि पॉइंटर और मेटाडेटा टैग प्रत्येक लोड और स्टोर पर मेल खाते हैं।

एंड्रॉइड 12 में कर्नेल और यूजरस्पेस हीप मेमोरी एलोकेटर मेटाडेटा के साथ प्रत्येक आवंटन को बढ़ा सकते हैं। यह उपयोग-आफ्टर-फ़्री और बफ़र-ओवरफ़्लो बग का पता लगाने में मदद करता है, जो हमारे कोडबेस में मेमोरी सुरक्षा बग का सबसे आम स्रोत हैं।

एमटीई ऑपरेटिंग मोड

एमटीई के तीन ऑपरेटिंग मोड हैं:

  • सिंक्रोनस मोड (सिंक)
  • अतुल्यकालिक मोड (ASYNC)
  • असममित मोड (ASYMM)

सिंक्रोनस मोड (सिंक)

यह मोड प्रदर्शन की तुलना में बग का पता लगाने की शुद्धता के लिए अनुकूलित है और उच्च प्रदर्शन ओवरहेड स्वीकार्य होने पर इसे सटीक बग पहचान उपकरण के रूप में उपयोग किया जा सकता है। सक्षम होने पर, एमटीई सिंक सुरक्षा शमन के रूप में कार्य करता है। टैग बेमेल होने पर, प्रोसेसर तुरंत निष्पादन रोक देता है और SIGSEGV (कोड SEGV_MTESERR ) और मेमोरी एक्सेस और दोषपूर्ण पते के बारे में पूरी जानकारी के साथ प्रक्रिया को समाप्त कर देता है।

हम HWASan/KASAN के विकल्प के रूप में या उत्पादन में परीक्षण के दौरान इस मोड का उपयोग करने की सलाह देते हैं जब लक्ष्य प्रक्रिया एक कमजोर हमले की सतह का प्रतिनिधित्व करती है। इसके अलावा, जब ASYNC मोड ने बग की उपस्थिति का संकेत दिया है, तो निष्पादन को SYNC मोड में स्विच करने के लिए रनटाइम एपीआई का उपयोग करके एक सटीक बग रिपोर्ट प्राप्त की जा सकती है।

SYNC मोड में चलने पर, एंड्रॉइड एलोकेटर सभी आवंटन और डीलोकेशन के लिए स्टैक ट्रेस रिकॉर्ड करता है और बेहतर त्रुटि रिपोर्ट प्रदान करने के लिए उनका उपयोग करता है जिसमें मेमोरी त्रुटि का स्पष्टीकरण शामिल होता है, जैसे उपयोग-बाद-मुक्त, या बफर-ओवरफ्लो, और स्टैक प्रासंगिक स्मृति घटनाओं के निशान. ऐसी रिपोर्टें अधिक प्रासंगिक जानकारी प्रदान करती हैं और बग का पता लगाना और उन्हें ठीक करना आसान बनाती हैं।

अतुल्यकालिक मोड (ASYNC)

यह मोड बग रिपोर्ट की सटीकता से अधिक प्रदर्शन के लिए अनुकूलित है और इसे मेमोरी सुरक्षा बग के लिए कम-ओवरहेड पहचान के रूप में उपयोग किया जा सकता है।
टैग बेमेल होने पर, प्रोसेसर निकटतम कर्नेल प्रविष्टि (उदाहरण के लिए, एक सिस्कल या टाइमर इंटरप्ट) तक निष्पादन जारी रखता है, जहां यह दोषपूर्ण पते या मेमोरी एक्सेस को रिकॉर्ड किए बिना SIGSEGV (कोड SEGV_MTEAERR ) के साथ प्रक्रिया को समाप्त कर देता है।
हम अच्छी तरह से परीक्षण किए गए कोडबेस पर उत्पादन में इस मोड का उपयोग करने की सलाह देते हैं जहां मेमोरी सुरक्षा बग का घनत्व कम माना जाता है, जिसे परीक्षण के दौरान SYNC मोड का उपयोग करके हासिल किया जाता है।

असममित मोड (ASYMM)

आर्म v8.7-ए में एक अतिरिक्त सुविधा, एसिमेट्रिक एमटीई मोड मेमोरी रीड्स पर सिंक्रोनस चेकिंग और मेमोरी राइट्स की एसिंक्रोनस चेकिंग प्रदान करता है, जिसका प्रदर्शन ASYNC मोड के समान है। अधिकांश स्थितियों में, यह मोड ASYNC मोड में सुधार है, और जब भी यह उपलब्ध हो तो हम ASYNC के बजाय इसका उपयोग करने की सलाह देते हैं।

इस कारण से, नीचे वर्णित कोई भी एपीआई असममित मोड का उल्लेख नहीं करता है। इसके बजाय, एसिंक्रोनस का अनुरोध होने पर ओएस को हमेशा असममित मोड का उपयोग करने के लिए कॉन्फ़िगर किया जा सकता है। कृपया अधिक जानकारी के लिए "सीपीयू-विशिष्ट पसंदीदा एमटीई स्तर को कॉन्फ़िगर करना" अनुभाग देखें।

उपयोक्ता स्थान में एमटीई

निम्नलिखित अनुभाग वर्णन करते हैं कि सिस्टम प्रक्रियाओं और अनुप्रयोगों के लिए एमटीई को कैसे सक्षम किया जा सकता है। एमटीई डिफ़ॉल्ट रूप से अक्षम है, जब तक कि नीचे दिए गए विकल्पों में से एक किसी विशेष प्रक्रिया के लिए सेट न किया गया हो ( नीचे देखें कि एमटीई किन घटकों के लिए सक्षम है)।

बिल्ड सिस्टम का उपयोग करके एमटीई को सक्षम करना

एक प्रक्रिया-व्यापी संपत्ति के रूप में, एमटीई को मुख्य निष्पादन योग्य की निर्माण समय सेटिंग द्वारा नियंत्रित किया जाता है। निम्नलिखित विकल्प अलग-अलग निष्पादनयोग्यों के लिए, या स्रोत ट्री में संपूर्ण उपनिर्देशिकाओं के लिए इस सेटिंग को बदलने की अनुमति देते हैं। सेटिंग को लाइब्रेरीज़, या किसी ऐसे लक्ष्य पर अनदेखा कर दिया जाता है जो न तो निष्पादन योग्य है और न ही परीक्षण योग्य है।

1. किसी विशेष प्रोजेक्ट के लिए Android.bp ( उदाहरण ) में एमटीई सक्षम करना:

एमटीई मोड सेटिंग
अतुल्यकालिक एमटीई
  sanitize: {
  memtag_heap: true,
  }
सिंक्रोनस एमटीई
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

या Android.mk:

एमटीई मोड सेटिंग
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

2. उत्पाद चर का उपयोग करके स्रोत ट्री में उपनिर्देशिका पर एमटीई सक्षम करना:

एमटीई मोड सूची शामिल करें सूची बहिष्कृत करें
async PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
साथ-साथ करना PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

या

एमटीई मोड सेटिंग
अतुल्यकालिक एमटीई MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
सिंक्रोनस एमटीई MEMTAG_HEAP_SYNC_INCLUDE_PATHS

या किसी निष्पादन योग्य के बहिष्कृत पथ को निर्दिष्ट करके:

एमटीई मोड सेटिंग
अतुल्यकालिक एमटीई PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
सिंक्रोनस एमटीई

उदाहरण, ( PRODUCT_CFI_INCLUDE_PATHS के समान उपयोग)

  PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
  PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
                                    vendor/$(vendor)/projectB

सिस्टम गुणों का उपयोग करके एमटीई को सक्षम करना

उपरोक्त बिल्ड सेटिंग्स को निम्न सिस्टम प्रॉपर्टी सेट करके रनटाइम पर ओवरराइड किया जा सकता है:

arm64.memtag.process.<basename> = (off|sync|async)

जहां basename निष्पादन योग्य के आधार नाम के लिए है।

उदाहरण के लिए, एसिंक्रोनस एमटीई का उपयोग करने के लिए /system/bin/ping या /data/local/tmp/ping सेट करने के लिए, adb shell setprop arm64.memtag.process.ping async उपयोग करें।

पर्यावरण चर का उपयोग करके एमटीई को सक्षम करना

बिल्ड सेटिंग को ओवरराइड करने का एक और तरीका पर्यावरण चर को परिभाषित करना है: MEMTAG_OPTIONS=(off|sync|async) यदि पर्यावरण चर और सिस्टम प्रॉपर्टी दोनों परिभाषित हैं, तो चर को प्राथमिकता दी जाती है।

अनुप्रयोगों के लिए एमटीई सक्षम करना

यदि निर्दिष्ट नहीं है तो एमटीई डिफ़ॉल्ट रूप से अक्षम है, लेकिन जो ऐप्स एमटीई का उपयोग करना चाहते हैं वे AndroidManifest.xml में <application> या <process> टैग के तहत android:memtagMode सेट करके ऐसा कर सकते हैं।

android:memtagMode=(off|default|sync|async)

जब <application> टैग पर सेट किया जाता है, तो विशेषता एप्लिकेशन द्वारा उपयोग की जाने वाली सभी प्रक्रियाओं को प्रभावित करती है, और <process> टैग को सेट करके व्यक्तिगत प्रक्रियाओं के लिए ओवरराइड किया जा सकता है।

प्रयोग के लिए, संगतता परिवर्तनों का उपयोग किसी ऐसे एप्लिकेशन के लिए memtagMode विशेषता का डिफ़ॉल्ट मान सेट करने के लिए किया जा सकता है जो मैनिफ़ेस्ट में कोई मान निर्दिष्ट नहीं करता है (या default निर्दिष्ट करता है)।
इन्हें वैश्विक सेटिंग मेनू में System > Advanced > Developer options > App Compatibility Changes के अंतर्गत पाया जा सकता है। NATIVE_MEMTAG_ASYNC या NATIVE_MEMTAG_SYNC सेट करने से किसी विशेष एप्लिकेशन के लिए MTE सक्षम हो जाता है।
वैकल्पिक रूप से, इसे am कमांड का उपयोग करके निम्नानुसार सेट किया जा सकता है:

$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name

एमटीई सिस्टम छवि का निर्माण

हम विकास और पालन-पोषण के दौरान सभी मूल बायनेरिज़ पर एमटीई को सक्षम करने की दृढ़ता से अनुशंसा करते हैं। यह मेमोरी सुरक्षा बग का शीघ्र पता लगाने में मदद करता है और परीक्षण बिल्ड में सक्षम होने पर यथार्थवादी उपयोगकर्ता कवरेज प्रदान करता है।

हम विकास के दौरान सभी मूल बायनेरिज़ पर सिंक्रोनस मोड में एमटीई को सक्षम करने की दृढ़ता से अनुशंसा करते हैं

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

बिल्ड सिस्टम में किसी भी वेरिएबल की तरह, SANITIZE_TARGET उपयोग पर्यावरण वेरिएबल या make सेटिंग के रूप में किया जा सकता है (उदाहरण के लिए, product.mk फ़ाइल में)।
कृपया ध्यान दें कि यह सभी मूल प्रक्रियाओं के लिए एमटीई को सक्षम करता है, लेकिन उन अनुप्रयोगों के लिए नहीं (जो zygote64 से फोर्क किए गए हैं) जिनके लिए ऊपर दिए गए निर्देशों का पालन करके एमटीई को सक्षम किया जा सकता है।

सीपीयू-विशिष्ट पसंदीदा एमटीई स्तर को कॉन्फ़िगर करना

कुछ सीपीयू पर ASYMM या यहां तक ​​कि SYNC मोड में MTE का प्रदर्शन ASYNC के समान हो सकता है। इससे उन सीपीयू पर सख्त जांच को सक्षम करना सार्थक हो जाता है जब कम सख्त जांच मोड का अनुरोध किया जाता है, ताकि प्रदर्शन में गिरावट के बिना सख्त जांच के त्रुटि पता लगाने के लाभ प्राप्त किए जा सकें।
डिफ़ॉल्ट रूप से, ASYNC मोड में चलने के लिए कॉन्फ़िगर की गई प्रक्रियाएँ सभी CPU पर ASYNC मोड में चलेंगी। विशिष्ट सीपीयू पर SYNC मोड में इन प्रक्रियाओं को चलाने के लिए कर्नेल को कॉन्फ़िगर करने के लिए, मूल्य सिंक को बूट समय पर sysfs प्रविष्टि /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred पर लिखा जाना चाहिए। यह एक init स्क्रिप्ट के साथ किया जा सकता है। उदाहरण के लिए, SYNC मोड में ASYNC मोड प्रक्रियाओं को चलाने के लिए CPU 0-1 को कॉन्फ़िगर करने के लिए, और ASYMM मोड में रन का उपयोग करने के लिए CPU 2-3 को, विक्रेता init स्क्रिप्ट के init क्लॉज में निम्नलिखित जोड़ा जा सकता है:

  write /sys/devices/system/cpu/cpu0/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu1/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu2/mte_tcf_preferred asymm
  write /sys/devices/system/cpu/cpu3/mte_tcf_preferred asymm

SYNC मोड में चलने वाली ASYNC मोड प्रक्रियाओं के टॉम्बस्टोन में मेमोरी त्रुटि के स्थान का एक सटीक स्टैक ट्रेस होगा। हालाँकि, उनमें आवंटन या डीलोकेशन स्टैक ट्रेस शामिल नहीं होगा। ये स्टैक ट्रेस केवल तभी उपलब्ध होते हैं जब प्रक्रिया को SYNC मोड में चलाने के लिए कॉन्फ़िगर किया गया हो।

int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

जहां level 0 या 1 है.
मॉलोक में मेमोरी इनिशियलाइज़ेशन को अक्षम करता है, और जब तक शुद्धता के लिए आवश्यक न हो मेमोरी टैग को बदलने से बचता है।

int mallopt(M_MEMTAG_TUNING, level)

level कहां है:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

टैग आवंटन रणनीति का चयन करता है।

  • डिफ़ॉल्ट सेटिंग M_MEMTAG_TUNING_BUFFER_OVERFLOW है।
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW - आसन्न आवंटन के लिए अलग टैग मान निर्दिष्ट करके रैखिक बफर ओवरफ्लो और अंडरफ्लो बग का निर्धारणात्मक पता लगाने में सक्षम बनाता है। इस मोड में उपयोग-बाद-मुक्त बग का पता लगाने की संभावना थोड़ी कम हो गई है क्योंकि प्रत्येक मेमोरी स्थान के लिए संभावित टैग मानों में से केवल आधे ही उपलब्ध हैं। कृपया ध्यान रखें कि एमटीई एक ही टैग ग्रेन्युल (16-बाइट संरेखित खंड) के भीतर ओवरफ्लो का पता नहीं लगा सकता है, और इस मोड में भी छोटे ओवरफ्लो को मिस कर सकता है। इस तरह का अतिप्रवाह मेमोरी भ्रष्टाचार का कारण नहीं हो सकता है, क्योंकि एक ग्रेन्युल के भीतर की मेमोरी का उपयोग कभी भी एकाधिक आवंटन के लिए नहीं किया जाता है।
  • M_MEMTAG_TUNING_UAF - स्थानिक (बफर ओवरफ़्लो) और टेम्पोरल (मुफ़्त के बाद उपयोग) दोनों बग का पता लगाने की समान ~93% संभावना के लिए स्वतंत्र रूप से यादृच्छिक टैग सक्षम करता है।

ऊपर वर्णित एपीआई के अलावा, अनुभवी उपयोगकर्ता निम्नलिखित के बारे में जानना चाहेंगे:

  • PSTATE.TCO हार्डवेयर रजिस्टर सेट करने से टैग चेकिंग अस्थायी रूप से रुक सकती है ( उदाहरण )। उदाहरण के लिए, अज्ञात टैग सामग्री के साथ मेमोरी की एक श्रृंखला की प्रतिलिपि बनाते समय, या हॉट लूप में प्रदर्शन बाधा को संबोधित करते समय।
  • M_HEAP_TAGGING_LEVEL_SYNC का उपयोग करते समय, सिस्टम क्रैश हैंडलर आवंटन और डीलोकेशन स्टैक ट्रेस जैसी अतिरिक्त जानकारी प्रदान करता है। इस कार्यक्षमता के लिए टैग बिट्स तक पहुंच की आवश्यकता होती है और सिग्नल हैंडलर सेट करते समय SA_EXPOSE_TAGBITS ध्वज को पास करके सक्षम किया जाता है। कोई भी प्रोग्राम जो अपना स्वयं का सिग्नल हैंडलर सेट करता है और सिस्टम को अज्ञात क्रैश सौंपता है, उसे भी ऐसा ही करने की अनुशंसा की जाती है।

कर्नेल में एमटीई

कर्नेल के लिए एमटीई-त्वरित KASAN को सक्षम करने के लिए, कर्नेल को CONFIG_KASAN=y , CONFIG_KASAN_HW_TAGS=y से कॉन्फ़िगर करें। ये कॉन्फ़िगरेशन Android 12-5.10 से शुरू होकर, GKI कर्नेल पर डिफ़ॉल्ट रूप से सक्षम हैं।
इसे निम्न कमांड लाइन तर्कों का उपयोग करके बूट समय पर नियंत्रित किया जा सकता है:

  • kasan=[on|off] - KASAN को सक्षम या अक्षम करें (डिफ़ॉल्ट: on )
  • kasan.mode=[sync |async ] - सिंक्रोनस और एसिंक्रोनस मोड के बीच चयन करें (डिफ़ॉल्ट: sync )
  • kasan.stacktrace=[on|off] - क्या स्टैक ट्रेस एकत्र करना है (डिफ़ॉल्ट: on )
    • स्टैक ट्रेस संग्रह के लिए भी stack_depot_disable=off की आवश्यकता होती है।
  • kasan.fault=[report|panic] - क्या केवल रिपोर्ट प्रिंट करनी है, या कर्नेल को भी पैनिक करना है (डिफ़ॉल्ट: report )। इस विकल्प के बावजूद, पहली रिपोर्ट की गई त्रुटि के बाद टैग जाँच अक्षम हो जाती है।

हम पालन-पोषण, विकास और परीक्षण के दौरान SYNC मोड का उपयोग करने की दृढ़ता से अनुशंसा करते हैं। यह विकल्प पर्यावरण चर या बिल्ड सिस्टम का उपयोग करने वाली सभी प्रक्रियाओं के लिए विश्व स्तर पर सक्षम होना चाहिए। इस मोड में, विकास प्रक्रिया के शुरू में ही बग का पता लगा लिया जाता है, कोडबेस को तेजी से स्थिर किया जाता है और बाद में उत्पादन में बग का पता लगाने की लागत से बचा जाता है।

हम उत्पादन में ASYNC मोड का उपयोग करने की पुरजोर अनुशंसा करते हैं। यह एक प्रक्रिया में मेमोरी सुरक्षा बग की उपस्थिति का पता लगाने के साथ-साथ गहराई से बचाव के लिए एक कम ओवरहेड टूल प्रदान करता है। एक बार बग का पता चलने पर, डेवलपर SYNC मोड पर स्विच करने के लिए रनटाइम एपीआई का लाभ उठा सकता है और उपयोगकर्ताओं के नमूना सेट से एक सटीक स्टैक ट्रेस प्राप्त कर सकता है।

हम एसओसी के लिए सीपीयू-विशिष्ट पसंदीदा एमटीई स्तर को कॉन्फ़िगर करने की दृढ़ता से अनुशंसा करते हैं। Asymm मोड में आमतौर पर ASYNC जैसी ही प्रदर्शन विशेषताएँ होती हैं, और यह लगभग हमेशा इसके लिए बेहतर होता है। छोटे इन-ऑर्डर कोर अक्सर तीनों मोड में समान प्रदर्शन दिखाते हैं, और SYNC को प्राथमिकता देने के लिए कॉन्फ़िगर किया जा सकता है।

डेवलपर्स को /data/tombstones , logcat जांच करके या अंतिम उपयोगकर्ता बग के लिए विक्रेता DropboxManager पाइपलाइन की निगरानी करके क्रैश की उपस्थिति की जांच करनी चाहिए। एंड्रॉइड नेटिव कोड को डीबग करने के बारे में अधिक जानकारी के लिए, यहां जानकारी देखें।

एमटीई सक्षम प्लेटफ़ॉर्म घटक

एंड्रॉइड 12 में, कई सुरक्षा महत्वपूर्ण सिस्टम घटक अंतिम उपयोगकर्ता क्रैश का पता लगाने और रक्षा-गहराई की एक अतिरिक्त परत के रूप में कार्य करने के लिए एमटीई ASYNC का उपयोग करते हैं। ये घटक हैं:

  • नेटवर्किंग डेमॉन और उपयोगिताएँ ( netd के अपवाद के साथ)
  • ब्लूटूथ, सिक्योरएलिमेंट, एनएफसी एचएएल और सिस्टम एप्लिकेशन
  • statsd डेमॉन
  • system_server
  • zygote64 (एप्लिकेशन को MTE का उपयोग करने के लिए ऑप्ट-इन करने की अनुमति देने के लिए)

इन लक्ष्यों का चयन निम्नलिखित मानदंडों के आधार पर किया गया था:

  • एक विशेषाधिकार प्राप्त प्रक्रिया (एक ऐसी प्रक्रिया के रूप में परिभाषित जिसकी किसी चीज़ तक पहुंच है जो कि unprivileged_app SELinux डोमेन के पास नहीं है)
  • अविश्वसनीय इनपुट को प्रोसेस करता है ( दो का नियम )
  • स्वीकार्य प्रदर्शन मंदी (धीमी गति से उपयोगकर्ता को दृश्यमान विलंबता नहीं मिलती)

हम विक्रेताओं को ऊपर उल्लिखित मानदंडों का पालन करते हुए अधिक घटकों के उत्पादन में एमटीई को सक्षम करने के लिए प्रोत्साहित करते हैं। विकास के दौरान हम आसानी से ठीक किए गए बग का पता लगाने और उनके प्रदर्शन पर ASYNC प्रभाव का आकलन करने के लिए SYNC मोड का उपयोग करके इन घटकों का परीक्षण करने की सलाह देते हैं।
भविष्य में, एंड्रॉइड आगामी हार्डवेयर डिज़ाइनों की प्रदर्शन विशेषताओं द्वारा निर्देशित, एमटीई सक्षम सिस्टम घटकों की सूची का विस्तार करने की योजना बना रहा है।