요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
Undefined Behavior Sanitizer - UBSAN
====================================
UBSAN is a runtime undefined behaviour checker.
UBSAN uses compile-time instrumentation to catch undefined behavior (UB).
Compiler inserts code that perform certain kinds of checks before operations
that may cause UB. If check fails (i.e. UB detected) __ubsan_handle_*
function called to print error message.
GCC has that feature since 4.9.x [1_] (see ``-fsanitize=undefined`` option and
its suboptions). GCC 5.x has more checkers implemented [2_].
Report example
--------------
::
================================================================================
UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
shift exponent 32 is to large for 32-bit type 'unsigned int'
CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc1+ #26
0000000000000000 ffffffff82403cc8 ffffffff815e6cd6 0000000000000001
ffffffff82403cf8 ffffffff82403ce0 ffffffff8163a5ed 0000000000000020
ffffffff82403d78 ffffffff8163ac2b ffffffff815f0001 0000000000000002
Call Trace:
[<ffffffff815e6cd6>] dump_stack+0x45/0x5f
[<ffffffff8163a5ed>] ubsan_epilogue+0xd/0x40
[<ffffffff8163ac2b>] __ubsan_handle_shift_out_of_bounds+0xeb/0x130
[<ffffffff815f0001>] ? radix_tree_gang_lookup_slot+0x51/0x150
[<ffffffff8173c586>] _mix_pool_bytes+0x1e6/0x480
[<ffffffff83105653>] ? dmi_walk_early+0x48/0x5c
[<ffffffff8173c881>] add_device_randomness+0x61/0x130
[<ffffffff83105b35>] ? dmi_save_one_device+0xaa/0xaa
[<ffffffff83105653>] dmi_walk_early+0x48/0x5c
[<ffffffff831066ae>] dmi_scan_machine+0x278/0x4b4
[<ffffffff8111d58a>] ? vprintk_default+0x1a/0x20
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830b2240>] setup_arch+0x405/0xc2c
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ae053>] start_kernel+0x83/0x49a
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ad386>] x86_64_start_reservations+0x2a/0x2c
[<ffffffff830ad4f3>] x86_64_start_kernel+0x16b/0x17a
================================================================================
Usage
-----
To enable UBSAN, configure the kernel with::
CONFIG_UBSAN=y
To exclude files from being instrumented use::
UBSAN_SANITIZE_main.o := n
and to exclude all targets in one directory use::
UBSAN_SANITIZE := n
When disabled for all targets, specific files can be enabled using::
UBSAN_SANITIZE_main.o := y
Detection of unaligned accesses controlled through the separate option -
CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support
unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
still enable it in config, just note that it will produce a lot of UBSAN
reports.
References
----------
.. _1: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
.. _2: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
.. _3: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
UBSAN 개요와 compiler instrumentation
1-15SPDX 라이선스 식별자: GPL-2.0
Undefined Behavior Sanitizer - UBSAN
UBSAN은 runtime에 undefined behaviour를 검사하는 도구입니다.
UBSAN은 compile-time instrumentation을 사용해 undefined behavior, 즉 UB를 포착합니다. Compiler는 UB를 일으킬 수 있는 operation을 실행하기 전에 특정 검사를 수행하는 code를 삽입합니다. 검사에 실패해 UB가 감지되면 `__ubsan_handle_*` function을 호출하여 error message를 출력합니다.
GCC는 4.9.x부터 이 기능을 제공합니다. `-fsanitize=undefined` option과 그 suboption을 사용하며, GCC 5.x에는 더 많은 checker가 구현되어 있습니다.
Compile-time에 삽입한 검사에서 runtime report가 생성되는 경로입니다.
UBSAN report 예
16-48Report 예
다음 literal block은 `../include/linux/bitops.h:110:33`에서 32-bit `unsigned int`에 대해 shift exponent 32를 사용한 undefined behaviour report 전체입니다. `__ubsan_handle_shift_out_of_bounds`가 호출된 뒤 이어지는 call trace와 register-style address 정보를 원문 그대로 보존합니다.
================================================================================
UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
shift exponent 32 is to large for 32-bit type 'unsigned int'
CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc1+ #26
0000000000000000 ffffffff82403cc8 ffffffff815e6cd6 0000000000000001
ffffffff82403cf8 ffffffff82403ce0 ffffffff8163a5ed 0000000000000020
ffffffff82403d78 ffffffff8163ac2b ffffffff815f0001 0000000000000002
Call Trace:
[<ffffffff815e6cd6>] dump_stack+0x45/0x5f
[<ffffffff8163a5ed>] ubsan_epilogue+0xd/0x40
[<ffffffff8163ac2b>] __ubsan_handle_shift_out_of_bounds+0xeb/0x130
[<ffffffff815f0001>] ? radix_tree_gang_lookup_slot+0x51/0x150
[<ffffffff8173c586>] _mix_pool_bytes+0x1e6/0x480
[<ffffffff83105653>] ? dmi_walk_early+0x48/0x5c
[<ffffffff8173c881>] add_device_randomness+0x61/0x130
[<ffffffff83105b35>] ? dmi_save_one_device+0xaa/0xaa
[<ffffffff83105653>] dmi_walk_early+0x48/0x5c
[<ffffffff831066ae>] dmi_scan_machine+0x278/0x4b4
[<ffffffff8111d58a>] ? vprintk_default+0x1a/0x20
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830b2240>] setup_arch+0x405/0xc2c
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ae053>] start_kernel+0x83/0x49a
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ad386>] x86_64_start_reservations+0x2a/0x2c
[<ffffffff830ad4f3>] x86_64_start_kernel+0x16b/0x17a
================================================================================
설정, 선택적 instrumentation과 참고 자료
49-79사용법
UBSAN을 활성화하려면 kernel을 다음과 같이 설정합니다.
CONFIG_UBSAN=y
특정 file을 instrumentation 대상에서 제외하려면 다음을 사용합니다.
UBSAN_SANITIZE_main.o := n
한 directory의 모든 target을 제외하려면 다음을 사용합니다.
UBSAN_SANITIZE := n
모든 target에서 UBSAN을 비활성화한 상태로 특정 file만 다시 활성화하려면 다음을 사용합니다.
UBSAN_SANITIZE_main.o := y
Unaligned access 감지는 별도 option `CONFIG_UBSAN_ALIGNMENT`로 제어합니다. Unaligned access를 효율적으로 지원하는 architecture, 즉 `CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y`인 경우 기본값은 off입니다. Config에서 이를 직접 활성화할 수 있지만 매우 많은 UBSAN report가 생성될 수 있다는 점에 유의해야 합니다.
Kconfig와 Makefile 설정이 적용되는 범위를 비교합니다.
참고 자료
GCC 4.9 debugging option: `https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html`
현재 GCC debugging option: `https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html`
Clang UndefinedBehaviorSanitizer 문서: `https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html`
요약과 해설
ubsan.rst:1-79UBSAN은 compiler가 UB 가능 지점 앞에 삽입한 검사를 runtime에 실행하고, 실패하면 `__ubsan_handle_*`를 통해 위치와 call trace를 보고합니다.
`CONFIG_UBSAN=y`로 전체 기능을 켜고 `UBSAN_SANITIZE` 계열 Makefile 변수로 directory나 file별 instrumentation을 조정할 수 있습니다. Alignment 검사는 report 양이 많을 수 있어 별도 option으로 관리합니다.