이 페이지에서는 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
컴파일러 플래그에도 불구하고 signed integer overflow 및 underflow를 정리합니다.-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_DYNAMIC
이 선택됩니다.!OF_DYNAMIC
를 사용하면of_node_get()
및of_node_put()
가noops
로 구현되므로 참조 수가 효과적으로 사용 중지됩니다.OF_DYNAMIC
를 다시 사용 설정하면struct device_node
의 참조 수를 잘못 구현하는 드라이버의 문제가 노출됩니다. 이로 인해 메모리 손상, use-after-free, 메모리 누수와 같은 다양한 유형의 오류가 발생합니다. - OF 파싱 관련 API의 모든 사용은 검사해야 합니다. 다음 목록은 일부이지만 지금까지 관찰된 사례를 포함합니다.
- Use after free (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()
- Use after free (UAF):
- 앞서 언급한 변경사항은 Linux
6.12-rc4
(aosp/3315251 참고)를 출시하는 동안 복원되어CONFIG_OF_DYNAMIC
를 다시 사용 설정하고 결함이 있는 드라이버를 노출할 수 있습니다.
- 요약: