🇰🇷 한글 설명
Linux 커널의 BPF ringbuf에서 __bpf_ringbuf_reserve 함수가 tracepoint 내부(선점 비활성화 상태)에서 호출되는데, spinlock_t를 사용하여 RT(Real-Time) 커널에서 'sleep in atomic' 경고가 발생하는 문제입니다. 이를 raw_spinlock_t로 변경하여 해결했습니다.
💡 쉬운 설명
리눅스 커널의 실시간(RT) 버전에서 특정 기능이 잘못된 잠금 방식을 사용해 시스템 경고나 불안정이 생길 수 있습니다. 잠금 방식을 바꿔서 이 문제를 고쳤습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
bpf: Use raw_spinlock_t in ringbuf
The function __bpf_ringbuf_reserve is invoked from a tracepoint, which
disables preemption. Using spinlock_t in this context can lead to a
"sleep in atomic" warning in the RT variant. This issue is illustrated
in the example below:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 556208, name: test_progs
preempt_count: 1, expected: 0
RCU nest depth: 1, expected: 1
INFO: lockdep is turned off.
Preemption disabled at:
[<ffffd33a5c88ea44>] migrate_enable+0xc0/0x39c
CPU: 7 PID: 556208 Comm: test_progs Tainted: G
Hardware name: Qualcomm SA8775P Ride (DT)
Call trace:
dump_backtrace+0xac/0x130
show_stack+0x1c/0x30
dump_stack_lvl+0xac/0xe8
dump_stack+0x18/0x30
__might_resched+0x3bc/0x4fc
rt_spin_lock+0x8c/0x1a4
__bpf_ringbuf_reserve+0xc4/0x254
bpf_ringbuf_reserve_dynptr+0x5c/0xdc
bpf_prog_ac3d15160d62622a_test_read_write+0x104/0x238
trace_call_bpf+0x238/0x774
perf_call_bpf_enter.isra.0+0x104/0x194
perf_syscall_enter+0x2f8/0x510
trace_sys_enter+0x39c/0x564
syscall_trace_enter+0x220/0x3c0
do_el0_svc+0x138/0x1dc
el0_svc+0x54/0x130
el0t_64_sync_handler+0x134/0x150
el0t_64_sync+0x17c/0x180
Switch the spinlock to raw_spinlock_t to avoid this error.
📍 영향받는 시스템
BPF ringbuf를 사용하는 PREEMPT_RT 설정의 Linux 커널 (수정 커밋 이전 버전)
⚔️ 공격 벡터
로컬 사용자가 tracepoint에 연결된 BPF 프로그램을 통해 커널 경고 또는 서비스 불안정을 유발할 수 있음 (CVSS 5.5, 주로 서비스 거부 영향)
🛡️ 대응 방법
수정이 포함된 최신 Linux 커널 버전으로 업데이트 (배포판 보안 업데이트 적용)
🔧 검증 코드
출력된 커널 버전을 배포판의 보안 권고문에서 CVE-2024-50138 수정 버전과 비교하여, 같거나 이후 버전이면 패치된 것이고 이전 버전이면 업데이트가 필요합니다.
uname -r && (dpkg -l linux-image-$(uname -r) 2>/dev/null || rpm -q kernel 2>/dev/null) | head -5