GKI 16-6.12 — основные ошибки для Android

На этой странице описаны важные проблемы и исправления ошибок, обнаруженные в android-mainline , которые могут быть важны для партнеров.

15 ноября 2024 г.

  • Clang обновлен до 19.0.1 для android-mainline и android16-6.12

    • Описание: В новой версии 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 предназначен для обработки целых чисел со знаком как целых чисел без знака, дополненных до двух, с определенным поведением при переполнении.

      • Хотя очистка переполнения знакового целого числа в ядре Linux может помочь выявить ошибки, бывают случаи, когда переполнение является преднамеренным, например, с atomic_long_t . В результате CONFIG_UBSAN_SIGNED_WRAP был отключен , чтобы позволить UBSAN функционировать исключительно как средство очистки границ.
    • О CONFIG_UBSAN_TRAP : UBSAN настроен на запуск паники ядра при обнаружении проблемы для защиты целостности ядра. Однако мы отключили это поведение с 23 октября по 12 ноября . Мы сделали это, чтобы разблокировать обновление компилятора и одновременно исправить известные проблемы __counted_by .

1 ноября 2024 г.

  • Посадка Linux 6.12-rc4
    • Краткое описание: CONFIG_OF_DYNAMIC потенциально может вызвать серьезную регрессию для неисправных драйверов.
    • Подробности: при объединении Linux 6.12-rc1 с android-mainline мы заметили проблемы с невозможностью загрузки драйверов вне дерева. Изменение, выявившее ошибки драйвера, было идентифицировано как коммит 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") , и мы временно отменили его в aosp/3287735 . Изменение выбирает CONFIG_OF_OVERLAY , который выбирает CONFIG_OF_DYNAMIC . С помощью !OF_DYNAMIC подсчет ссылок на of_node_get() и of_node_put() фактически отключается, поскольку они реализованы как noops . Включение OF_DYNAMIC снова выявляет проблемы в драйверах, неправильно реализующих подсчет ссылок для struct device_node . Это вызывает различные типы ошибок, такие как повреждение памяти, использование после освобождения и утечки памяти.
    • Все случаи использования API, связанных с синтаксическим анализом OF, должны быть проверены. Следующий список является неполным, но содержит случаи, которые мы наблюдали:
      • Использовать после бесплатного (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()
    • Ранее упомянутое изменение было восстановлено при выпуске Linux 6.12-rc4 (см. aosp/3315251 ), снова включив CONFIG_OF_DYNAMIC и потенциально обнаруживая неисправные драйверы.
,

На этой странице описаны важные проблемы и исправления ошибок, обнаруженные в android-mainline , которые могут быть важны для партнеров.

15 ноября 2024 г.

  • Clang обновлен до 19.0.1 для android-mainline и android16-6.12

    • Описание: В новой версии 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 предназначен для обработки целых чисел со знаком как целых чисел без знака, дополненных до двух, с определенным поведением при переполнении.

      • Хотя очистка переполнения знакового целого числа в ядре Linux может помочь выявить ошибки, бывают случаи, когда переполнение является преднамеренным, например, с atomic_long_t . В результате CONFIG_UBSAN_SIGNED_WRAP был отключен , чтобы позволить UBSAN функционировать исключительно как средство очистки границ.
    • О CONFIG_UBSAN_TRAP : UBSAN настроен на запуск паники ядра при обнаружении проблемы для защиты целостности ядра. Однако мы отключили это поведение с 23 октября по 12 ноября . Мы сделали это, чтобы разблокировать обновление компилятора и одновременно исправить известные проблемы __counted_by .

1 ноября 2024 г.

  • Посадка Linux 6.12-rc4
    • Краткое описание: CONFIG_OF_DYNAMIC потенциально может вызвать серьезную регрессию для неисправных драйверов.
    • Подробности: при объединении Linux 6.12-rc1 с android-mainline мы заметили проблемы с невозможностью загрузки драйверов вне дерева. Изменение, выявившее ошибки драйвера, было идентифицировано как коммит 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") , и мы временно отменили его в aosp/3287735 . Изменение выбирает CONFIG_OF_OVERLAY , который выбирает CONFIG_OF_DYNAMIC . С помощью !OF_DYNAMIC подсчет ссылок на of_node_get() и of_node_put() фактически отключается, поскольку они реализованы как noops . Включение OF_DYNAMIC снова выявляет проблемы в драйверах, неправильно реализующих подсчет ссылок для struct device_node . Это вызывает различные типы ошибок, такие как повреждение памяти, использование после освобождения и утечки памяти.
    • Все случаи использования API, связанных с синтаксическим анализом OF, должны быть проверены. Следующий список является неполным, но содержит случаи, которые мы наблюдали:
      • Использовать после бесплатного (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()
    • Ранее упомянутое изменение было восстановлено при выпуске Linux 6.12-rc4 (см. aosp/3315251 ), снова включив CONFIG_OF_DYNAMIC и потенциально обнаруживая неисправные драйверы.