أداة ضبط سلوك غير محدّدة

ينفذ UnifiedBehaviorSanitizer (UBSan) أدوات وقت التجميع والتحقق من أنواع مختلفة من السلوكيات غير المحددة. وفي حين أن UBSan قادر على كشف العديد أخطاء غير محدّدة للسلوك، يتوافق Android مع:

  • محاذاة
  • قيمة منطقية (Bool)
  • حدود
  • تعداد
  • حجم عائم للإرسال
  • قسمة-تقسيم-على-صفر
  • عدد صحيح قسمة على صفر
  • سمة غير خالية
  • خالية
  • return
  • سمة return-non-null
  • قاعدة Shift
  • أس shift
  • تجاوز عدد صحيح موقَّع
  • لا يمكن الوصول
  • تجاوز عدد صحيح غير موقَّع
  • مربوط بـ vla

تجاوز عدد صحيح غير موقَّع، في حين أنّه غير محدّد من الناحية الفنية السلوك، حيث يتم تضمينها في المطهّر واستخدامها في العديد من وحدات Android، بما في ذلك مكونات خادم الوسائط، لإزالة أي تجاوز لعدد صحيح كاتم الثغرات الأمنية.

التنفيذ

في نظام إصدار Android، يمكنك تفعيل UBSan على نطاق عالمي أو محلي. للتفعيل UBSan عالميًا، يجب تعيين SANITIZE_TARGET في Android.mk. لتفعيل بروتوكول UBSan في على مستوى الوحدة، وتعيين LOCAL_SANITIZE وتحديد السلوكيات غير المحددة التي التي تريد البحث عنها في Android.mk. مثلاً:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0

LOCAL_SRC_FILES:= sanitizer-status.c

LOCAL_MODULE:= sanitizer-status

LOCAL_SANITIZE := alignment bounds null unreachable integer
LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer

include $(BUILD_EXECUTABLE)

وإعداد المخطط المكافئ (Android.bp):

cc_binary {

    cflags: [
        "-std=c11",
        "-Wall",
        "-Werror",
        "-O0",
    ],

    srcs: ["sanitizer-status.c"],

    name: "sanitizer-status",

    sanitize: {
        misc_undefined: [
            "alignment",
            "bounds",
            "null",
            "unreachable",
            "integer",
        ],
        diag: {
            misc_undefined: [
                "alignment",
                "bounds",
                "null",
                "unreachable",
                "integer",
            ],
        },
    },

}

اختصارات UBSan

تتوفر في Android أيضًا اختصاران، هما "integer" default-ub، لتفعيل مجموعة من المعقّمات في آنٍ واحد. عدد صحيح لتفعيل integer-divide-by-zero، "signed-integer-overflow" و"unsigned-integer-overflow" تعمل default-ub على تفعيل عمليات التحقق التي تحتوي على الحد الأدنى من التجميع العنقودي مشاكل في الأداء: bool, integer-divide-by-zero, return, returns-nonnull-attribute, shift-exponent, unreachable and vla-bound. تشير رسالة الأشكال البيانية يمكن استخدام فئة sanitizer مع العدد الصحيح مع SANITIZE_TARGET وLOCAL_SANITIZE، بينما يمكن استخدام default-ub مع SANITIZE_TARGET.

الإبلاغ عن الأخطاء بشكل أفضل

يستدعي تنفيذ UBSan الافتراضي في Android دالة محددة عند حدوث سلوك غير معروف. بشكل افتراضي، يتم إلغاء هذه الدالة. ومع ذلك، بدءًا من تشرين الأول (أكتوبر) 2016، تشتمل خدمة UBSan على نظام التشغيل Android على مكتبة وقت تشغيل اختيارية تقديم تقرير أكثر تفصيلاً عن الأخطاء، بما في ذلك نوع السلوك غير المحدد التي تم العثور عليها، ومعلومات سطر رمز المصدر والملف. لتفعيل هذا الخطأ إعداد التقارير التي تتضمّن عمليات تحقّق من الأعداد الصحيحة، أضِف ما يلي إلى ملف Android.mk:

LOCAL_SANITIZE:=integer
LOCAL_SANITIZE_DIAG:=integer

تُفعِّل القيمة LOCAL_SANITIZE المطهِّر أثناء عملية الإنشاء. يُفعِّل LOCAL_SANITIZE_DIAG وضع التشخيص للمعقّم المحدد. من المهم من الممكن تعيين LOCAL_SANITIZE وLOCAL_SANITIZE_DIAG على قيم مختلفة، يتم تفعيل عمليات التحقق هذه في LOCAL_SANITIZE فقط. إذا لم يتم تحديد شيك في LOCAL_SANITIZE، ولكن محددة في LOCAL_SANITIZE_DIAG، لم يتم تفعيل عملية التحقق ورسائل التشخيص.

في ما يلي مثال على المعلومات التي تقدّمها مكتبة وقت تشغيل UBSan:

pixel-xl:/ # sanitizer-status ubsan
sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')

تنقيح يتجاوز العدد الصحيح

يمكن أن تتسبب فائض الأعداد الصحيحة غير المقصودة في تلف الذاكرة أو تقديم معلومات الكشف عن الثغرات الأمنية في المتغيرات المرتبطة بعمليات الوصول إلى الذاكرة أو عمليات توزيع الذاكرة. للتصدي لهذا الأمر، أضفنا الخوارزمية UnifiedBehaviorSanitizer (UBSan) معقّمات التجاوز الأعداد الصحيحة الموقّعة وغير الموقَّعة إلى صعب إطار عمل الوسائط في Android 7.0. في نظام Android 9، سنُجري موسعة UBSan لتغطية المزيد من المكونات وتحسين دعم نظام الإصدار لها.

تم تصميم هذا الخيار لإضافة عمليات تحقّق حول العمليات الحسابية. العمليات / instructions—التي قد تجاوز - لإلغاء عملية بأمان في حالة حدوث فائض. يمكن لهذه المعقّمات الحدّ من تلف فئة كاملة من تلف الذاكرة الثغرات الأمنية في الكشف عن المعلومات حيث يكون السبب الجذري عددًا صحيحًا تجاوز القيمة، مثل الثغرة الأمنية Stagefright الأصلية.

الأمثلة والمصدر

يتم توفير Integer Overflow Sanitization (IntSan) بواسطة المحول البرمجي ويضيفون أداة في النظام الثنائي أثناء وقت التجميع لاكتشاف الحساب يتجاوز. ويتم تفعيلها افتراضيًا في مكونات مختلفة عبر المنصة، على سبيل المثال /platform/external/libnl/Android.bp

التنفيذ

تستخدم أداة IntSan معقّمات العدد الصحيح الموقّع وغير الموقَّعة من UBSan. هذا النمط يتم تفعيل إجراءات التخفيف على مستوى كل وحدة. يساعد في الحفاظ على المكونات المهمة من أمان Android ويجب عدم إيقافه.

نشجعك بشدة على تفعيل "القضاء على الأعداد الصحيحة من Integer Overflow" للحصول على والمكونات. ويمثّل المرشحون المثاليون رموزًا برمجية أصلية أو رموزًا برمجية أصلية تحلّل مدخلات المستخدم غير الموثوق بها. هناك أعباء عامة صغيرة مرتبطة بالأداء الذي يعتمد على استخدام الرمز البرمجي وانتشار العمليات الحسابية. توقع نسبة مئوية صغيرة من النفقات العامة واختبر ما إذا كان بشأن الأداء مصدر قلق.

إتاحة IntSan في ملفات Makefiles

لتفعيل IntSan في ملف إعداد، أضِف ما يلي:

LOCAL_SANITIZE := integer_overflow
    # Optional features
    LOCAL_SANITIZE_DIAG := integer_overflow
    LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
  • يأخذ LOCAL_SANITIZE قائمة بالمعقّمات مفصولة بفواصل، حيث يُعد integer_overflow مجموعة من الخيارات معبأة مسبقًا المطهرات الكاملة للعدد الصحيح الموقّع وغير الموقَّع الذي يحتوي على افتراضي القائمة المحظورة
  • يفعِّل "LOCAL_SANITIZE_DIAG" وضع التشخيص معقّمات. يُرجى استخدام وضع "بيانات التشخيص" أثناء الاختبار فقط، لأنّ ذلك لن يؤدي إلى إلغاء التجاوز، مع تجاهل الميزة الأمنية تمامًا والتخفيف من حدتها. راجع تحديد المشاكل وحلّها للحصول على تفاصيل إضافية.
  • يسمح لك LOCAL_SANITIZE_BLOCKLIST بتحديد قائمة حظر لمنع تصحيح الدوال وملفات المصدر. عرض يُرجى تحديد المشاكل وحلّها للاطّلاع على التفاصيل.

إذا أردت التحكّم بشكل أدقّ في المحتوى، يمكنك تفعيل المعقّمات بشكل فردي باستخدام أحدها. أو كلتا العلامتين:

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,
          },
          BLOCKLIST: "modulename_BLOCKLIST.txt",
       },

كما هو الحال مع make Files، السمة integer_overflow هي عبارة عن حزمة مُثبَّتة مسبقًا. مجموعة من الخيارات لتجاوز الأعداد الصحيحة الفردية الموقعة وغير الموقَّعة المعقّمات باستخدام خيار افتراضي القائمة المحظورة

تفعِّل مجموعة diag من الخصائص وضع التشخيص معقّمات. لا تستخدِم وضع التشخيص إلا أثناء الاختبار. وضع "بيانات التشخيص" غير مفعّل إلغاء التجاوز، الأمر الذي ينفي تمامًا المزايا الأمنية والتخفيف في تصاميم المستخدم. راجِع قسم تحديد المشاكل وحلّها لمعرفة مزيد من التفاصيل.

تسمح السمة BLOCKLIST بتحديد ملف BLOCKLIST. تسمح للمطوّرين بمنع نشر الدوال والملفات المصدر تم تنظيفه. راجع تحديد المشاكل وحلّها بشأن تفاصيل إضافية.

لتفعيل المعقّمات بشكل فردي، استخدِم ما يلي:

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

تحديد المشاكل وحلّها

إذا كنت تقوم بتمكين تنقيح تجاوز الأعداد الصحيحة في المكونات الجديدة، أو تعتمد على لمعرضات النظام الأساسي التي خضعت لتنقيح فائض من الأعداد الصحيحة، فقد تواجه بعض المشكلات الخاصة بتجاوزات الأعداد الصحيحة الحميدة التي تتسبب في عمليات الإلغاء. يجب عليك اختبار مع تمكين التعقيم لضمان ظهور فيضانات حميدة.

للعثور على عمليات الإلغاء الناتجة عن التعقيم في تصميمات المستخدمين، ابحث عن SIGABRT تعطُّل مع رسائل "الإلغاء" التي تشير إلى تجاوز السعة بواسطة UBSan، مثل:

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

ومع ذلك، يجب أن يتضمن تتبُّع تسلسل استدعاء الدوال البرمجية الدالة التي تتسبب في الإلغاء، قد لا تكون الفواصل التي تحدث في الدوال المضمّنة واضحة في تتبُّع تسلسل استدعاء الدوال البرمجية.

لتحديد السبب الأساسي بسهولة أكبر، عليك تفعيل بيانات التشخيص في المكتبة. مما يؤدي إلى إلغاء عملية الإلغاء ومحاولة إعادة إنتاج الخطأ. مع بيانات التشخيص المفعَّلة حاليًا، لن يتم إلغاء العملية وسيتم بدلاً من ذلك مواصلة تشغيلها. يساعد عدم الإلغاء في زيادة عدد الفائض الحميدة في مسار تنفيذ معين بدون الحاجة إلى إعادة التحويل البرمجي بعد إصلاح كل خطأ. تعرض بيانات التشخيص رسالة خطأ تتضمن رقم السطر والمصدر الملف الذي يتسبب في الإلغاء:

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_*_overflow من Clang الدوال (مثال)
  • إيقاف التعقيم في الدالة من خلال تحديد السمة no_sanitize (مثال)
  • إيقاف تنقيح دالة أو ملف مصدر من خلال ملف BLOCKLIST (مثال)

يجب عليك استخدام الحل الأكثر دقة قدر الإمكان. على سبيل المثال، قد يكون حجم مع العديد من العمليات الحسابية وعملية واحدة كاملة يجب إعادة ضبط العملية الفردية بدلاً من الدالة بأكملها القائمة المحظورة.

تشمل الأنماط الشائعة التي قد تؤدي إلى تجاوزات حميدة ما يلي:

  • ضمني عمليات البث التي يحدث فيها فائض غير موقَّع قبل الإرسال إلى نوع موقَّع (مثال)
  • عمليات حذف القوائم المرتبطة التي تقلِّل من فهرس التكرار عند الحذف (مثال)
  • تعيين نوع غير موقَّع على -1 بدلاً من تحديد القيمة القصوى الفعلية (مثال)
  • يشير ذلك المصطلح إلى التكرارات التي تقلّل عددًا صحيحًا غير موقَّع في الشرط (مثال، مثال)

ننصح المطوّرين بأن يؤكّدوا أنّ الحالات التي يرصد فيها المطهّر إذا كان هذا المحتوى حميمًا فعلاً بدون أي آثار جانبية أو أمان غير مقصود قبل إيقاف عملية التعقيم.

إيقاف IntSan

يمكنك إيقاف IntSan باستخدام القوائم المحظورة أو سمات الدوال. الإيقاف باعتدال وفقط عندما يكون إعادة ضبط التعليمات البرمجية غير معقولة أو إذا كانت هناك النفقات العامة المتعلقة بالأداء المشكل.

راجِع وثائق Clang الأولية للحصول على مزيد من المعلومات حول إيقاف IntSan بالدالة السمات وملف BLOCKLIST والتنسيق. يجب تحديد نطاق الحظر المُدرج في القائمة عن طريق باستخدام أسماء الأقسام التي تحدد المطهّر المستهدف لتجنب التأثير في معقّمات.

التحقُّق

في الوقت الحالي، لا يوجد اختبار CTS خصيصًا لتعقيم Integer Overflow. بدلاً من ذلك، تأكَّد من اجتياز اختبارات CTS مع تفعيل IntSan أو عدم تفعيله للتحقُّق. عدم تأثيره على الجهاز.

تعقيم الحدود

يضيف BoundsSanitizer (BoundSan) أداة إلى البرامج الثنائية لإدراج الحدود للتحقق من عمليات الوصول إلى الصفائف. تتم إضافة عمليات الفحص هذه إذا لم يتمكن المحول البرمجي من تثبت في وقت التجميع أن الوصول سيكون آمنًا وما إذا كان حجم الصفيفة في وقت التشغيل، بحيث يمكن التحقق منها. نظام Android 10 ينشر BoundSan البلوتوث وبرامج الترميز. يتم توفير BoundSan بواسطة المحول البرمجي ويتم تمكينه بواسطة بشكل افتراضي في مكونات مختلفة عبر النظام الأساسي.

التنفيذ

تستخدم شركة BoundSan شبكة UBSan ويفتح أبوابه. يتم تفعيل إجراءات التخفيف هذه على مستوى كل وحدة. من المفيد الحفاظ على أمان مكونات Android المهمة وعدم إيقافها.

ننصحك بشدة بتفعيل BoundSan لمكونات إضافية. يشكّل البرنامج المرشح المثالي رموزًا برمجية أصلية أو رموزًا برمجية أصلية معقّدة تحلّل إدخال مستخدم غير موثوق به. النفقات العامة على الأداء المرتبطة بتفعيل BoundSan يعتمد على عدد مرات الوصول إلى الصفائف التي لا يمكن إثبات أمانها. يمكنك توقُّع نسبة صغيرة من النفقات العامة في المتوسط واختبار ما إذا كان الأداء مصدر قلق.

تفعيل BoundSan في ملفات المخطط

يمكن تفعيل BoundSan في ملفات المخططات من خلال إضافة "bounds". إلى السمة misc_undefined Cleanedes لـ النظام الثنائي والمكتبة الوحدات:

    sanitize: {
       misc_undefined: ["bounds"],
       diag: {
          misc_undefined: ["bounds"],
       },
       BLOCKLIST: "modulename_BLOCKLIST.txt",
تشخيص

تفعِّل السمة diag وضع التشخيص للمعقّمات. لا تستخدِم وضع التشخيص إلا أثناء الاختبار. لا يتم إلغاء تفعيل وضع "بيانات التشخيص" تجاوز الميزة، الذي ينفي الميزة الأمنية للتخفيف ويحمل أعباء أداء أعلى، لذا لا يُنصح باستخدامها للإصدارات الإنتاجية.

قائمة الحظر

تسمح السمة BLOCKLIST بتحديد القائمة المحظورة. ملف يمكن للمطورين استخدامه لمنع تشغيل الدوال والملفات المصدر تم تنظيفه. لا تستخدِم هذه السمة إلا إذا كان الأداء مصدرًا للقلق وكان الهدف من الملفات/الدوال بشكل كبير. تدقيق هذه الملفات أو الدوال يدويًا لضمان أمان عمليات الوصول إلى الصفائف. راجِع تحديد المشاكل وحلّها للتعرّف على التفاصيل.

تفعيل BoundSan في ملفات makefiles

يمكن تفعيل BoundSan في ملفات Makefiles من خلال إضافة "bounds". إلى المتغيّر LOCAL_SANITIZE للوحدات الثنائية والوحدات في المكتبة:

    LOCAL_SANITIZE := bounds
    # Optional features
    LOCAL_SANITIZE_DIAG := bounds
    LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt

يقبل "LOCAL_SANITIZE" قائمة بالمعقّمات مفصولة بفواصل الفاصلة.

يفعِّل "LOCAL_SANITIZE_DIAG" وضع بيانات التشخيص. استخدام بيانات التشخيص الوضع أثناء الاختبار فقط. لا يتم إلغاء وضع التشخيص عند تجاوز السعة، والتي ينفي الميزة الأمنية للتخفيف ويتحمل أعباء الأداء، لذا لا يُنصح باستخدامها للإصدارات الإنتاجية.

تسمح الدالة LOCAL_SANITIZE_BLOCKLIST بتحديد القائمة المحظورة. يسمح للمطورين بمنع تخزين الدوال والملفات المصدر تم تنظيفه. لا تستخدِم هذه السمة إلا إذا كان الأداء مصدرًا للقلق وكان الهدف من الملفات/الدوال بشكل كبير. تدقيق هذه الملفات أو الدوال يدويًا لضمان أمان عمليات الوصول إلى الصفائف. راجِع تحديد المشاكل وحلّها للتعرّف على التفاصيل.

إيقاف BoundSan

يمكنك تعطيل BoundSan في الدوال والملفات المصدر باستخدام BLOCKLIST أو سمات الدوال. من الأفضل إبقاء BoundSan مفعّلة، لذلك يجب إيقافها فقط تؤدي الدالة أو الملف إلى إنشاء قدر كبير من النفقات العامة المصدر قد تمت مراجعته يدويًا.

لمزيد من المعلومات حول تعطيل BoundSan باستخدام الدالة السمات وملف BLOCKLIST ، يُرجى الرجوع إلى وثائق Clang LLVM. نطاق وضع القائمة المحظورة في معقّم معين باستخدام أسماء الأقسام لتحديد المطهر المستهدف لتجنب التأثير على المطهرات الأخرى.

التحقُّق

لا يوجد اختبار CTS مخصّص لـ BoundSan. بدلاً من ذلك، تأكد من أن CTS اجتياز الاختبارات مع تفعيل BoundSan أو بدونه للتحقق من أنه لا يؤثر الجهاز.

تحديد المشاكل وحلّها

قم باختبار المكونات بدقة بعد تمكين BoundSan للتأكد من أن أي ملفات تتم معالجة عمليات الوصول إلى خارج الحدود التي لم يتم اكتشافها.

يمكن بسهولة تحديد أخطاء BoundSan لأنّها تتضمّن ما يلي: رسالة إلغاء عملية النشر في Tombstone:

    pid: ###, tid: ###, name: Binder:###  >>> /system/bin/foobar <<<
    signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
    Abort message: 'ubsan: out-of-bounds'

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

    external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'