پسوند برچسب گذاری حافظه بازو

Arm v9 Extension برچسب‌گذاری حافظه Arm (MTE) را معرفی می‌کند که یک پیاده‌سازی سخت‌افزاری از حافظه برچسب‌گذاری شده است.

در سطح بالایی، MTE هر تخصیص/تخصیص حافظه را با ابرداده اضافی برچسب گذاری می کند. یک تگ به یک مکان حافظه اختصاص می دهد، که سپس می تواند با اشاره گرهایی که به آن مکان حافظه اشاره می کنند مرتبط شود. در زمان اجرا، CPU بررسی می کند که نشانگر و تگ های فراداده در هر بارگذاری و ذخیره مطابقت دارند.

در اندروید 12، تخصیص دهنده حافظه هسته و فضای کاربران می تواند هر تخصیص را با ابرداده افزایش دهد. این به شناسایی باگ‌های بدون استفاده و سرریز بافر، که رایج‌ترین منبع اشکالات ایمنی حافظه در پایگاه‌های کد ما هستند، کمک می‌کند.

حالت های عملیاتی MTE

MTE دارای سه حالت عملیاتی است:

  • حالت همزمان (SYNC)
  • حالت ناهمزمان (ASYNC)
  • حالت نامتقارن (ASYMM)

حالت همزمان (SYNC)

این حالت برای صحت تشخیص اشکال بیش از عملکرد بهینه شده است و می تواند به عنوان یک ابزار دقیق تشخیص اشکال استفاده شود، زمانی که سربار عملکرد بالاتر قابل قبول باشد. وقتی فعال باشد، MTE SYNC به عنوان یک کاهش امنیتی عمل می کند. در صورت عدم تطابق تگ، پردازنده بلافاصله اجرا را متوقف می کند و با SIGSEGV (کد SEGV_MTESERR ) و اطلاعات کامل در مورد دسترسی به حافظه و آدرس خطا، فرآیند را خاتمه می دهد.

ما توصیه می کنیم از این حالت در حین آزمایش به عنوان جایگزینی برای HWASan/KASAN یا در هنگام تولید استفاده کنید، زمانی که فرآیند هدف یک سطح حمله آسیب پذیر را نشان می دهد. علاوه بر این، زمانی که حالت ASYNC وجود یک باگ را نشان می‌دهد، می‌توان با استفاده از APIهای زمان اجرا برای تغییر اجرا به حالت SYNC، گزارش اشکال دقیقی به دست آورد.

هنگامی که در حالت SYNC اجرا می شود، تخصیص دهنده اندروید ردپای پشته را برای همه تخصیص ها و تخصیص ها ثبت می کند و از آنها برای ارائه گزارش های خطای بهتری استفاده می کند که شامل توضیح یک خطای حافظه مانند استفاده پس از آزاد شدن، یا سرریز بافر و پشته است. ردپای رویدادهای مربوط به حافظه چنین گزارش هایی اطلاعات متنی بیشتری را ارائه می دهند و ردیابی و رفع اشکالات را آسان تر می کنند.

حالت ناهمزمان (ASYNC)

این حالت برای عملکرد بیش از دقت گزارش‌های اشکال بهینه شده است و می‌تواند به عنوان تشخیص سربار پایین برای اشکالات ایمنی حافظه استفاده شود.
در صورت عدم تطابق تگ، پردازنده تا نزدیکترین ورودی هسته (به عنوان مثال، وقفه syscall یا تایمر) به اجرا ادامه می‌دهد، جایی که فرآیند را با SIGSEGV (کد SEGV_MTEAERR ) بدون ثبت آدرس خطا یا دسترسی به حافظه خاتمه می‌دهد.
توصیه می‌کنیم از این حالت در تولید روی پایگاه‌های کد به خوبی آزمایش‌شده استفاده کنید، جایی که چگالی اشکالات ایمنی حافظه کم است، که با استفاده از حالت SYNC در طول آزمایش به دست می‌آید.

حالت نامتقارن (ASYMM)

یک ویژگی اضافی در Arm v8.7-A، حالت Asymmetric MTE بررسی همزمان خواندن حافظه و بررسی ناهمزمان نوشتن حافظه را با عملکردی مشابه حالت ASYNC فراهم می کند. در اکثر مواقع، این حالت نسبت به حالت ASYNC بهبود یافته است و توصیه می کنیم هر زمان که در دسترس بود، از آن به جای ASYNC استفاده کنید.

به همین دلیل، هیچ یک از API های توضیح داده شده در زیر به حالت نامتقارن اشاره ای نمی کنند. در عوض، سیستم عامل را می توان طوری پیکربندی کرد که همیشه از حالت نامتقارن هنگام درخواست Asynchronous استفاده کند. لطفاً برای اطلاعات بیشتر به بخش "پیکربندی سطح MTE ترجیحی ویژه CPU" مراجعه کنید.

MTE در فضای کاربران

بخش‌های زیر نحوه فعال کردن MTE را برای فرآیندها و برنامه‌های سیستمی توضیح می‌دهند. MTE به طور پیش‌فرض غیرفعال است، مگر اینکه یکی از گزینه‌های زیر برای یک فرآیند خاص تنظیم شده باشد (ببینید MTE برای چه مؤلفه‌هایی در زیر فعال است).

فعال کردن MTE با استفاده از سیستم ساخت

به عنوان یک ویژگی گسترده فرآیند، MTE توسط تنظیم زمان ساخت فایل اجرایی اصلی کنترل می شود. گزینه‌های زیر اجازه می‌دهند این تنظیم را برای فایل‌های اجرایی جداگانه یا برای کل زیر شاخه‌های درخت منبع تغییر دهید. این تنظیم در کتابخانه‌ها یا هر هدفی که نه قابل اجرا و نه آزمایشی است نادیده گرفته می‌شود.

1. فعال کردن MTE در Android.bp ( به عنوان مثال )، برای یک پروژه خاص:

حالت MTE تنظیمات
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 تنظیمات
MTE ناهمزمان MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
MTE سنکرون MEMTAG_HEAP_SYNC_INCLUDE_PATHS

یا با تعیین مسیر exclude یک فایل اجرایی:

حالت MTE تنظیمات
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 استفاده کنید.

فعال کردن MTE با استفاده از یک متغیر محیطی

یک راه دیگر برای لغو تنظیمات ساخت، تعریف متغیر محیطی است: 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 ترجیحی ویژه CPU

در برخی از CPU ها، عملکرد MTE در حالت های ASYMM یا حتی SYNC ممکن است مشابه عملکرد ASYNC باشد. این امر باعث می‌شود در صورت درخواست حالت بررسی دقیق‌تر، بررسی‌های دقیق‌تر روی آن پردازنده‌ها فعال شود تا از مزایای تشخیص خطای بررسی‌های سخت‌گیرانه‌تر، بدون جنبه‌های منفی عملکرد، برخوردار شوید.
به‌طور پیش‌فرض، فرآیندهایی که برای اجرا در حالت ASYNC پیکربندی شده‌اند، در حالت ASYNC روی همه پردازنده‌ها اجرا می‌شوند. برای پیکربندی هسته برای اجرای این فرآیندها در حالت SYNC روی CPUهای خاص، مقدار sync باید در ورودی sysfs /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred در زمان بوت نوشته شود. این را می توان با یک اسکریپت init انجام داد. به عنوان مثال، برای پیکربندی CPU 0-1 برای اجرای فرآیندهای حالت ASYNC در حالت SYNC، و CPU های 2-3 برای استفاده از run در حالت ASYMM، ممکن است موارد زیر به عبارت init یک اسکریپت 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 اجرا می‌شوند حاوی ردیابی پشته‌ای دقیق از محل خطای حافظه هستند. با این حال، آنها ردیابی پشته تخصیص یا توزیع را شامل نمی شوند. این ردیابی پشته تنها در صورتی در دسترس هستند که فرآیند برای اجرا در حالت 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٪ برای شناسایی اشکالات مکانی (سرریز بافر) و زمانی (استفاده پس از رایگان) فعال می‌کند.

علاوه بر APIهایی که در بالا توضیح داده شد، کاربران با تجربه ممکن است بخواهند از موارد زیر نیز آگاه باشند:

  • تنظیم رجیستر سخت افزاری 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 ). صرف نظر از این گزینه، بررسی برچسب پس از اولین خطای گزارش شده غیرفعال می شود.

ما اکیداً استفاده از حالت SYNC را در هنگام نمایش، توسعه و آزمایش توصیه می کنیم. این گزینه باید به صورت سراسری برای تمام فرآیندهایی که از متغیر محیطی یا با سیستم ساخت استفاده می کنند فعال شود. در این حالت، باگ‌ها در مراحل اولیه توسعه شناسایی می‌شوند، پایگاه کد سریع‌تر تثبیت می‌شود و از هزینه‌های شناسایی باگ‌ها در مراحل بعدی تولید جلوگیری می‌شود.

ما به شدت توصیه می کنیم از حالت ASYNC در تولید استفاده کنید. این یک ابزار سربار کم برای تشخیص وجود اشکالات ایمنی حافظه در یک فرآیند و همچنین دفاع در عمق بیشتر فراهم می کند. پس از شناسایی یک باگ، توسعه‌دهنده می‌تواند از APIهای زمان اجرا برای تغییر به حالت SYNC استفاده کند و یک ردیابی پشته دقیق از مجموعه نمونه‌گیری شده از کاربران دریافت کند.

ما قویاً توصیه می کنیم که سطح MTE ترجیحی ویژه CPU را برای SoC پیکربندی کنید. حالت Asymm معمولاً همان ویژگی های عملکردی ASYNC را دارد و تقریباً همیشه نسبت به آن ارجحیت دارد. هسته های کوچک مرتب اغلب عملکرد مشابهی را در هر سه حالت نشان می دهند و می توان آنها را طوری پیکربندی کرد که SYNC را ترجیح دهد.

توسعه‌دهندگان باید وجود خرابی‌ها را با بررسی /data/tombstones ، logcat یا نظارت بر خط لوله DropboxManager فروشنده برای باگ‌های کاربر نهایی بررسی کنند. برای اطلاعات بیشتر در مورد اشکال زدایی کد بومی اندروید، اطلاعات اینجا را ببینید.

اجزای پلتفرم فعال شده MTE

در اندروید 12، تعدادی از اجزای سیستم حیاتی امنیتی از MTE ASYNC برای شناسایی خرابی‌های کاربر نهایی استفاده می‌کنند و به عنوان یک لایه اضافی دفاعی در عمق عمل می‌کنند. این اجزا عبارتند از:

  • دیمون ها و ابزارهای شبکه (به استثنای netd )
  • بلوتوث، SecureElement، HAL های NFC و برنامه های سیستمی
  • دیمون statsd
  • system_server
  • zygote64 (برای اینکه برنامه‌ها بتوانند از MTE استفاده کنند)

این اهداف بر اساس معیارهای زیر انتخاب شدند:

  • یک فرآیند ممتاز (تعریف شده به عنوان فرآیندی که به چیزی دسترسی دارد که دامنه SELinux unprivileged_app به آن دسترسی ندارد)
  • ورودی غیرقابل اعتماد فرآیندها ( قانون دو )
  • کاهش عملکرد قابل قبول (کاهش سرعت تاخیر قابل مشاهده توسط کاربر ایجاد نمی کند)

ما فروشندگان را تشویق می کنیم تا MTE را در تولید قطعات بیشتر، با پیروی از معیارهای ذکر شده در بالا، فعال کنند. در طول توسعه، ما توصیه می‌کنیم این مؤلفه‌ها را با استفاده از حالت SYNC آزمایش کنید تا باگ‌ها را به راحتی برطرف کنید و تأثیر ASYNC را بر عملکرد آنها ارزیابی کنید.
در آینده، اندروید قصد دارد فهرست اجزای سیستمی را که MTE روی آنها فعال است، با هدایت ویژگی های عملکرد طراحی های سخت افزاری آینده گسترش دهد.