Errata android-mainline GKI 16-6.12

Halaman ini menjelaskan masalah penting dan perbaikan bug yang ditemukan di android-mainline yang mungkin penting 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: Sanitasi batas sangat penting untuk melindungi integritas kernel dengan mendeteksi akses di luar batas. Dengan CONFIG_UBSAN_TRAP diaktifkan, sanitizer batas memicu kernel panic pada setiap temuan.

      • 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 sanitizer batas dan menyebabkan panik kernel. Untuk mengatasi masalah ini, tetapkan ukuran array segera setelah mengalokasikan memori yang mendasarinya, seperti yang diilustrasikan dalam aosp/3343204.
    • Tentang CONFIG_UBSAN_SIGNED_WRAP: Versi baru Clang membersihkan overflow dan underflow bilangan bulat bertanda meskipun ada tanda compiler -fwrapv. Flag -fwrapv dirancang untuk memperlakukan bilangan bulat bertanda sebagai bilangan bulat tidak bertanda komplemen dua dengan perilaku overflow yang ditentukan.

      • Meskipun membersihkan overflow bilangan bulat bertanda di kernel Linux dapat membantu mengidentifikasi bug, ada kasus ketika overflow disengaja, misalnya, dengan atomic_long_t. Akibatnya, CONFIG_UBSAN_SIGNED_WRAP telah dinonaktifkan agar UBSAN berfungsi hanya sebagai sanitizer 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 membuka blokir 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 Linux 6.12-rc1 ke android-mainline, kami melihat masalah terkait driver di luar pohon 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 mengembalikannya untuk sementara di aosp/3287735. Perubahan memilih CONFIG_OF_OVERLAY, yang memilih CONFIG_OF_DYNAMIC. Dengan !OF_DYNAMIC, penghitungan referensi pada of_node_get() dan of_node_put() secara efektif dinonaktifkan karena diimplementasikan sebagai noops. Mengaktifkan OF_DYNAMIC lagi akan memunculkan 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 parsing OF harus diperiksa. Daftar berikut bersifat parsial, tetapi berisi kasus yang telah kami amati:
      • Penggunaan setelah gratis (UAF):
        • Penggunaan kembali argumen device_node yang sama: Fungsi tersebut memanggil of_node_put() pada node yang diberikan, 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 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 di sekitar, 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 harus 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 keluar dari dalam berikut, Anda perlu menghilangkan referensi yang tersisa di beberapa titik:
        • 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 mendaratkan Linux 6.12-rc4 (lihat aosp/3315251) yang mengaktifkan CONFIG_OF_DYNAMIC lagi dan berpotensi mengekspos driver yang rusak.