أداة AddressSanitizer المستندة إلى الأجهزة

يُرجى الاطّلاع على مقالة فهم تقارير HWASan للحصول على معلومات حول كيفية قراءة الأعطال التي يرصدها HWASan!

‫Hardware-assisted AddressSanitizer (HWASan) هي أداة لرصد أخطاء الذاكرة تشبه AddressSanitizer. يستخدم HWASan ذاكرة وصول عشوائي (RAM) أقل بكثير مقارنةً بـ ASan، ما يجعله مناسبًا لـ تنظيف النظام بأكمله. لا يتوفّر HWASan إلا على الإصدار 10 من Android والإصدارات الأحدث، وعلى أجهزة AArch64 فقط.

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

مقارنةً بـ ASan الكلاسيكي، يتضمّن HWASan ما يلي:

  • نفس الحمل الزائد لوحدة المعالجة المركزية (CPU) (ضعف الحمل تقريبًا)
  • نفس الحمل الزائد لحجم الرمز (من 40% إلى 50%)
  • حمل زائد أصغر بكثير على ذاكرة الوصول العشوائي (من 10% إلى 35%)

يرصد HWASan المجموعة نفسها من الأخطاء التي يرصدها ASan:

  • فائض سعة المخزن المؤقت أو نقصها في المكدس والذاكرة المخصّصة
  • استخدام الذاكرة المخصّصة بعد تفريغها
  • استخدام المكدس خارج النطاق
  • تفريغ الذاكرة مرّتين أو تفريغها بشكل غير متوقّع

بالإضافة إلى ذلك، يرصد HWASan استخدام المكدس بعد العودة.

يتوافق HWASan (مثل ASan) مع UBSan, ويمكن تفعيل كلتيهما على هدف في الوقت نفسه.

تفاصيل التنفيذ والقيود

يستند HWASan إلى الـ ذاكرة التي تم وضع علامات عليها، حيث يتم ربط قيمة علامة عشوائية صغيرة بالمؤشرات ونطاقات عناوين الذاكرة. لكي يكون الوصول إلى الذاكرة صالحًا، يجب أن تتطابق العلامات على المؤشر والذاكرة. يعتمد HWASan على ميزة تجاهل البايت العلوي (TBI) في ARMv8، والتي تُعرف أيضًا باسم وضع علامات على العنوان الظاهري، لتخزين علامة المؤشر في الـ أعلى بتات العنوان.

يمكنك قراءة المزيد عن تصميم HWASan على موقع مستندات Clang الإلكتروني.

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

ومع ذلك، يتضمّن HWASan عددًا محدودًا من قيم العلامات المحتمَلة (256)، ما يعني أنّ هناك احتمالاً بنسبة% 0.4 لعدم رصد أي خطأ أثناء تنفيذ البرنامج مرة واحدة.

المتطلبات

تتوافق الإصدارات الحديثة (4.14 والإصدارات الأحدث) من نواة Android الشائعة مع HWASan على الفور. لا تتوافق الفروع الخاصة بالإصدار 10 من Android مع HWASan.

يتوفّر دعم مساحة المستخدم لـ HWASan بدءًا من الإصدار 11 من Android.

إذا كنت تستخدم نواة مختلفة، يتطلّب HWASan أن تقبل نواة Linux المؤشرات التي تم وضع علامات عليها في وسيطات طلبات النظام. تم تنفيذ هذا الدعم في مجموعات التصحيحات التالية في المصدر الرئيسي:

إذا كنت تنشئ باستخدام سلسلة أدوات مخصّصة، تأكَّد من أنّها تتضمّن كل شيء حتى عملية الإيداع c336557f في LLVM.

استخدام HWASan

استخدِم الأوامر التالية لإنشاء المنصة بأكملها باستخدام HWASan:

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

لتسهيل الأمر، يمكنك إضافة الإعداد SANITIZE_TARGET إلى تعريف منتج، على غرار aosp_coral_hwasan.

بالنسبة إلى المستخدمين الذين يعرفون AddressSanitizer، تم التخلّص من الكثير من تعقيدات عملية الإنشاء:

  • لا حاجة إلى تشغيل الأمر make مرّتين.
  • تعمل عمليات الإنشاء التزايدية على الفور.
  • لا حاجة إلى تثبيت ذاكرة ROM لبيانات المستخدم.

تم أيضًا التخلّص من بعض قيود AddressSanitizer:

  • يمكن استخدام الملفات التنفيذية الثابتة.
  • يمكنك تخطّي تنظيف أي هدف باستثناء libc. على عكس ASan، ليس هناك شرط بأنّه إذا تم تنظيف مكتبة، يجب أيضًا تنظيف أي ملف تنفيذي يرتبط بها.

يمكنك التبديل بحرية بين HWASan والصور العادية بنفس رقم الإصدار (أو رقم إصدار أعلى) وليس عليك محو بيانات الجهاز.

لتخطّي تنظيف وحدة، استخدِم LOCAL_NOSANITIZE := hwaddress (في ملف Android.mk) أو sanitize: { hwaddress: false } (في ملف Android.bp).

تنظيف الأهداف الفردية

يمكن تفعيل HWASan لكل هدف في عملية إنشاء عادية (غير نظيفة)، طالما تم أيضًا تنظيف libc.so هو أيضًا تنظيفه. أضِف hwaddress: true إلى كتلة التنظيف في "libc_defaults" في bionic/libc/Android.bp. بعد ذلك، نفِّذ الإجراء نفسه في الهدف الذي تعمل عليه.

يُرجى العِلم أنّ تنظيف libc يتيح وضع علامات على عمليات تخصيص الذاكرة المخصّصة على مستوى النظام، بالإضافة إلى الـ تحقّق من العلامات لعمليات الذاكرة داخل libc.so. قد يؤدي ذلك إلى رصد الأخطاء حتى في الملفات الثنائية التي لم يتم تفعيل HWASan عليها إذا كان الوصول إلى الذاكرة غير السليم في libc.so (مثلاً، pthread_mutex_unlock() على ذاكرة mutex تم تنفيذ delete() عليها).

ليس من الضروري تغيير أي ملفات إنشاء إذا تم إنشاء المنصة بأكملها باستخدام HWASan.

عمليات تتبُّع أفضل للمكدس

يستخدم HWASan أداة سريعة لإزالة الإطارات تستند إلى مؤشر الإطار لتسجيل عملية تتبُّع المكدس لكل حدث تخصيص وإلغاء تخصيص للذاكرة في البرنامج. تفعِّل Android مؤشرات الإطار في رمز AArch64 تلقائيًا، لذا فإنّ هذه الميزة تعمل بشكل رائع في الواقع. إذا كنت بحاجة إلى إزالة الإطارات من خلال الرمز المُدار، اضبط HWASAN_OPTIONS=fast_unwind_on_malloc=0 في بيئة العملية. يُرجى العِلم أنّ عمليات تتبُّع المكدس للوصول إلى الذاكرة غير السليم تستخدم أداة إزالة الإطارات "البطيئة" تلقائيًا، ولا يؤثر هذا الإعداد إلا في عمليات تتبُّع التخصيص وإلغاء التخصيص. يمكن أن يكون هذا الخيار مكثّفًا جدًا لوحدة المعالجة المركزية، وذلك حسب الحمل.

وضع الرموز

يُرجى الاطّلاع على مقالة وضع الرموز في "فهم تقارير HWASan".

HWASan في التطبيقات

على غرار AddressSanitizer، لا يمكن أن يرى HWASan رمز Java، ولكن يمكنه رصد الأخطاء في مكتبات JNI. حتى الإصدار 14 من Android، كان تشغيل تطبيقات HWASan على جهاز لا يستخدم HWASan غير مدعوم.

على جهاز يستخدم HWASan، يمكن التحقّق من التطبيقات باستخدام HWASan من خلال إنشاء رمزها باستخدام SANITIZE_TARGET:=hwaddress في Make أو -fsanitize=hwaddress في علامات المحول البرمجي. على جهاز لا يستخدم HWASan (يعمل بالإصدار 14 من Android أو إصدار أحدث)، يجب إضافة ملف wrap.sh يضبط LD_HWASAN=1 يُرجى الاطّلاع على مستندات المطوّرين للتطبيق للحصول على مزيد من التفاصيل.