GKI 16-6.12 android-mainline errata

توضّح هذه الصفحة المشاكل المهمة وإصلاحات الأخطاء التي تم العثور عليها في android-mainline والتي قد تكون مهمة للشركاء.

‫15 نوفمبر 2024

  • تم تعديل Clang إلى الإصدار 19.0.1 لكل من android-mainline وandroid16-6.12

    • الملخّص: يقدّم الإصدار الجديد من Clang أداة تنظيف حدود للمصفوفات، حيث يتم تخزين حجم المصفوفة في متغيّر منفصل مرتبط بالمصفوفة باستخدام السمة __counted_by. قد تتسبّب هذه الميزة في حدوث خطأ فادح في النواة إذا لم يتم تعديل حجم المصفوفة بشكل صحيح. تبدو رسالة الخطأ كما يلي:
    UBSAN: array-index-out-of-bounds in common/net/wireless/nl80211.c
    index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]')
    
    • التفاصيل: أداة تنظيف الحدود ضرورية لحماية سلامة النواة من خلال رصد عمليات الوصول خارج الحدود. وعند تفعيل CONFIG_UBSAN_TRAP، يؤدي برنامج تنظيف الحدود إلى حدوث خطأ فادح في النواة عند العثور على أي مشكلة.

      • كانت النسخة السابقة من أداة تنظيف الحدود تتحقّق فقط من المصفوفات ذات الحجم الثابت، ولم يكن بإمكانها التحقّق من المصفوفات التي يتم تخصيصها بشكل ديناميكي. يستخدم الإصدار الجديد السمة __counted_by لتحديد حدود المصفوفة في وقت التشغيل ورصد المزيد من حالات الوصول إلى خارج الحدود. ومع ذلك، في بعض الحالات، يتم الوصول إلى المصفوفة قبل ضبط متغيّر الحجم، ما يؤدي إلى تشغيل أداة تنظيف الحدود والتسبّب في حدوث خطأ فادح في النواة. لحلّ هذه المشكلة، اضبط حجم المصفوفة مباشرةً بعد تخصيص الذاكرة الأساسية، كما هو موضّح في aosp/3343204.
    • حول CONFIG_UBSAN_SIGNED_WRAP: يعمل الإصدار الجديد من Clang على تنظيف الأعداد الصحيحة الموقّعة التي تتجاوز الحد الأقصى أو الأدنى على الرغم من علامة برنامج التجميع -fwrapv. تم تصميم العلامة -fwrapv للتعامل مع الأعداد الصحيحة الموقّعة على أنّها أعداد صحيحة غير موقّعة بنظام المتمم الثنائي مع تحديد سلوك تجاوز السعة.

      • على الرغم من أنّ تنظيف تجاوز عدد صحيح موقّع في نواة Linux يمكن أن يساعد في تحديد الأخطاء، هناك حالات يكون فيها التجاوز مقصودًا، على سبيل المثال، مع atomic_long_t. نتيجةً لذلك، تم CONFIG_UBSAN_SIGNED_WRAP إيقاف السلوك التلقائي للسماح لـ UBSAN بالعمل كأداة تنظيف للحدود فقط.
    • لمحة عن CONFIG_UBSAN_TRAP: تم ضبط UBSAN لتشغيل حالة الذعر في النواة عند رصد مشكلة لحماية سلامة النواة. ومع ذلك، أوقفنا هذه الميزة من 23 أكتوبر إلى 12 نوفمبر. وقد اتّخذنا هذا الإجراء لإتاحة تحديث برنامج الترجمة أثناء حلّ المشاكل المعروفة في __counted_by.

‫1 نوفمبر 2024

  • إصدار Linux 6.12-rc4
    • الملخّص: CONFIG_OF_DYNAMIC قد يؤدي إلى حدوث تراجعات كبيرة في أداء برامج التشغيل المعطّلة.
    • التفاصيل: أثناء دمج Linux 6.12-rc1 في android-mainline، لاحظنا مشاكل في تعذُّر تحميل برامج التشغيل خارج الشجرة. تم تحديد التغيير الذي كشف عن أخطاء برنامج التشغيل على أنّه عملية الإيداع 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")، وقد تراجعنا عنه مؤقتًا في aosp/3287735. يؤدي التغيير إلى تحديد CONFIG_OF_OVERLAY، ما يؤدي إلى تحديد CONFIG_OF_DYNAMIC. باستخدام !OF_DYNAMIC، يتم إيقاف ميزة احتساب المراجع في of_node_get() وof_node_put() بشكل فعّال لأنّها يتم تنفيذها على أنّها noops. سيؤدي تفعيل OF_DYNAMIC مجددًا إلى الكشف عن مشاكل في برامج التشغيل التي تنفّذ بشكل خاطئ عملية احتساب المراجع الخاصة بـ struct device_node. ويؤدي ذلك إلى حدوث أنواع مختلفة من الأخطاء، مثل تلف الذاكرة واستخدام ذاكرة معيّنة بعد تفريغها وتسرّب الذاكرة.
    • يجب فحص جميع استخدامات واجهات برمجة التطبيقات ذات الصلة بتحليل OF. القائمة التالية جزئية، ولكنها تتضمّن حالات لاحظناها:
      • الاستخدام بعد التثبيت (UAF):
        • إعادة استخدام وسيطة device_node نفسها: تستدعي هذه الدوال of_node_put() على العقدة المحدّدة، وقد تحتاج إلى إضافة of_node_get() قبل استدعائها (على سبيل المثال، عند استدعائها بشكل متكرّر مع العقدة نفسها كوسيطة):
          • of_find_compatible_node()
          • of_find_node_by_name()
          • of_find_node_by_path()
          • of_find_node_by_type()
          • of_get_next_cpu_node()
          • of_get_next_parent()
          • of_get_next_child()
          • of_get_next_available_child()
          • of_get_next_reserved_child()
          • of_find_node_with_property()
          • of_find_matching_node_and_match()
        • استخدام device_node بعد أي نوع من الخروج من حلقات تكرار معيّنة:
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • الاحتفاظ بمؤشرات مباشرة إلى سمات char * من device_node في أي مكان، مثلاً باستخدام:
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • تسرّبات الذاكرة:
        • الحصول على device_node ونسيان إلغاء مرجعه (of_node_put()). يجب تحرير العُقد التي يتم عرضها من هذه العُقد في مرحلة ما:
          • of_find_compatible_node()
          • of_find_node_by_name()
          • of_find_node_by_path()
          • of_find_node_by_type()
          • of_find_node_by_phandle()
          • of_parse_phandle()
          • of_find_node_opts_by_path()
          • of_get_next_cpu_node()
          • of_get_compatible_child()
          • of_get_child_by_name()
          • of_get_parent()
          • of_get_next_parent()
          • of_get_next_child()
          • of_get_next_available_child()
          • of_get_next_reserved_child()
          • of_find_node_with_property()
          • of_find_matching_node_and_match()
      • الاحتفاظ بقيمة device_node من تكرار حلقي إذا كنت ستعود أو ستخرج من إحدى الحالات التالية، عليك إسقاط المرجع المتبقي في مرحلة ما:
        • for_each_available_child_of_node()
        • for_each_child_of_node()
        • for_each_node_by_type()
        • for_each_compatible_node()
        • of_for_each_phandle()
    • تمت استعادة التغيير المذكور سابقًا أثناء إطلاق Linux 6.12-rc4 (راجِع aosp/3315251) ما أدّى إلى تفعيل CONFIG_OF_DYNAMIC مرة أخرى، ما قد يؤدي إلى ظهور برامج تشغيل معطّلة.