خطای خط اصلی اندروید GKI 16-6.12

این صفحه مشکلات مهم و رفع اشکال‌های موجود در android-mainline را شرح می‌دهد که ممکن است برای شرکا مهم باشد.

15 نوامبر 2024

  • Clang برای android-mainline و android16-6.12 به 19.0.1 به روز شده است.

    • خلاصه: نسخه جدید 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 برای رفتار با اعداد صحیح امضا شده به عنوان اعداد صحیح بدون علامت مکمل دو با رفتار سرریز تعریف شده طراحی شده است.

      • در حالی که پاکسازی سرریز اعداد صحیح امضا شده در هسته لینوکس می تواند به شناسایی اشکالات کمک کند، مواردی وجود دارد که سرریز عمدی است، به عنوان مثال، با atomic_long_t . در نتیجه، CONFIG_UBSAN_SIGNED_WRAP غیرفعال شده است تا به UBSAN اجازه دهد صرفاً به عنوان یک ضدعفونی کننده محدوده عمل کند.
    • درباره CONFIG_UBSAN_TRAP : UBSAN به گونه‌ای پیکربندی شده است که وقتی مشکلی را برای محافظت از یکپارچگی هسته تشخیص می‌دهد، باعث ایجاد وحشت در هسته شود. با این حال، ما این رفتار را از 23 اکتبر تا 12 نوامبر غیرفعال کردیم. ما این کار را برای رفع انسداد به‌روزرسانی کامپایلر انجام دادیم در حالی که مشکلات شناخته شده __counted_by برطرف کردیم.

1 نوامبر 2024

  • لینوکس 6.12-rc4 فرود
    • خلاصه: CONFIG_OF_DYNAMIC به طور بالقوه باعث ایجاد رگرسیون شدید برای درایورهای معیوب می شود.
    • جزئیات: در حین ادغام Linux 6.12-rc1 در android-mainline متوجه مشکلاتی در بارگیری درایورهای خارج از درخت شدیم. تغییری که باگ‌های درایور را آشکار کرد به‌عنوان commit 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") شناسایی شد و ما به‌طور موقت آن را در aosp/3287735 برگردانیم. این تغییر CONFIG_OF_OVERLAY انتخاب می کند که CONFIG_OF_DYNAMIC انتخاب می کند. با !OF_DYNAMIC ، ref-counting روی of_node_get() و of_node_put() به طور موثر غیرفعال می شود زیرا آنها به صورت noops پیاده سازی می شوند. فعال کردن مجدد OF_DYNAMIC مشکلاتی را در درایورهایی که به اشتباه ref-counting را برای struct device_node پیاده سازی می کنند، آشکار می کند. این باعث انواع مختلفی از خطاها مانند خرابی حافظه، استفاده پس از آزاد شدن و نشت حافظه می شود.
    • همه کاربردهای APIهای مربوط به تجزیه باید بازرسی شوند. لیست زیر جزئی است، اما شامل مواردی است که ما مشاهده کرده ایم:
      • استفاده بعد از رایگان (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()
    • تغییری که قبلاً ذکر شد، هنگام فرود لینوکس 6.12-rc4 (به aosp/3315251 مراجعه کنید) بازیابی شد و CONFIG_OF_DYNAMIC دوباره فعال کرد و احتمالاً درایورهای معیوب را فاش کرد.
،

این صفحه مشکلات مهم و رفع اشکال‌های موجود در android-mainline را شرح می‌دهد که ممکن است برای شرکا مهم باشد.

15 نوامبر 2024

  • Clang برای android-mainline و android16-6.12 به 19.0.1 به روز شده است.

    • خلاصه: نسخه جدید 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 برای رفتار با اعداد صحیح امضا شده به عنوان اعداد صحیح بدون علامت مکمل دو با رفتار سرریز تعریف شده طراحی شده است.

      • در حالی که پاکسازی سرریز اعداد صحیح امضا شده در هسته لینوکس می تواند به شناسایی اشکالات کمک کند، مواردی وجود دارد که سرریز عمدی است، به عنوان مثال، با atomic_long_t . در نتیجه، CONFIG_UBSAN_SIGNED_WRAP غیرفعال شده است تا به UBSAN اجازه دهد صرفاً به عنوان یک ضدعفونی کننده محدوده عمل کند.
    • درباره CONFIG_UBSAN_TRAP : UBSAN به گونه‌ای پیکربندی شده است که وقتی مشکلی را برای محافظت از یکپارچگی هسته تشخیص می‌دهد، باعث ایجاد وحشت در هسته شود. با این حال، ما این رفتار را از 23 اکتبر تا 12 نوامبر غیرفعال کردیم. ما این کار را برای رفع انسداد به‌روزرسانی کامپایلر انجام دادیم در حالی که مشکلات شناخته شده __counted_by برطرف کردیم.

1 نوامبر 2024

  • لینوکس 6.12-rc4 فرود
    • خلاصه: CONFIG_OF_DYNAMIC به طور بالقوه باعث ایجاد رگرسیون شدید برای درایورهای معیوب می شود.
    • جزئیات: در حین ادغام Linux 6.12-rc1 در android-mainline متوجه مشکلاتی در بارگیری درایورهای خارج از درخت شدیم. تغییری که باگ‌های درایور را آشکار کرد به‌عنوان commit 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") شناسایی شد و ما به‌طور موقت آن را در aosp/3287735 برگردانیم. این تغییر CONFIG_OF_OVERLAY انتخاب می کند که CONFIG_OF_DYNAMIC انتخاب می کند. با !OF_DYNAMIC ، ref-counting روی of_node_get() و of_node_put() به طور موثر غیرفعال می شود زیرا آنها به صورت noops پیاده سازی می شوند. فعال کردن مجدد OF_DYNAMIC مشکلاتی را در درایورهایی که به اشتباه ref-counting را برای struct device_node پیاده سازی می کنند، آشکار می کند. این باعث انواع مختلفی از خطاها مانند خرابی حافظه، استفاده پس از آزاد شدن و نشت حافظه می شود.
    • همه کاربردهای APIهای مربوط به تجزیه باید بازرسی شوند. لیست زیر جزئی است، اما شامل مواردی است که ما مشاهده کرده ایم:
      • استفاده بعد از رایگان (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()
    • تغییری که قبلاً ذکر شد، هنگام فرود لینوکس 6.12-rc4 (به aosp/3315251 مراجعه کنید) بازیابی شد و CONFIG_OF_DYNAMIC دوباره فعال کرد و احتمالاً درایورهای معیوب را فاش کرد.