🇰🇷 한글 설명
Linux 커널의 clocksource_verify_choose_cpus() 함수가 preemption이 비활성화된 상태에서 get_random_u32()를 호출하는 문제입니다. PREEMPT_RT 커널에서 random.c의 spinlock이 sleeping lock이 되어 atomic context에서 획득 불가능하여 커널 패닉이 발생합니다. migrate_disable()을 사용하여 atomic context를 피하도록 수정되었습니다.
💡 쉬운 설명
Linux 커널이 난수 생성 시 특정 상황에서 필요한 잠금을 획득할 수 없는 상태에 있었던 문제입니다. 이를 더 안전한 방식으로 처리하도록 커널 코드를 수정했습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
clocksource: Use migrate_disable() to avoid calling get_random_u32() in atomic context
The following bug report happened with a PREEMPT_RT kernel:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2012, name: kwatchdog
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
get_random_u32+0x4f/0x110
clocksource_verify_choose_cpus+0xab/0x1a0
clocksource_verify_percpu.part.0+0x6b/0x330
clocksource_watchdog_kthread+0x193/0x1a0
It is due to the fact that clocksource_verify_choose_cpus() is invoked with
preemption disabled. This function invokes get_random_u32() to obtain
random numbers for choosing CPUs. The batched_entropy_32 local lock and/or
the base_crng.lock spinlock in driver/char/random.c will be acquired during
the call. In PREEMPT_RT kernel, they are both sleeping locks and so cannot
be acquired in atomic context.
Fix this problem by using migrate_disable() to allow smp_processor_id() to
be reliably used without introducing atomic context. preempt_disable() is
then called after clocksource_verify_choose_cpus() but before the
clocksource measurement is being run to avoid introducing unexpected
latency.
📍 영향받는 시스템
Linux kernel with PREEMPT_RT, clocksource watchdog and verification functions, especially on real-time patched systems
⚔️ 공격 벡터
Kernel panic or system instability trigger through watchdog timer verification on PREEMPT_RT enabled systems
🛡️ 대응 방법
Update to patched Linux kernel version that includes migrate_disable() fix for clocksource verification
🔧 검증 코드
'Patched'가 출력되면 migrate_disable() 지원을 확인할 수 있습니다. PREEMPT_RT 커널 버전과 최신 패치 적용 여부를 확인하세요.
grep -q 'migrate_disable' /boot/config-$(uname -r) 2>/dev/null && echo 'Patched' || echo 'May be vulnerable'