Errata android-mainline GKI 16-6.12

Halaman ini menjelaskan masalah penting dan perbaikan bug yang ditemukan di android-mainline yang mungkin signifikan bagi partner.

15 November 2024

  • Clang diupdate ke 19.0.1 untuk android-mainline dan android16-6.12

    • Ringkasan: Clang versi baru memperkenalkan sanitizer batas untuk array, dengan ukuran array disimpan dalam variabel terpisah yang ditautkan ke array menggunakan atribut __counted_by. Fitur ini dapat menyebabkan kernel panic jika ukuran array tidak diperbarui dengan benar. Pesan error terlihat seperti ini:
    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 *[]')
    
    • Detail: Pemurni batas sangat penting untuk melindungi integritas kernel dengan mendeteksi akses di luar batas. Dan dengan mengaktifkan CONFIG_UBSAN_TRAP, pembersih batas akan memicu kernel panic pada temuan apa pun.

      • Versi sebelumnya dari pembersih batas hanya memeriksa array berukuran tetap dan tidak dapat memeriksa array yang dialokasikan secara dinamis. Versi baru menggunakan atribut __counted_by untuk menentukan batas array saat runtime dan mendeteksi lebih banyak kasus akses di luar batas. Namun, dalam beberapa kasus, array diakses sebelum variabel ukuran ditetapkan, yang memicu pembersihan batas dan menyebabkan kernel panik. Untuk mengatasi masalah ini, tetapkan ukuran array segera setelah mengalokasikan memori yang mendasarinya, seperti yang diilustrasikan dalam aosp/3343204.
    • Tentang CONFIG_UBSAN_SIGNED_WRAP: Clang versi baru membersihkan overflow dan underflow bilangan bulat bertanda tangan meskipun ada flag compiler -fwrapv. Flag -fwrapv dirancang untuk memperlakukan bilangan bulat bertanda sebagai bilangan bulat tanpa tanda komplemen dua dengan perilaku overflow yang ditentukan.

      • Meskipun membersihkan overflow bilangan bulat bertanda di kernel Linux dapat membantu mengidentifikasi bug, ada kalanya overflow dilakukan secara sengaja, misalnya, dengan atomic_long_t. Oleh karena itu, CONFIG_UBSAN_SIGNED_WRAP telah dinonaktifkan untuk memungkinkan UBSAN berfungsi hanya sebagai pembersih batas.
    • Tentang CONFIG_UBSAN_TRAP: UBSAN dikonfigurasi untuk memicu kernel panic saat mendeteksi masalah untuk melindungi integritas kernel. Namun, kami menonaktifkan perilaku ini dari 23 Oktober hingga 12 November. Kami melakukan hal ini untuk berhenti memblokir update compiler saat kami memperbaiki masalah __counted_by yang diketahui.

1 November 2024

  • Peluncuran Linux 6.12-rc4
    • Ringkasan: CONFIG_OF_DYNAMIC berpotensi menyebabkan regresi parah untuk driver yang rusak.
    • Detailnya: Saat menggabungkan 6.12-rc1 Linux ke dalam android-mainline, kami melihat masalah pada driver di luar hierarki yang gagal dimuat. Perubahan yang mengekspos bug driver diidentifikasi sebagai commit 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") dan kami sementara mengembalikannya di aosp/3287735. Perubahan ini memilih CONFIG_OF_OVERLAY, yang memilih CONFIG_OF_DYNAMIC. Dengan !OF_DYNAMIC, penghitungan referensi pada of_node_get() dan of_node_put() dinonaktifkan secara efektif karena diimplementasikan sebagai noops. Mengaktifkan OF_DYNAMIC lagi akan mengekspos masalah pada driver yang salah menerapkan penghitungan referensi untuk struct device_node. Hal ini menyebabkan berbagai jenis error seperti kerusakan memori, use-after-free, dan kebocoran memori.
    • Semua penggunaan API terkait penguraian OF harus diperiksa. Daftar berikut bersifat sebagian, tetapi berisi kasus yang telah kami amati:
      • Use after free (UAF):
        • Penggunaan kembali argumen device_node yang sama: Fungsi tersebut memanggil of_node_put() pada node yang diberikan, yang mungkin perlu menambahkan of_node_get() sebelum memanggilnya (misalnya, saat memanggil berulang kali dengan node yang sama sebagai argumen):
          • 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()
        • Penggunaan device_node setelah jenis keluar dari loop tertentu:
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • Mempertahankan pointer langsung ke properti char * dari device_node, misalnya, menggunakan:
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • Kebocoran memori:
        • Mendapatkan device_node dan lupa untuk membatalkan referensinya (of_node_put()). Node yang ditampilkan dari ini perlu dibebaskan pada suatu saat:
          • 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()
      • Mempertahankan device_node dari iterasi loop. Jika Anda kembali atau berhenti dari dalam hal berikut, Anda harus menghapus referensi yang tersisa pada suatu saat:
        • for_each_available_child_of_node()
        • for_each_child_of_node()
        • for_each_node_by_type()
        • for_each_compatible_node()
        • of_for_each_phandle()
    • Perubahan yang disebutkan sebelumnya dipulihkan saat meluncurkan 6.12-rc4 Linux (lihat aosp/3315251) yang mengaktifkan CONFIG_OF_DYNAMIC lagi dan berpotensi mengekspos driver yang rusak.