AddressSanitizer به کمک سخت افزار

برای اطلاعات در مورد نحوه خواندن خرابی های HWASan به درک گزارش های HWASan مراجعه کنید!

AddressSanitizer با کمک سخت افزار (HWASan) یک ابزار تشخیص خطای حافظه مشابه AddressSanitizer است. HWASan در مقایسه با ASan از رم بسیار کمتری استفاده می کند که آن را برای پاکسازی کل سیستم مناسب می کند. HWASan فقط در اندروید 10 و بالاتر و فقط روی سخت افزار AArch64 در دسترس است.

اگرچه HWASan اساساً برای کدهای C/C++ مفید است، اما HWASan همچنین می‌تواند به اشکال‌زدایی کد جاوا کمک کند که باعث خرابی در C/C++ مورد استفاده برای پیاده‌سازی رابط‌های جاوا می‌شود. این کار مفید است زیرا خطاهای حافظه را در صورت وقوع پیدا می کند و مستقیماً به کد مسئول اشاره می کند.

می‌توانید تصاویر HWASan از پیش ساخته شده را از ci.android.com ( دستورالعمل‌های دقیق راه‌اندازی ) روی دستگاه‌های پیکسل پشتیبانی‌شده فلاش کنید.

در مقایسه با ASan کلاسیک، HWASan دارای:

  • سربار CPU مشابه (~2x)
  • سربار اندازه کد مشابه (40 تا 50%)
  • سربار رم بسیار کوچکتر (10٪ - 35٪)

HWASan همان مجموعه ای از اشکالات ASan را شناسایی می کند:

  • سرریز/زیر جریان بافر پشته و پشته
  • استفاده از پشته پس از رایگان
  • پشته استفاده خارج از محدوده
  • دو برابر رایگان / وحشی رایگان

علاوه بر این، HWASan استفاده از پشته را پس از بازگشت تشخیص می دهد.

HWASan (همان ASan) با UBSan سازگار است، هر دو را می توان همزمان روی یک هدف فعال کرد.

جزئیات و محدودیت های پیاده سازی

HWASan مبتنی بر رویکرد برچسب‌گذاری حافظه است، که در آن یک مقدار تگ تصادفی کوچک هم با اشاره‌گرها و هم با محدوده‌ای از آدرس‌های حافظه مرتبط است. برای اینکه دسترسی به حافظه معتبر باشد، نشانگر و برچسب حافظه باید مطابقت داشته باشند. HWASan برای ذخیره تگ اشاره گر در بالاترین بیت های آدرس، بر روی ویژگی ARMv8 بایت نادیده گرفته شده (TBI) که به آن برچسب گذاری آدرس مجازی نیز گفته می شود، متکی است.

می توانید اطلاعات بیشتری در مورد طراحی HWASan در سایت مستندات Clang بخوانید.

طبق طراحی، HWASan مناطق قرمز با اندازه محدود ASan برای تشخیص سرریزها یا قرنطینه با ظرفیت محدود ASan برای تشخیص استفاده پس از رایگان ندارد. به همین دلیل، HWASan می‌تواند یک باگ را بدون توجه به اینکه سرریز زیاد باشد یا مدت‌ها پیش حافظه اختصاص داده شده است، شناسایی کند. این به HWASan یک مزیت بزرگ نسبت به ASan می دهد.

با این حال، HWASan دارای تعداد محدودی از مقادیر برچسب ممکن است (256)، که به این معنی است که احتمال 0.4٪ از دست رفتن هر گونه اشکال در طول یک اجرای برنامه وجود دارد.

الزامات

نسخه های اخیر (4.14+) هسته رایج اندروید از HWASan خارج از جعبه پشتیبانی می کنند. شاخه های خاص اندروید 10 از HWASan پشتیبانی نمی کنند.

پشتیبانی از فضای کاربری برای HWASan از اندروید 11 در دسترس است.

اگر با هسته دیگری کار می کنید، HWASan از هسته لینوکس می خواهد که نشانگرهای برچسب گذاری شده را در آرگومان های فراخوانی سیستم بپذیرد. پشتیبانی از این در پچ‌ست‌های بالادستی زیر پیاده‌سازی شد:

اگر با یک زنجیره ابزار سفارشی می‌سازید، مطمئن شوید که همه چیز تا LLVM commit c336557f را شامل می‌شود.

از HWASan استفاده کنید

از دستورات زیر برای ساخت کل پلتفرم با استفاده از HWASan استفاده کنید:

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

برای راحتی، می‌توانید تنظیم SANITIZE_TARGET را به تعریف محصول، مشابه aosp_coral_hwasan اضافه کنید.

برای کاربرانی که با AddressSanitizer آشنا هستند، بسیاری از پیچیدگی های ساخت از بین رفته است:

  • نیازی به دوبار اجرا نیست.
  • ساخت های افزایشی خارج از جعبه کار می کنند.
  • نیازی به فلش کردن اطلاعات کاربری نیست.

برخی از محدودیت‌های AddressSanitizer نیز از بین رفته‌اند:

  • فایل های اجرایی استاتیک پشتیبانی می شوند.
  • اشکالی ندارد که از پاکسازی هر هدفی به جز libc صرفنظر کنید. برخلاف ASan، هیچ الزامی وجود ندارد که اگر کتابخانه ای پاکسازی شود، هر فایل اجرایی که به آن پیوند می دهد نیز باید باشد.

جابجایی بین HWASan و تصاویر معمولی با همان شماره ساخت (یا بالاتر) می تواند آزادانه انجام شود. پاک کردن دستگاه لازم نیست.

برای رد شدن از پاکسازی یک ماژول، از LOCAL_NOSANITIZE := hwaddress (Android.mk) یا sanitize: { hwaddress: false } (Android.bp) استفاده کنید.

اهداف فردی را ضدعفونی کنید

تا زمانی که libc.so نیز ضدعفونی شده باشد، HWASan را می‌توان به ازای هر هدف در یک ساخت معمولی (غیر عفونی‌شده) فعال کرد. hwaddress: true به بلوک پاکسازی در "libc_defaults" در bionic/libc/Android.bp. سپس همین کار را در هدفی که روی آن کار می کنید انجام دهید.

توجه داشته باشید که پاک‌سازی libc برچسب‌گذاری تخصیص حافظه پشته در سراسر سیستم و همچنین بررسی تگ‌ها برای عملیات حافظه در داخل libc.so را امکان‌پذیر می‌کند. اگر دسترسی بد به حافظه در libc.so باشد (مثلاً pthread_mutex_unlock() در یک delete() ed mutex) ممکن است حتی در باینری‌هایی که HWASan در آن‌ها فعال نشده باشد، باگ‌هایی پیدا کند.

اگر کل پلتفرم با استفاده از HWASan ساخته شده باشد، نیازی به تغییر هیچ فایل ساختی نیست.

فلش استیشن

برای اهداف توسعه، می‌توانید با استفاده از Flashstation ، یک بیلد AOSP دارای HWASan را روی دستگاه Pixel با بوت‌لودر آنلاک فلش کنید. هدف _hwasan را انتخاب کنید، به عنوان مثال aosp_flame_hwasan-userdbug. برای جزئیات بیشتر به مستندات NDK برای HWASan برای توسعه دهندگان برنامه مراجعه کنید.

ردیابی های پشته ای بهتر

HWASan از یک بازکردن سریع و مبتنی بر اشاره گر فریم برای ثبت یک ردیابی پشته برای هر تخصیص حافظه و رویداد تخصیص در برنامه استفاده می کند. اندروید به طور پیش فرض نشانگرهای فریم را در کد AArch64 فعال می کند، بنابراین در عمل عالی عمل می کند. اگر نیاز به باز کردن کد مدیریت شده دارید، HWASAN_OPTIONS=fast_unwind_on_malloc=0 در محیط فرآیند تنظیم کنید. توجه داشته باشید که ردیابی پشته دسترسی بد به حافظه به طور پیش‌فرض از بازکردن آهسته استفاده می‌کند. این تنظیم فقط بر روی تخصیص و ردیابی توزیع تأثیر می گذارد. این گزینه بسته به بار می تواند بسیار CPU فشرده باشد.

نمادسازی

نمادسازی را در "درک گزارش های HWASan" ببینید.

HWASan در برنامه ها

مشابه AddressSanitizer، HWASan نمی تواند کدهای جاوا را ببیند، اما می تواند اشکالات موجود در کتابخانه های JNI را شناسایی کند. تا قبل از Android 14، اجرای برنامه های HWASan در دستگاه غیر HWASan پشتیبانی نمی شد.

در دستگاه HWASan، برنامه‌ها را می‌توان با ساخت کدشان با SANITIZE_TARGET:=hwaddress در Make، یا -fsanitize=hwaddress در پرچم‌های کامپایلر، با HWASan بررسی کرد. در دستگاه غیر HWASan (دارای Android نسخه 14 یا جدیدتر)، باید یک تنظیم فایل wrap.sh LD_HWASAN=1 اضافه شود. برای جزئیات بیشتر به مستندات برنامه‌نویس برنامه مراجعه کنید.