GKI 16-6.12 android-mainline errata

Bu sayfada, android-mainline'te bulunan ve iş ortakları için önemli olabilecek önemli sorunlar ve hata düzeltmeleri açıklanmaktadır.

15 Kasım 2024

  • Clang, android-mainline ve android16-6.12 için 19.0.1 sürümüne güncellendi

    • Özet: Clang'ın yeni sürümünde, diziler için bir sınır temizleyici tanıtıldı. Bu temizleyicide, dizinin boyutu __counted_by özelliği kullanılarak diziye bağlı ayrı bir değişkende saklanır. Dizi boyutu düzgün şekilde güncellenmezse bu özellik çekirdek paniğine neden olabilir. Hata mesajı şu şekilde görünür:
    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 *[]')
    
    • Ayrıntılar: Sınır temizleyici, sınır dışı erişimi tespit ederek çekirdeğin bütünlüğünü korumak için çok önemlidir. CONFIG_UBSAN_TRAP etkinleştirildiğinde, sınır temizleyici herhangi bir bulguda çekirdek paniği tetikler.

      • Sınır temizleyicinin önceki sürümü yalnızca sabit boyutlu dizileri kontrol ediyordu ve dinamik olarak ayrılmış dizileri kontrol edemiyordu. Yeni sürüm, çalışma zamanında dizi sınırlarını belirlemek ve daha fazla sınır dışı erişim durumunu tespit etmek için __counted_by özelliğini kullanır. Ancak bazı durumlarda, boyut değişkeni ayarlanmadan önce diziye erişilir. Bu durum, sınır temizleyiciyi tetikler ve çekirdek paniğine neden olur. Bu sorunu gidermek için aosp/3343204 bölümünde gösterildiği gibi, temel belleği ayırdıktan hemen sonra dizi boyutunu ayarlayın.
    • CONFIG_UBSAN_SIGNED_WRAP hakkında: Clang'ın yeni sürümü, -fwrapv derleyici işaretine rağmen imzalı tam sayı taşması ve eksik akışı temizler. -fwrapv işareti, işaretli tam sayıları tanımlanmış taşma davranışına sahip ikilik tamamlayıcı işaretsiz tam sayılar olarak işlemek için tasarlanmıştır.

      • Linux çekirdeğinde işaretli tam sayı taşmalarını temizlemek hataları tespit etmeye yardımcı olsa da taşmanın kasıtlı olduğu durumlar da vardır (ör. atomic_long_t). Sonuç olarak, UBSAN'ın yalnızca sınır temizleyici olarak çalışmasına izin vermek için CONFIG_UBSAN_SIGNED_WRAP devre dışı bırakıldı.
    • CONFIG_UBSAN_TRAP hakkında: UBSAN, çekirdeğin bütünlüğünü korumak için bir sorun algıladığında kernel paniği tetikleyecek şekilde yapılandırılmıştır. Ancak bu davranışı 23 Ekim ile 12 Kasım arasında devre dışı bıraktık. Bu işlemi, bilinen __counted_by sorunlarını düzeltirken derleyici güncellemesinin engellemesini kaldırmak için yaptık.

1 Kasım 2024

  • Linux 6.12-rc4 kullanıma sunuldu
    • Özet: CONFIG_OF_DYNAMIC, hatalı sürücülerde ciddi gerilemelere neden olabilir.
    • Ayrıntılar: Linux 6.12-rc1, android-mainline ile birleştirilirken ağaç dışı sürücülerin yüklenemediğiyle ilgili sorunlar fark ettik. Sürücünün hatalarını ortaya çıkaran değişiklik, 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") commit'i olarak tanımlandı ve aosp/3287735 adresinde geçici olarak geri alındı. Değişiklik, CONFIG_OF_OVERLAY'ü seçer ve CONFIG_OF_DYNAMIC'u seçer. !OF_DYNAMIC ile of_node_get() ve of_node_put()'de referans sayımı, noops olarak uygulandıkları için etkili bir şekilde devre dışı bırakılır. OF_DYNAMIC'ü tekrar etkinleştirmek, struct device_node için referans sayımını yanlış uygulayan sürücülerdeki sorunları ortaya çıkarır. Bu durum, bellek bozulması, boşaltıldıktan sonra kullanım ve bellek sızıntısı gibi çeşitli hatalara neden olur.
    • OF ayrıştırma ile ilgili API'lerin tüm kullanımları incelenmelidir. Aşağıdaki liste kısmidir ancak gözlemlediğimiz durumları içerir:
      • Ücretsiz kullanımdan sonra (UAF):
        • Aynı device_node bağımsız değişkeninin yeniden kullanılması: Bu işlevler, verilen düğümde of_node_put() çağrısı yapar. Bu işlevleri çağırmadan önce bir of_node_get() eklemeniz gerekebilir (örneğin, bağımsız değişken olarak aynı düğümle tekrar tekrar çağırırken):
          • 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()
        • Belirli döngülerden herhangi bir şekilde çıktıktan sonra device_node kullanımı:
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • device_node'dan char * mülklerine doğrudan işaretçiler tutmak (örneğin, aşağıdakileri kullanarak):
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • Bellek sızıntısı:
        • device_node almak ve referansını kaldırmayı unutmak (of_node_put()). Bunlardan döndürülen düğümlerin bir noktada serbest bırakılması gerekir:
          • 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()
      • Döngü iterasyonundan bir device_node tutma. Aşağıdakilerden birinde dönüyor veya ara veriyorsanız bir noktada kalan referansı bırakmanız gerekir:
        • for_each_available_child_of_node()
        • for_each_child_of_node()
        • for_each_node_by_type()
        • for_each_compatible_node()
        • of_for_each_phandle()
    • Daha önce bahsedilen değişiklik, Linux 6.12-rc4 (aosp/3315251 adresine bakın) kullanıma sunulurken geri yüklendi. Bu değişiklik, CONFIG_OF_DYNAMIC'ın tekrar etkinleştirilmesine ve hatalı sürücülerin ortaya çıkmasına neden olabilir.