تفعيل إضافة وضع علامات الذاكرة

توفّر بنية Arm v9 إضافة وضع علامات الذاكرة (MTE) من Arm، وهي تنفيذ على مستوى الأجهزة لميزة "الذاكرة التي تم وضع علامات عليها".

على مستوى عالٍ، تضع ميزة MTE علامة على كل عملية تخصيص/إلغاء تخصيص للذاكرة باستخدام بيانات وصفية إضافية. وتخصّص علامة لموقع في الذاكرة، ويمكن بعد ذلك ربطها بالمؤشرات التي تشير إلى هذا الموقع في الذاكرة. أثناء التشغيل، تتحقّق وحدة المعالجة المركزية من تطابق المؤشر وعلامات البيانات الوصفية عند كل عملية تحميل وتخزين.

في Android 12، يمكن لموزّع ذاكرة "كومة" مساحة المستخدم والنواة إضافة بيانات وصفية إلى كل عملية تخصيص. يساعد ذلك في رصد أخطاء الاستخدام بعد تحرير الذاكرة ومشاكل فائض المخزن المؤقت، وهي المصدر الأكثر شيوعًا لأخطاء أمان الذاكرة في رموزنا البرمجية.

أوضاع تشغيل ميزة إضافة وضع علامات الذاكرة (MTE)

تتضمّن ميزة "إضافة وضع علامات الذاكرة" ثلاثة أوضاع تشغيل:

  • الوضع المتزامن (SYNC)
  • الوضع غير المتزامن (ASYNC)
  • الوضع غير المتماثل (ASYMM)

الوضع المتزامن (SYNC)

تم تحسين هذا الوضع لضمان دقة رصد الأخطاء على حساب الأداء، ويمكن استخدامه كأداة دقيقة لرصد الأخطاء، عندما يكون ارتفاع تكلفة الأداء مقبولاً. عند تفعيل ميزة "مزامنة إضافة وضع علامات الذاكرة"، تعمل هذه الميزة كإجراء لتخفيف مخاطر الأمان. في حال عدم تطابق العلامة، يوقف المعالج التنفيذ على الفور ويُنهي العملية باستخدام SIGSEGV (رمز SEGV_MTESERR) والمعلومات الكاملة عن الوصول إلى الذاكرة وعنوان الخطأ.

ننصحك باستخدام هذا الوضع أثناء الاختبار كبديل لميزة HWASan/KASAN أو في مرحلة الإنتاج عندما تمثّل العملية المستهدَفة سطح هجوم معرّضًا للضعف. بالإضافة إلى ذلك، عندما يشير وضع ASYNC إلى وجود خطأ ، يمكن الحصول على تقرير خطأ دقيق باستخدام واجهات برمجة التطبيقات لوقت التشغيل لتبديل التنفيذ إلى وضع SYNC.

عند التشغيل في وضع SYNC، يسجِّل مخصّص الذاكرة في Android عمليات تتبُّع تسلسل استدعاء الدوالّ لجميع عمليات تخصيص الذاكرة وإلغاء تخصيصها ويستخدمها لتقديم تقارير أخطاء أفضل تتضمّن شرحًا لخطأ في الذاكرة، مثل استخدام ذاكرة معيّنة بعد تفريغها أو تجاوز المخزن المؤقت للذاكرة الديناميكية، وعمليات تتبُّع تسلسل استدعاء الدوالّ لأحداث الذاكرة ذات الصلة. توفّر هذه التقارير المزيد من المعلومات السياقية، ويسهّل بالتالي تتبُّع الأخطاء وإصلاحها.

الوضع غير المتزامن (ASYNC)

تم تحسين هذا الوضع للأداء على دقة تقارير الأخطاء ويمكن استخدامه كطريقة خفيفة التحميل لرصد أخطاء أمان الذاكرة.
في حال عدم تطابق العلامة، يواصل المعالج التنفيذ إلى أن يصل إلى أقرب إدخال في النواة (على سبيل المثال، طلب نظام التشغيل أو المقاطعة المبرمَجة للوقت)، حيث يُنهي العملية باستخدام SIGSEGV (الرمز SEGV_MTEAERR) بدون تسجيل عنوان الخطأ أو الوصول إلى الذاكرة.
ننصحك باستخدام هذا الوضع في مرحلة الإنتاج على قواعد بيانات تم اختبارها جيدًا ويُعرف أنّ كثافة أخطاء أمان الذاكرة فيها منخفضة، ويتم تحقيق ذلك باستخدام وضع "مزامنة" أثناء الاختبار.

الوضع غير المتماثل (ASYMM)

يقدّم وضع Asymmetric MTE، وهو ميزة إضافية في Arm v8.7-A، فحصًا متزامنًا لعمليات قراءة الذاكرة وفحصًا غير متزامن لعمليات كتابة الذاكرة، بأداء مشابه لأداء وضع ASYNC. في معظم الحالات، يُعدّ هذا الوضع تحسُّنًا على وضع ASYNC، وننصح باستخدامه بدلاً من ASYNC كلما كان متاحًا.

لهذا السبب، لا تشير أي من واجهات برمجة التطبيقات الموضّحة أدناه إلى وضع Asymmetric. بدلاً من ذلك، يمكن ضبط نظام التشغيل لاستخدام الوضع غير المتماثل دائمًا عند طلب الوضع غير المتزامن. يُرجى الرجوع إلى قسم "ضبط مستوى MTE المفضّل الخاص بالمعالج المركزي" للحصول على مزيد من المعلومات.

اختبار MTE في مساحة المستخدم

توضّح الأقسام التالية كيفية تفعيل ميزة MTE لعمليات النظام والتطبيقات. تكون ميزة MTE غير مفعّلة تلقائيًا، ما لم يتم تحديد أحد الخيارات أدناه لعملية معيّنة (اطّلِع على المكوّنات التي تكون ميزة MTE مفعّلة فيها أدناه).

تفعيل إضافة وضع علامات الذاكرة (MTE) باستخدام نظام الإنشاء

وبما أنّ إضافة وضع علامات الذاكرة هي خاصيّة على مستوى العملية، يتم التحكّم فيها من خلال إعداد وقت الإنشاء للملف التنفيذي الرئيسي. تتيح الخيارات التالية تغيير هذا الإعداد لملف تنفيذي فردي أو لملفّات فرعية كاملة في شجرة المصدر. يتم تجاهل الإعداد في المكتبات أو أيّ هدف ليس قابلاً للتنفيذ أو اختبارًا.

‫1. تفعيل ميزة "إضافة وضع علامات الذاكرة" في Android.bp (مثال)، لمشروع معيّن:

وضع MTE الإعدادات
إضافة وضع علامات الذاكرة غير المتزامنة
  sanitize: {
  memtag_heap: true,
  }
MTE المتزامن
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

أو في Android.mk:

وضع MTE الإعدادات
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

‫2- تفعيل إضافة وضع علامات الذاكرة (MTE) على دليل فرعي في شجرة المصدر باستخدام متغيّر المنتج:

وضع MTE تضمين القائمة قائمة الاستبعاد
غير متزامن 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

أو

وضع MTE الإعدادات
إضافة وضع علامات الذاكرة غير المتزامنة MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MTE المتزامن MEMTAG_HEAP_SYNC_INCLUDE_PATHS

أو من خلال تحديد مسار استبعاد ملف تنفيذي:

وضع MTE الإعدادات
إضافة وضع علامات الذاكرة غير المتزامنة PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
MTE المتزامن

مثال (استخدام مشابه لرمز PRODUCT_CFI_INCLUDE_PATHS)

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

تفعيل إضافة وضع علامات الذاكرة (MTE) باستخدام خصائص النظام

يمكن إلغاء إعدادات الإنشاء أعلاه أثناء التشغيل من خلال ضبط سمة النظام التالية:

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

حيث يشير basename إلى الاسم الأساسي للملف القابل للتنفيذ.

على سبيل المثال، لضبط /system/bin/ping أو /data/local/tmp/ping لاستخدام MTE غير المتزامن، استخدِم adb shell setprop arm64.memtag.process.ping async.

تفعيل إضافة وضع علامات الذاكرة باستخدام متغيّر بيئة

هناك طريقة أخرى لإلغاء إعدادات الإنشاء وهي من خلال تحديد متغيّر البيئة: MEMTAG_OPTIONS=(off|sync|async) في حال تحديد متغيّر البيئة وخاصية النظام، يكون للمتغيّر الأولوية.

تفعيل إضافة وضع علامات الذاكرة (MTE) للتطبيقات

في حال عدم تحديده، يتم إيقاف MTE تلقائيًا، ولكن يمكن للتطبيقات التي تريد استخدام MTE إجراء ذلك من خلال ضبط android:memtagMode ضمن علامة <application> أو <process> في AndroidManifest.xml.

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

إنشاء صورة نظام MTE

ننصحك بشدة بتفعيل ميزة MTE في جميع الملفات الثنائية الأصلية أثناء التطوير والإعداد. يساعد ذلك في رصد أخطاء أمان الذاكرة في وقت مبكر ويوفّر تغطية واقعية للمستخدمين، في حال تفعيله في النُسخ الاختبارية.

ننصحك بشدة بتفعيل ميزة MTE في الوضع المتزامن على جميع الملفات الثنائية الأصلية أثناء التطوير.

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

كما هو الحال مع أي متغيّر في نظام الإنشاء، يمكن استخدام SANITIZE_TARGET كمتغيّر بيئة أو إعداد make (على سبيل المثال، في ملف product.mk).
يُرجى العلم أنّ هذا الإجراء يؤدي إلى تفعيل ميزة MTE لجميع العمليات الأصلية، ولكن ليس لتطبيقات (التي تمّت فوركتها من zygote64) التي يمكن تفعيل ميزة MTE فيها باتّباع التعليمات الواردة أعلاه.

ضبط مستوى MTE المفضّل الخاص بوحدة المعالجة المركزية

في بعض وحدات المعالجة المركزية، قد يكون أداء MTE في وضع ASYMM أو حتى وضع SYNC مشابهًا لأداء ASYNC. لهذا السبب، من المفيد تفعيل عمليات التحقّق الأكثر صرامة على وحدات المعالجة المركزية هذه عند طلب وضع التحقّق الأقل صرامة، وذلك بهدف الاستفادة من مزايا رصد الأخطاء في عمليات التحقّق الأكثر صرامة بدون التحمّل لسلبيات الأداء.
سيتم تشغيل العمليات التي تم ضبطها لتعمل في وضع ASYNC تلقائيًا في وضع ASYNC على جميع وحدات المعالجة المركزية. لضبط النواة لتشغيل هذه العمليات في وضع SYNC على معالجات مركزية معيّنة، يجب كتابة مزامنة القيمة في إدخال sysfs /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred أثناء التمهيد. ويمكن إجراء ذلك باستخدام نص برمجي لبدء التشغيل. على سبيل المثال، لضبط وحدات المعالجة المركزية من 0 إلى 1 لتشغيل عمليات وضع ASYNC في وضع SYNC، ووحدات المعالجة المركزية من 2 إلى 3 لاستخدام وضع التشغيل في وضع ASYMM، يمكن إضافة ما يلي إلى عبارة 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

ستحتوي شواهد القبور من عمليات وضع ASYNC التي تعمل في وضع SYNC على أثر تتبع تسلسل استدعاء الدوال البرمجية دقیق لمكان خطأ الذاكرة. ومع ذلك، لن يتم تضمين تتبع تسلسل استدعاء الدوال البرمجية لعمليات تخصيص الذاكرة أو إلغاء تخصيصها. لا تتوفّر هذه عمليات تتبُّع تسلسل استدعاء الدوالّ إلا في حال ضبط العملية لتعمل في وضع "مزامنة".

int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

حيث يكون level هو 0 أو 1.
يوقف هذا الخيار إعداد الذاكرة في malloc، ويتجنّب تغيير علامات الذاكرة ما لم يكن ذلك ضروريًا للتأكد من صحة الإجراء.

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 - يتيح رصدًا دقيقًا لأخطاء تجاوز سعة المخزن المؤقت الخطي ونقصها من خلال تعيين قيم علامة مختلفة للعمليات المجاورة. يقلّ احتمال رصد أخطاء الاستخدام بعد تحرير الذاكرة في هذا الوضع قليلاً لأنّ نصف قيم العلامات المحتملة فقط متاح لكل موقع ذاكرة. يُرجى العِلم أنّ ميزة MTE لا يمكنها رصد فائض البيانات ضمن وحدة العلامة نفسها (القطعة المُحاذية التي تبلغ 16 بايت)، ويمكن أن تفوت فائض البيانات الصغير حتى في هذا الوضع. ولا يمكن أن يكون هذا التجاوز سببًا في فساد ملف تعريف الارتباط ، لأنّه لا يتم أبدًا استخدام الذاكرة ضمن حبيبة واحدة في عمليات تخصيص متعددة.
  • M_MEMTAG_TUNING_UAF - تفعِّل علامات عشوائية بشكل مستقل لاحتمالات متسقة تبلغ% 93 تقريبًا لرصد كلّ من الأخطاء المكانية (تدفّق المخزن المؤقت) والأخطاء الزمنية (الاستخدام بعد تحرير الذاكرة).

بالإضافة إلى واجهات برمجة التطبيقات الموضّحة أعلاه، قد يريد المستخدمون المجرّبون معرفة ما يلي:

  • يمكن أن يؤدي ضبط سجلّ الأجهزةPSTATE.TCO إلى إيقاف التحقّق من العلامة مؤقتًا (مثال). على سبيل المثال، عند نسخ نطاق من الذاكرة يحتوي على محتوى علامة غير معروف، أو عند معالجة مشكلة قيود الأداء في حلقة ساخنة.
  • عند استخدام M_HEAP_TAGGING_LEVEL_SYNC، يقدّم معالِج الأعطال في النظام معلومات إضافية، مثل عمليات تتبُّع تسلسل استدعاء الدوال البرمجية لعمليات التخصيص وإلغاء التخصيص. تتطلّب هذه الوظيفة الوصول إلى أجزاء العلامة ويتم تفعيلها من خلال تمرير العلامة SA_EXPOSE_TAGBITS عند ضبط معالِج الإشارات. أي برنامج يحدّد معالِج إشارة خاص به ويفوّض الأعطال غير المعروفة إلى النظام، يُنصح به اتّباع الإجراء نفسه.

ميزة MTE في النواة

لتفعيل KASAN المُسرَّع باستخدام MTE للنواة، عليك ضبط النواة باستخدام CONFIG_KASAN=y وCONFIG_KASAN_HW_TAGS=y. تكون هذه الإعدادات مفعَّلة تلقائيًا في نواة GKI، بدءًا من الإصدار Android 12-5.10.
يمكن التحكّم في ذلك أثناء عملية التشغيل باستخدام وسيطات سطر الأوامر التالية:

  • kasan=[on|off] - تفعيل KASAN أو إيقافه (الإعداد التلقائي: on)
  • kasan.mode=[sync|async] - الاختيار بين الوضع المتزامن وغير المتزامن (التلقائي: sync)
  • kasan.stacktrace=[on|off] - ما إذا كان سيتم جمع أثر تسلسل استدعاء الدوال البرمجية (تلقائيًا: on)
    • تتطلب أيضًا عملية جمع "تتبُّع تسلسل استدعاء الدوال البرمجية" استخدام stack_depot_disable=off.
  • kasan.fault=[report|panic] - يشير إلى ما إذا كان سيتم طباعة التقرير فقط، أو أيضًا إرسال إشارة الذعر إلى النواة (الإعداد التلقائي: report). بغض النظر عن هذا الخيار، يتم إيقاف التحقّق من العلامة بعد ظهور أول خطأ يتم الإبلاغ عنه.

ننصحك بشدة باستخدام وضع "مزامنة" أثناء عملية الإعداد والتطوير والاختبار. يجب تفعيل هذا الخيار بشكل عام لجميع العمليات التي تستخدم متغيّر البيئة أو نظام الإنشاء. في هذا الوضع، يتم رصد الأخطاء في مرحلة مبكّرة من عملية التطوير، ويتم استقرار قاعدة الرموز البرمجية بشكل أسرع، ويُتجنّب تكاليف رصد الأخطاء لاحقًا في مرحلة الإنتاج.

ننصح بشدة باستخدام وضع ASYNC في مرحلة الإنتاج. توفّر هذه الأداة تكلفة منخفضة لرصد وجود أخطاء في أمان الذاكرة في إحدى العمليات، بالإضافة إلى تعزيز الدفاع المفصّل. بعد رصد خطأ، يمكن للمطوّر الاستفادة من واجهات برمجة التطبيقات لوقت التشغيل للتبديل إلى وضع "مزامنة" والحصول على تتبع دقيق للمسار في الذاكرة من مجموعة تم اختيار عيّنات منها من المستخدمين.

ننصحك بشدة بضبط مستوى MTE المفضّل الخاص بوحدة المعالجة المركزية لوحدة المعالجة المركزية (SoC). يمتلك وضع Asymm عادةً خصائص الأداء نفسها التي يمتلكها وضع ASYNC، وهو مفضّل عنه دائمًا تقريبًا. غالبًا ما تُظهر النوى الصغيرة للمعالجة غير المتعدّدة المهام أداءً مشابهًا في جميع الأوضاع الثلاثة، ويمكن ضبطها لتفضيل وضع SYNC.

على المطوّرين التحقّق من حدوث الأعطال من خلال التحقّق من /data/tombstones، logcat أو من خلال مراقبة مسار DropboxManager المورّد بحثًا عن الأخطاء في تطبيق المستخدم النهائي. لمزيد من المعلومات حول تصحيح أخطاء الرموز البرمجية الأصلية لنظام التشغيل Android، يمكنك الاطّلاع على المعلومات هنا.

مكونات المنصة التي تم تفعيل ميزة إضافة وضع علامات الذاكرة (MTE) فيها

في نظام التشغيل Android 12، يستخدم عدد من مكوّنات النظام المهمة من حيث الأمان واجهة MTE ASYNC لرصد الأعطال لدى المستخدم النهائي ولتوفير طبقة إضافية من الدفاع المتعدّد الطبقات. وتشمل هذه المكوّنات ما يلي:

  • برامج الخدمات وبرامج الخدمات المتعلقة بالشبكات (باستثناء netd)
  • بلوتوث وSecureElement وواجهات برمجة التطبيقات لبروتوكول NFC وتطبيقات النظام
  • statsd برنامج خفي
  • system_server
  • zygote64 (للسماح للتطبيقات بالموافقة على استخدام MTE)

تم اختيار هذه الاستهدافات استنادًا إلى المعايير التالية:

  • عملية مميّزة (يُقصد بها عملية يمكنها الوصول إلى محتوى لا يمكن لنطاق SELinux unprivileged_app الوصول إليه)
  • معالجة إدخال غير موثوق به (قاعدة من اثنتين)
  • انخفاض مقبول في الأداء (لا يؤدي الانخفاض إلى حدوث وقت استجابة ملحوظ للمستخدم)

ونشجّع المورّدين على تفعيل ميزة MTE في مرحلة الإنتاج لعدد أكبر من المكوّنات، وفقًا للمعايير المذكورة أعلاه. أثناء التطوير، ننصحك باختبار هذه المكوّنات باستخدام وضع SYNC لرصد الأخطاء التي يمكن إصلاحها بسهولة وتقييم أثر ASYNC في أدائها.
في المستقبل، يخطّط فريق Android لتوسيع قائمة مكوّنات النظام التي يتم تفعيل ميزة MTE فيها، استنادًا إلى خصائص الأداء لتصاميم الأجهزة القادمة.