العنوان

AddressSanitizer (ASan) هي أداة سريعة تعتمد على المترجم لاكتشاف أخطاء الذاكرة في الكود الأصلي.

يكتشف ASan:

  • كومة و كومة تجاوز سعة المخزن المؤقت / تحت التدفق
  • استخدام كومة بعد مجانا
  • كومة استخدام خارج النطاق
  • مزدوج مجاني / مجاني بري

يعمل ASan على كل من ARM 32 بت و 64 بت ، بالإضافة إلى x86 و x86-64. تبلغ النفقات العامة لوحدة المعالجة المركزية من ASan تقريبًا 2x ، ويتراوح حجم حجم الشفرة بين 50٪ و 2x ، ونفقات ذاكرة كبيرة (تعتمد على أنماط التخصيص الخاصة بك ، ولكن بترتيب 2x).

الروبوت (10) وفرع سيد AOSP على AArch64 دعم تسارع الأجهزة اسان (HWASan) ، وهي أداة مماثلة مع انخفاض النفقات العامة RAM وأكبر مجموعة من الحشرات المكتشفة. يكتشف HWASan استخدام المكدس بعد الإرجاع ، بالإضافة إلى الأخطاء التي اكتشفها ASan.

HWASan لديه نفس حجم وحدة المعالجة المركزية وحجم الكود ، ولكن ذاكرة RAM أقل بكثير (15٪). HWASan غير حتمي. لا يوجد سوى 256 قيمة علامة محتملة ، لذلك هناك احتمال ثابت بنسبة 0.4٪ لفقدان أي خطأ. لا يحتوي HWASan على مناطق حمراء ذات حجم محدود من ASan لاكتشاف التدفقات الزائدة والحجر الصحي ذي السعة المحدودة للكشف عن الاستخدام بعد الاستخدام ، لذلك لا يهم HWASan حجم الفائض أو المدة التي تم فيها إلغاء تخصيص الذاكرة. هذا يجعل HWASan أفضل من ASan. يمكنك قراءة المزيد عن تصميم HWASan أو حول استخدام HWASan على الروبوت .

يكتشف ASan التدفقات المكدسة / العالمية بالإضافة إلى تدفقات الكومة ، وهو سريع مع الحد الأدنى من الذاكرة الزائدة.

يصف هذا المستند كيفية إنشاء وتشغيل أجزاء / كل أجهزة Android باستخدام ASan. إذا كنت بناء SDK / التطبيق NDK مع اسان، انظر عنوان المطهر بدلا من ذلك.

تعقيم الملفات التنفيذية الفردية باستخدام ASan

إضافة LOCAL_SANITIZE:=address أو sanitize: { address: true } لحكم بناء القابل للتنفيذ. يمكنك البحث في الكود عن أمثلة موجودة أو للعثور على المطهرات الأخرى المتاحة.

عندما تم الكشف عن الأخطاء، يطبع اسان في تقرير مطول على حد سواء إلى الإخراج القياسي و logcat ثم تعطل العملية.

تعقيم المكتبات المشتركة مع ASan

نظرًا للطريقة التي يعمل بها ASan ، لا يمكن استخدام المكتبة التي تم إنشاؤها باستخدام ASan إلا بواسطة ملف قابل للتنفيذ تم إنشاؤه باستخدام ASan.

لتعقيم مكتبة مشتركة مستخدمة في ملفات تنفيذية متعددة ، ليست كلها مبنية باستخدام ASan ، فأنت بحاجة إلى نسختين من المكتبة. الطريقة الموصى بها للقيام بذلك هي لإضافة ما يلي إلى Android.mk للوحدة في السؤال التالي:

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

هذا يضع المكتبة في /system/lib/asan بدلا من /system/lib . بعد ذلك ، قم بتشغيل الملف التنفيذي الخاص بك باستخدام:

LD_LIBRARY_PATH=/system/lib/asan

لالشياطين النظام، إضافة ما يلي إلى القسم المناسب من /init.rc أو /init.$device$.rc .

setenv LD_LIBRARY_PATH /system/lib/asan

تحقق من أن عملية يستخدم المكتبات من /system/lib/asan عندما تكون موجودة من قبل القراءة /proc/$PID/maps . إذا لم يكن الأمر كذلك ، فقد تحتاج إلى تعطيل SELinux:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

أفضل آثار المكدس

يستخدم ASan أداة فك اللفة سريعة تعتمد على مؤشر الإطار لتسجيل تتبع المكدس لكل تخصيص للذاكرة وحدث إلغاء تخصيص في البرنامج. تم تصميم معظم أجهزة Android بدون مؤشرات الإطارات. نتيجة لذلك ، غالبًا ما تحصل على إطار واحد أو إطارين مهمين. لإصلاح ذلك ، قم بإعادة بناء المكتبة باستخدام ASan (موصى به!) ، أو باستخدام:

LOCAL_CFLAGS:=-fno-omit-frame-pointer
LOCAL_ARM_MODE:=arm

أو مجموعة ASAN_OPTIONS=fast_unwind_on_malloc=0 في البيئة العملية. يمكن أن يكون هذا الأخير شديد الاستخدام لوحدة المعالجة المركزية ، اعتمادًا على الحمل.

الترميز

في البداية ، تحتوي تقارير ASan على مراجع للإزاحات في الثنائيات والمكتبات المشتركة. هناك طريقتان للحصول على الملف المصدر ومعلومات الخط:

  • تأكد من أن llvm-symbolizer ثنائي موجود في /system/bin . llvm-symbolizer بنيت من مصادر في third_party/llvm/tools/llvm-symbolizer .
  • تصفية التقرير من خلال external/compiler-rt/lib/asan/scripts/symbolize.py النصي.

يمكن النهج الثاني توفير المزيد من البيانات (أي، file:line المواقع) بسبب توافر المكتبات يرمز على المضيف.

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

لا يمكن لـ ASan رؤية كود Java ، ولكن يمكنه اكتشاف الأخطاء في مكتبات JNI. لذلك، تحتاج لبناء قابل للتنفيذ مع اسان، وهو في هذه الحالة هو /system/bin/app_process( 32|64 ) . يمكّن هذا ASan في جميع التطبيقات الموجودة على الجهاز في نفس الوقت ، وهو حمل ثقيل ، ولكن يجب أن يكون الجهاز الذي يحتوي على ذاكرة وصول عشوائي سعتها 2 جيجابايت قادرًا على التعامل مع هذا.

إضافة LOCAL_SANITIZE:=address ل app_process حكم البناء في frameworks/base/cmds/app_process . تجاهل app_process__asan الهدف في نفس الملف في الوقت الحالي (اذا كان لا يزال هناك في الوقت الذي تقرأ هذا).

تحرير service zygote قسم من المناسب system/core/rootdir/init.zygote( 32|64 ).rc ملف لإضافة الأسطر التالية إلى كتلة من خطوط بادئة التي تحتوي على class main ، بادئة أيضا من قبل نفس المبلغ:

    setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
    setenv ASAN_OPTIONS allow_user_segv_handler=true

إنشاء ومزامنة adb وإقلاع فلاش fastboot وإعادة التشغيل.

باستخدام خاصية الالتفاف

يضع النهج في القسم السابق ASan في كل تطبيق في النظام (في الواقع ، في كل سليل من عملية Zygote). من الممكن تشغيل تطبيق واحد (أو عدة) فقط باستخدام ASan ، مع استبدال بعض حمل الذاكرة من أجل بدء تشغيل أبطأ للتطبيق.

ويمكن القيام بذلك عن طريق بدء التطبيق الخاص بك مع wrap. خاصية. يعمل المثال التالي على تشغيل تطبيق Gmail ضمن ASan:

adb root
adb shell setenforce 0  # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"

وفي هذا السياق، asanwrapper يعيد كتابة /system/bin/app_process ل /system/bin/asan/app_process ، التي بنيت مع اسان. كما يضيف /system/lib/asan في بداية الطريق ديناميكية البحث المكتبة. بهذه الطريقة المكتبات اسان المجهزة-من /system/lib/asan هي المفضلة للمكتبات العادية في /system/lib عند تشغيل مع asanwrapper .

إذا تم العثور على خطأ ، فإن التطبيق يتعطل ، ويتم طباعة التقرير في السجل.

SANITIZE_TARGET

يتضمن Android 7.0 والإصدارات الأحدث دعمًا لبناء نظام Android الأساسي بالكامل باستخدام ASan في وقت واحد. (إذا كنت تقوم بإنشاء إصدار أعلى من Android 9 ، فإن HWASan هو خيار أفضل.)

قم بتشغيل الأوامر التالية في نفس شجرة البناء.

make -j42
SANITIZE_TARGET=address make -j42

في هذا الوضع، userdata.img يحتوي على مكتبات اضافية ويجب أن تومض إلى الجهاز كذلك. استخدم سطر الأوامر التالي:

fastboot flash userdata && fastboot flashall

هذا يبني مجموعتين من المكتبات المشتركة: عادي في /system/lib (أول جعل الاحتجاج)، واسان المجهزة في /data/asan/lib (ثاني جعل الاحتجاج). الكتابة التنفيذية من البناء الثاني على تلك من البناء الأول. التنفيذية المجهزة اسان-الحصول على مسار البحث مكتبة المختلفة التي تشمل /data/asan/lib قبل /system/lib من خلال استخدام /system/bin/linker_asan في PT_INTERP .

وclobbers نظام بناء المتوسطة الدلائل الكائن عند $SANITIZE_TARGET تغيرت قيمة. هذه القوات لإعادة بناء من جميع الأهداف مع الحفاظ على ثنائيات المثبتة ضمن /system/lib .

لا يمكن بناء بعض الأهداف باستخدام ASan:

  • الملفات التنفيذية المرتبطة إحصائيًا
  • LOCAL_CLANG:=false أهداف
  • LOCAL_SANITIZE:=false لا ASan'd ل SANITIZE_TARGET=address

يتم تخطي التنفيذية مثل هذه في SANITIZE_TARGET بناء، ويتم ترك نسخة من أول جعل الاحتجاج في /system/bin .

مكتبات مثل هذه مبنية بدون ASan. يمكن أن تحتوي على بعض رموز ASan من المكتبات الثابتة التي يعتمدون عليها.

الوثائق الداعمة