پاکسازی سرریز عدد صحیح

سرریزهای اعداد صحیح ناخواسته می تواند باعث تخریب حافظه یا آسیب پذیری های افشای اطلاعات در متغیرهای مرتبط با دسترسی های حافظه یا تخصیص حافظه شود. برای مبارزه با این موضوع، ضدعفونی‌کننده‌های سرریز اعداد صحیح علامت‌دار و بدون علامت Clang's UndefinedBehaviorSanitizer (UBSan) را اضافه کردیم تا چارچوب رسانه‌ای را در اندروید 7.0 سخت‌تر کنیم. در اندروید 9، UBSan را گسترش دادیم تا اجزای بیشتری را پوشش دهد و پشتیبانی از سیستم ساخت را برای آن بهبود بخشید.

این برای اضافه کردن بررسی‌ها در مورد عملیات / دستورالعمل‌های حسابی - که ممکن است سرریز شوند - طراحی شده است تا در صورت وقوع سرریز، به طور ایمن یک فرآیند را متوقف کند. این ضدعفونی‌کننده‌ها می‌توانند یک کلاس کامل از آسیب‌پذیری‌های حافظه و افشای اطلاعات را که علت اصلی آن سرریز اعداد صحیح است، مانند آسیب‌پذیری اصلی Stagefright، کاهش دهند.

مثال ها و منبع

پاکسازی سرریز عدد صحیح (IntSan) توسط کامپایلر ارائه می شود و ابزار دقیق را در طول زمان کامپایل به باینری اضافه می کند تا سرریزهای حسابی را تشخیص دهد. این به طور پیش فرض در اجزای مختلف در سراسر پلتفرم فعال است، به عنوان مثال /platform/external/libnl/Android.bp .

پیاده سازی

IntSan از ضدعفونی کننده های سرریز اعداد صحیح امضا شده و بدون علامت UBSan استفاده می کند. این کاهش در سطح هر ماژول فعال است. این کمک می کند تا اجزای مهم اندروید را ایمن نگه دارد و نباید غیرفعال شود.

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

پشتیبانی از IntSan در فایل های makefiles

برای فعال کردن IntSan در یک makefile، اضافه کنید:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE فهرستی از ضدعفونی‌کننده‌ها را می‌گیرد که با کاما از هم جدا شده‌اند، با integer_overflow از پیش‌بسته‌بندی‌شده از گزینه‌ها برای پاک‌کننده‌های سرریز اعداد صحیح امضاشده و بدون علامت با یک لیست سیاه پیش‌فرض است.
  • LOCAL_SANITIZE_DIAG حالت تشخیصی را برای ضدعفونی‌کننده‌ها روشن می‌کند. از حالت عیب‌یابی فقط در حین آزمایش استفاده کنید زیرا این حالت در سرریزها متوقف نمی‌شود و مزیت امنیتی کاهش را کاملاً نفی می‌کند. برای جزئیات بیشتر به عیب یابی مراجعه کنید.
  • LOCAL_SANITIZE_BLACKLIST به شما امکان می دهد یک فایل لیست سیاه را مشخص کنید تا از پاکسازی عملکردها و فایل های منبع جلوگیری کنید. برای جزئیات بیشتر به عیب یابی مراجعه کنید.

اگر می خواهید کنترل دانه ای بیشتری داشته باشید، ضدعفونی کننده ها را به صورت جداگانه با استفاده از یک یا هر دو پرچم فعال کنید:

LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow
LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow

پشتیبانی از IntSan در فایل های طرح اولیه

برای فعال کردن پاکسازی سرریز اعداد صحیح در یک فایل طرح اولیه، مانند /platform/external/libnl/Android.bp ، اضافه کنید:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

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

مجموعه ویژگی های دیاگ حالت diag را برای ضدعفونی کننده ها فعال می کند. از حالت عیب یاب فقط در طول آزمایش استفاده کنید. حالت عیب‌یابی در سرریزها متوقف نمی‌شود، که به طور کامل مزیت امنیتی کاهش در ساخت‌های کاربر را نفی می‌کند. برای جزئیات بیشتر به عیب یابی مراجعه کنید.

ویژگی blacklist اجازه می دهد تا یک فایل لیست سیاه را مشخص کنید که به توسعه دهندگان اجازه می دهد از پاکسازی توابع و فایل های منبع جلوگیری کنند. برای جزئیات بیشتر به عیب یابی مراجعه کنید.

برای فعال کردن ضدعفونی‌کننده‌ها به صورت جداگانه، از موارد زیر استفاده کنید:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

عیب یابی

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

برای یافتن سقط‌های ناشی از پاک‌سازی در ساخت‌های کاربر، خرابی‌های SIGABRT را با پیام‌های Abort جستجو کنید که نشان‌دهنده سرریز شدن توسط UBSan است، مانند:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

ردیابی پشته باید شامل تابعی باشد که باعث سقط می شود، با این حال، سرریزهایی که در توابع درون خطی رخ می دهند ممکن است در ردیابی پشته مشهود نباشند.

برای تعیین آسان‌تر علت اصلی، تشخیص را در کتابخانه فعال کنید که باعث سقط می‌شود و سعی کنید خطا را تکرار کنید. با فعال بودن عیب‌یابی، فرآیند متوقف نمی‌شود و در عوض به کار خود ادامه می‌دهد. عدم قطع به حداکثر رساندن تعداد سرریزهای خوش خیم در یک مسیر اجرای خاص بدون نیاز به کامپایل مجدد پس از رفع هر اشکال کمک می کند. Diagnostics یک پیام خطایی ایجاد می کند که شامل شماره خط و فایل منبع است که باعث سقط می شود:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')

هنگامی که عملیات محاسباتی مشکل ساز مشخص شد، اطمینان حاصل کنید که سرریز خوش خیم و مورد نظر است (مثلاً هیچ پیامد امنیتی ندارد). می‌توانید با موارد زیر به سقط ضدعفونی‌کننده رسیدگی کنید:

  • اصلاح مجدد کد برای جلوگیری از سرریز شدن ( مثال )
  • سرریز به صراحت از طریق توابع __builtin_*_سرریز Clang's ( مثال )
  • غیرفعال کردن sanitization در تابع با مشخص کردن ویژگی no_sanitize ( مثال )
  • غیرفعال کردن پاکسازی یک تابع یا فایل منبع از طریق یک فایل لیست سیاه ( مثال )

باید از گرانول ترین محلول ممکن استفاده کنید. به عنوان مثال، یک تابع بزرگ با تعداد زیادی عملیات حسابی و یک عملیات سرریز منفرد باید به جای اینکه کل تابع در لیست سیاه قرار گیرد، عملیات واحد مجدداً تغییر داده شود.

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

  • پخش‌های ضمنی که در آن یک سرریز بدون علامت قبل از ریخته شدن به یک نوع علامت‌دار رخ می‌دهد ( مثال )
  • حذف لیست پیوندی که شاخص حلقه در حذف را کاهش می دهد ( مثال )
  • اختصاص یک نوع بدون علامت به -1 به جای تعیین حداکثر مقدار واقعی ( مثال )
  • حلقه هایی که یک عدد صحیح بدون علامت را در شرایط کاهش می دهند ( مثال ، مثال )

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

غیرفعال کردن IntSan

می توانید IntSan را با لیست سیاه یا ویژگی های تابع غیرفعال کنید. غیرفعال کردن به مقدار کم و فقط در زمانی که تغییر مجدد کد غیرمنطقی است یا اگر سربار عملکرد مشکلی وجود داشته باشد.

برای اطلاعات بیشتر در مورد غیرفعال کردن IntSan با ویژگی های تابع و قالب بندی فایل لیست سیاه ، به مستندات Clang بالادست مراجعه کنید. در لیست سیاه باید با استفاده از نام بخش‌هایی که ضدعفونی‌کننده مورد نظر را مشخص می‌کنند، برای جلوگیری از تأثیرگذاری سایر ضدعفونی‌کننده‌ها، محدوده آن را برای ضدعفونی‌کننده خاص در نظر بگیرید.

اعتبار سنجی

در حال حاضر، هیچ تست CTS به طور خاص برای پاکسازی سرریز عدد صحیح وجود ندارد. درعوض، مطمئن شوید که تست‌های CTS با یا بدون فعال بودن IntSan انجام می‌شوند تا مطمئن شوید که روی دستگاه تأثیر نمی‌گذارد.