سكودو

Scudo عبارة عن مخصص ذاكرة ديناميكي لوضع المستخدم، أو مخصص الكومة ، مصمم ليكون مرنًا ضد الثغرات الأمنية المرتبطة بالكومة (مثل تجاوز سعة المخزن المؤقت القائم على الكومة ، والاستخدام بعد الحرية ، والحرة المزدوجة ) مع الحفاظ على الأداء. وهو يوفر أساسيات تخصيص C وإلغاء التخصيص القياسية (مثل malloc وfree)، بالإضافة إلى أساسيات C++ (مثل الجديد والحذف).

يعد Scudo بمثابة أداة تخفيف أكثر من كونه كاشفًا كاملاً لأخطاء الذاكرة مثل AddressSanitizer (ASan) .

منذ إصدار Android 11، يتم استخدام scudo لجميع التعليمات البرمجية الأصلية (باستثناء الأجهزة ذات الذاكرة المنخفضة، حيث لا يزال jemalloc مستخدمًا). في وقت التشغيل، تتم خدمة جميع عمليات تخصيص وإلغاء تخصيص الكومة الأصلية بواسطة Scudo لجميع الملفات التنفيذية وتبعيات مكتبتها، ويتم إحباط العملية في حالة اكتشاف تلف أو سلوك مشبوه في الكومة.

Scudo هو مصدر مفتوح وجزء من مشروع التحويل البرمجي لـ LLVM. الوثائق متاحة على https://llvm.org/docs/ScudoHardenedAllocator.html . يتم شحن وقت تشغيل Scudo كجزء من سلسلة أدوات Android وتمت إضافة الدعم إلى Soong وMake للسماح بتمكين المُخصص بسهولة في ملف ثنائي.

يمكنك تمكين أو تعطيل التخفيف الإضافي داخل المُخصص باستخدام الخيارات الموضحة أدناه.

التخصيص

يمكن تحديد بعض معلمات المُخصص على أساس كل عملية من خلال عدة طرق:

  • بشكل ثابت: حدد دالة __scudo_default_options في البرنامج الذي يقوم بإرجاع سلسلة الخيارات المراد تحليلها. يجب أن تحتوي هذه الوظيفة على النموذج الأولي التالي: extern "C" const char *__scudo_default_options() .
  • ديناميكيًا: استخدم متغير البيئة SCUDO_OPTIONS الذي يحتوي على سلسلة الخيارات المراد تحليلها. الخيارات المحددة بهذه الطريقة تتجاوز أي تعريف تم إجراؤه من خلال __scudo_default_options .

الخيارات التالية متاحة.

خيار افتراضي 64 بت افتراضي 32 بت وصف
QuarantineSizeKb 256 64 الحجم (بالكيلوبايت) للعزل المستخدم لتأخير إلغاء التخصيص الفعلي للقطع. قد تؤدي القيمة الأقل إلى تقليل استخدام الذاكرة ولكنها تقلل من فعالية التخفيف؛ تعود القيمة السالبة إلى الإعدادات الافتراضية. يؤدي تعيين كل من هذا و ThreadLocalQuarantineSizeKb إلى الصفر إلى تعطيل العزل بالكامل.
QuarantineChunksUpToSize 2048 512 الحجم (بالبايت) الذي يمكن عزل القطع فيه.
ThreadLocalQuarantineSizeKb 64 16 الحجم (بالكيلوبايت) المستخدم في ذاكرة التخزين المؤقت لكل مؤشر ترابط لإلغاء تحميل العزل العام. قد تؤدي القيمة الأقل إلى تقليل استخدام الذاكرة ولكنها قد تزيد من التنافس على العزل العام. يؤدي تعيين كل من هذا و QuarantineSizeKb إلى الصفر إلى تعطيل العزل تمامًا.
DeallocationTypeMismatch false false تمكين الإبلاغ عن الأخطاء في malloc/delete، new/free، new/delete[]
DeleteSizeMismatch true true لتمكين الإبلاغ عن الأخطاء عند عدم التطابق بين الأحجام الجديدة والمحذوفة.
ZeroContents false false تمكين محتويات القطعة الصفرية عند التخصيص وإلغاء التخصيص.
allocator_may_return_null false false يحدد أنه يمكن للمخصص إرجاع قيمة فارغة عند حدوث خطأ قابل للاسترداد، بدلاً من إنهاء العملية.
hard_rss_limit_mb 0 0 عندما يصل RSS الخاص بالعملية إلى هذا الحد، تنتهي العملية.
soft_rss_limit_mb 0 0 عندما يصل RSS الخاص بالعملية إلى هذا الحد، تفشل عمليات التخصيص الإضافية أو تُرجع null (اعتمادًا على قيمة allocator_may_return_null ) حتى يعود RSS لأسفل للسماح بالتخصيصات الجديدة.
allocator_release_to_os_interval_ms لا يوجد 5000 يؤثر فقط على مخصص 64 بت. في حالة التعيين، يحاول تحرير الذاكرة غير المستخدمة إلى نظام التشغيل، ولكن ليس أكثر من هذا الفاصل الزمني (بالمللي ثانية). إذا كانت القيمة سالبة، فلن يتم تحرير الذاكرة لنظام التشغيل.
abort_on_error true true إذا تم تعيينها، فستستدعي الأداة abort() بدلاً من _exit() بعد طباعة رسالة الخطأ.

تصديق

حاليًا، لا توجد اختبارات CTS مخصصة لسكودو. بدلاً من ذلك، تأكد من اجتياز اختبارات CTS مع أو بدون تمكين Scudo لثنائي معين للتحقق من أنه لا يؤثر على الجهاز.

استكشاف الأخطاء وإصلاحها

إذا تم اكتشاف مشكلة غير قابلة للاسترداد، فسيعرض المُخصص رسالة خطأ إلى واصف الخطأ القياسي ثم ينهي العملية. تتم إضافة تتبعات المكدس التي تؤدي إلى الإنهاء في سجل النظام. يبدأ الإخراج عادةً بخطأ Scudo ERROR: متبوعًا بملخص قصير للمشكلة بالإضافة إلى أي مؤشرات.

فيما يلي قائمة برسائل الخطأ الحالية وأسبابها المحتملة:

  • corrupted chunk header : فشل التحقق من المجموع الاختباري لرأس القطعة. من المحتمل أن يكون هذا بسبب أحد أمرين: تمت الكتابة فوق الرأس (جزئيًا أو كليًا)، أو أن المؤشر الذي تم تمريره إلى الوظيفة ليس قطعة.
  • race on chunk header : يحاول خيطان مختلفان معالجة نفس الرأس في نفس الوقت. عادةً ما يكون هذا من أعراض حالة السباق أو النقص العام في القفل عند إجراء العمليات على تلك القطعة.
  • invalid chunk state : القطعة ليست في الحالة المتوقعة لعملية معينة، على سبيل المثال، لم يتم تخصيصها عند محاولة تحريرها، أو لم يتم عزلها عند محاولة إعادة تدويرها. يعتبر الخطأ المزدوج هو السبب النموذجي لهذا الخطأ.
  • misaligned pointer : يتم فرض متطلبات المحاذاة الأساسية بقوة: 8 بايت على الأنظمة الأساسية 32 بت و16 بايت على الأنظمة الأساسية 64 بت. إذا كان المؤشر الذي تم تمريره إلى وظائفنا لا يتناسب مع تلك الوظائف، فسيكون المؤشر الذي تم تمريره إلى إحدى الوظائف خارج المحاذاة.
  • allocation type mismatch : عند تمكين هذا الخيار، يجب أن تتطابق وظيفة إلغاء التخصيص التي يتم استدعاؤها على القطعة مع نوع الوظيفة التي تم استدعاؤها لتخصيصها. يمكن أن يؤدي هذا النوع من عدم التطابق إلى حدوث مشكلات أمنية.
  • invalid sized delete : عند استخدام عامل الحذف بحجم C++ 14، وتمكين الفحص الاختياري، يكون هناك عدم تطابق بين الحجم الذي تم تمريره عند إلغاء تخصيص قطعة والحجم المطلوب عند تخصيصها. عادةً ما تكون هذه مشكلة في برنامج التحويل البرمجي أو ارتباك في النوع على الكائن الذي يتم إلغاء تخصيصه.
  • RSS limit exhausted : تم تجاوز الحد الأقصى المحدد اختياريًا لـ RSS.

إذا كنت تقوم بتصحيح الأخطاء في نظام التشغيل نفسه، فيمكنك استخدام HWASan OS build . إذا كنت تقوم بتصحيح الأخطاء في أحد التطبيقات، فمن الممكن استخدام إصدار تطبيق HWASan أيضًا.