اطّلِع على فهم تقارير HWASan للحصول على معلومات حول كيفية قراءة أعطال HWASan.
Hardware-assisted AddressSanitizer (HWASan) هي أداة لاكتشاف أخطاء الذاكرة تشبه أداة AddressSanitizer. يستخدم HWASan ذاكرة وصول عشوائي أقل بكثير مقارنةً بـ ASan، ما يجعله مناسبًا لتنظيف النظام بأكمله. لا تتوفّر أداة HWASan إلا على الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث، وعلى أجهزة AArch64 فقط.
على الرغم من أنّ HWASan مفيد بشكل أساسي لرموز C/C++ البرمجية، يمكن أن يساعد أيضًا في تصحيح أخطاء رموز Java البرمجية التي تتسبّب في حدوث أعطال في رموز C/C++ المستخدَمة لتنفيذ واجهات Java. وهي مفيدة لأنّها ترصد أخطاء الذاكرة عند حدوثها، وتوجّهك مباشرةً إلى الرمز المسؤول.
مقارنةً بـ ASan الكلاسيكية، تتضمّن HWASan ما يلي:
- تكلفة مماثلة لوحدة المعالجة المركزية (CPU) (أكثر من الضعف تقريبًا)
- زيادة حجم الرمز البرمجي المشابه (من 40 إلى 50%)
- استخدام أقل بكثير لذاكرة الوصول العشوائي (من 10% إلى 35%)
يرصد HWASan مجموعة الأخطاء نفسها التي يرصدها ASan:
- فائض سعة المخزن المؤقت أو نقصها في المكدّس والكومة
- استخدام الذاكرة بعد تحريرها
- استخدام الحزمة خارج النطاق
- Double free/wild free
بالإضافة إلى ذلك، يرصد HWASan استخدام الذاكرة المخصّصة للمكدّس بعد العودة.
يتوافق HWASan (مثل ASan) مع UBSan، ويمكن تفعيل كليهما على هدف في الوقت نفسه.
تفاصيل التنفيذ والقيود
تستند أداة HWASan إلى أسلوب وضع علامات على الذاكرة، حيث يتم ربط قيمة علامة عشوائية صغيرة بكل من المؤشرات ونطاقات عناوين الذاكرة. لكي يكون الوصول إلى الذاكرة صالحًا، يجب أن تتطابق العلامات الخاصة بالمؤشر والذاكرة. تعتمد أداة HWASan على ميزة تجاهل البايت العلوي (TBI) في ARMv8، والتي تُعرف أيضًا باسم وضع علامات على العناوين الافتراضية، لتخزين علامة المؤشر في أعلى بتات العنوان.
يمكنك الاطّلاع على مزيد من المعلومات حول تصميم HWASan على الموقع الإلكتروني لمستندات Clang.
لا يتضمّن HWASan، بحسب تصميمه، مناطق حمراء محدودة الحجم مثل ASan لرصد حالات تجاوز سعة المخزن المؤقت، أو حجر صحي محدود السعة مثل ASan لرصد حالات الاستخدام بعد التحرير. لهذا السبب، يمكن لأداة HWASan رصد خطأ بغض النظر عن حجم تجاوز سعة المخزن المؤقت أو المدة التي انقضت منذ إلغاء تخصيص الذاكرة. يمنح ذلك HWASan ميزة كبيرة مقارنةً بـ ASan.
ومع ذلك، يتيح HWASan عددًا محدودًا من قيم العلامات المحتملة (256)، ما يعني أنّ هناك احتمالاً بنسبة% 0.4 لعدم رصد أي خطأ أثناء تنفيذ البرنامج مرة واحدة.
المتطلبات
تتوافق الإصدارات الحديثة (4.14 والإصدارات الأحدث) من نواة Android الشائعة مع HWASan بدون الحاجة إلى أي إعدادات إضافية. لا تتوافق فروع Android 10 المحدّدة مع HWASan.
يتوفّر دعم مساحة المستخدم لأداة HWASan بدءًا من Android 11.
إذا كنت تعمل باستخدام نواة مختلفة، يتطلّب HWASan أن تقبل نواة Linux المؤشرات الموسومة في وسيطات استدعاء النظام. تمت إضافة هذه الميزة في حِزم التصحيح التالية:
- واجهة ABI لعناوين arm64 الموسومة
- arm64: إزالة العلامات من مؤشرات المستخدمين التي يتم تمريرها إلى النواة
- mm: تجنَّب إنشاء أسماء مستعارة لعناوين افتراضية في brk()/mmap()/mremap()
- arm64: التحقّق من صحة العناوين الموسومة في الدالة access_ok() التي يتم استدعاؤها من سلاسل تعليمات النواة
إذا كنت تستخدم مجموعة أدوات مخصّصة، تأكَّد من أنّها تتضمّن كل شيء حتى إصدار 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
أيضًا. أضِف hwaddress: true
إلى كتلة التنظيف في "libc_defaults"
في bionic/libc/Android.bp. بعد ذلك، نفِّذ الخطوات نفسها في المستند الهدف الذي تعمل عليه.
يُرجى العِلم أنّ تنظيف libc يتيح وضع علامات على عمليات تخصيص ذاكرة الكومة على مستوى النظام، بالإضافة إلى التحقّق من العلامات لعمليات الذاكرة داخل libc.so
. قد يؤدي ذلك إلى رصد الأخطاء حتى في الرموز الثنائية التي لم يتم تفعيل HWASan عليها إذا كان الوصول غير السليم إلى الذاكرة في libc.so
(مثلاً pthread_mutex_unlock()
على mutex delete()
ed).
ليس من الضروري تغيير أي ملفات إنشاء إذا تم إنشاء النظام الأساسي بالكامل باستخدام 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
.
يمكنك الاطّلاع على
مستندات مطوّري التطبيقات
لمزيد من التفاصيل.