이 페이지에서는 파트너에게 중요할 수 있는 android-mainline
에서 발견된 중요한 문제와 버그 수정사항을 설명합니다.
2024년 11월 15일
android-mainline
및android16-6.12
의 Clang이 19.0.1로 업데이트됨- 요약: 새 버전의 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
플래그는 부호 있는 정수를 오버플로 동작이 정의된 2의 보수 부호 없는 정수로 처리하도록 설계되었습니다.- Linux 커널에서 부호 있는 정수 오버플로를 정리하면 버그를 식별하는 데 도움이 될 수 있지만
atomic_long_t
와 같이 오버플로가 의도적인 인스턴스가 있습니다. 따라서 UBSAN이 경계 소독제로만 작동하도록CONFIG_UBSAN_SIGNED_WRAP
이 사용 중지되었습니다.
- Linux 커널에서 부호 있는 정수 오버플로를 정리하면 버그를 식별하는 데 도움이 될 수 있지만
CONFIG_UBSAN_TRAP
정보: UBSAN은 커널의 무결성을 보호하기 위해 문제를 감지하면 커널 패닉을 트리거하도록 구성됩니다. 하지만 10월 23일부터 11월 12일까지는 이 동작이 사용 중지되었습니다. 알려진__counted_by
문제를 수정하는 동안 컴파일러 업데이트를 차단 해제하기 위해 이렇게 했습니다.
- 요약: 새 버전의 Clang에서는 배열의 크기가
2024년 11월 1일
- 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_OVERLAY
은CONFIG_OF_DYNAMIC
을 선택합니다.!OF_DYNAMIC
를 사용하면of_node_get()
및of_node_put()
의 참조 횟수가noops
로 구현되므로 사실상 사용 중지됩니다.OF_DYNAMIC
를 다시 사용 설정하면struct device_node
의 참조 수를 잘못 구현하는 드라이버의 문제가 노출됩니다. 이로 인해 메모리 손상, use-after-free, 메모리 누수와 같은 다양한 유형의 오류가 발생합니다. - OF 파싱 관련 API의 모든 사용을 검사해야 합니다. 다음 목록은 일부만 포함되어 있지만 Google에서 관찰한 사례가 포함되어 있습니다.
- 해제 후 사용 (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()
- 예를 들어 다음을 사용하여
device_node
에서char *
속성으로 직접 포인터를 유지합니다.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()
- 해제 후 사용 (UAF):
- 앞서 언급한 변경사항은 Linux
6.12-rc4
(aosp/3315251 참고)을 적용하는 동안 복원되어CONFIG_OF_DYNAMIC
이 다시 사용 설정되고 결함이 있는 드라이버가 노출될 수 있습니다.
- 요약: