GKI 16-6.12 android-mainline errata

Bu sayfada, android-mainline'da bulunan ve iş ortakları için önemli olabilecek 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'in yeni sürümünde, dizinin boyutunun __counted_by özelliği kullanılarak diziye bağlı ayrı bir değişkende depolandığı diziler için bir sınır temizleyici sunuluyor. Dizi boyutu düzgün şekilde güncellenmezse bu özellik çekirdek panik durumuna 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 gereklidir. CONFIG_UBSAN_TRAP etkinleştirildiğinde ise sınır temizleyici, herhangi bir bulguda çekirdek panik durumunu tetikler.

      • Sınırlayıcı temizleyicinin önceki sürümü yalnızca sabit boyutlu dizileri kontrol ediyor ve dinamik olarak ayrılan dizileri kontrol edemiyordu. Yeni sürüm, çalışma zamanında dizi sınırlarını belirlemek ve sınır dışı erişimle ilgili daha fazla durumu tespit etmek için __counted_by özelliğini kullanır. Ancak bazı durumlarda, diziye boyut değişkeni ayarlanmadan önce erişilir. Bu durum, sınır temizleyicisini tetikleyerek çekirdek panik durumuna neden olur. Bu sorunu gidermek için aosp/3343204'te gösterildiği gibi, temel belleği ayırdıktan hemen sonra dizinin boyutunu ayarlayın.
    • CONFIG_UBSAN_SIGNED_WRAP hakkında: Clang'in yeni sürümü, -fwrapv derleyici işaretine rağmen işaretli tam sayı taşmasını ve taşma altını temizler. -fwrapv işareti, işaretli tam sayıları, tanımlanmış taşma davranışına sahip ikiye tümleyen işaretsiz tam sayılar olarak ele almak için tasarlanmıştır.

      • Linux çekirdeğinde işaretli tam sayı taşmasını temizlemek hataların belirlenmesine yardımcı olsa da taşmanın kasıtlı olduğu durumlar vardır (ör. atomic_long_t ile). Bu nedenle, 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 çekirdek panik durumunu tetikleyecek şekilde yapılandırılır. Ancak bu davranışı 23 Ekim ile 12 Kasım arasında devre dışı bıraktık. Bunu, 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 landing
    • Ö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üklenememesiyle ilgili sorunlar tespit edildi. Sürücü hatalarını ortaya çıkaran değişiklik, 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") taahhüdü olarak tanımlandı ve aosp/3287735'te geçici olarak geri alındı. Bu değişiklik, CONFIG_OF_OVERLAY'yı seçer ve CONFIG_OF_OVERLAY, CONFIG_OF_DYNAMIC'yı seçer. !OF_DYNAMIC ile of_node_get() ve of_node_put() üzerinde referans sayımı, noops olarak uygulandıkları için etkili bir şekilde devre dışı bırakılır. OF_DYNAMIC yeniden etkinleştirildiğinde, struct device_node için referans sayımını yanlış uygulayan sürücülerdeki sorunlar ortaya çıkar. Bu durum, bellek bozulması, boşaltıldıktan sonra kullanım ve bellek sızıntıları gibi çeşitli hatalara neden olur.
    • OF ayrıştırmayla ilgili API'lerin tüm kullanımları incelenmelidir. Aşağıdaki liste kısmi olsa da gözlemlediğimiz durumları içermektedir:
      • Ü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() işlevini çağırır. Bu işlevleri çağırmadan önce of_node_get() eklenmesi gerekebilir (örneğin, aynı düğümle bağımsız değişken olarak tekrar tekrar çağrıldığında):
          • 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 çıkış türünden sonra device_node kullanılması:
          • 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 * özelliklerine device_node üzerinden doğrudan işaretçiler tutmaktan kaçının. Örneğin, aşağıdakileri kullanın:
          • 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ıları:
        • device_node alıp referansını kaldırmayı unutma (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()
      • Bir döngü yinelemesinden device_node tutma. Aşağıdaki işlevlerden birinden dönüyorsanız veya bu işlevleri kesintiye uğratıyorsanı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'u kullanıma sunarken geri yüklendi 6.12-rc4 (aosp/3315251 adresine bakın) CONFIG_OF_DYNAMIC tekrar etkinleştirildi ve hatalı sürücüler kullanıma sunuldu.