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 مرة أخرى، ما قد يؤدي إلى ظهور برامج تشغيل معطّلة.