🇰🇷 한글 설명
Linux 커널의 gpio-keys 드라이버에서 PREEMPT_RT 활성화 시, gpio_keys_irq_timer() 콜백이 하드 IRQ 컨텍스트에서 실행되며 input_event()가 rt_spin_lock을 획득하려다 '잠자기 금지 컨텍스트에서의 sleep' 버그가 발생합니다. 수정으로 hrtimer를 하드 IRQ 컨텍스트 대신 일반 컨텍스트에서 실행되도록 변경했습니다.
💡 쉬운 설명
실시간(PREEMPT_RT) 리눅스 커널에서 GPIO 버튼 입력을 처리하는 부분이 잘못된 시점에 대기 상태에 들어가 시스템이 불안정해질 수 있는 문제입니다. 이 결함은 커널 패치로 수정되었습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
Input: gpio-keys - fix a sleep while atomic with PREEMPT_RT
When enabling PREEMPT_RT, the gpio_keys_irq_timer() callback runs in
hard irq context, but the input_event() takes a spin_lock, which isn't
allowed there as it is converted to a rt_spin_lock().
[ 4054.289999] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
[ 4054.290028] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/0
...
[ 4054.290195] __might_resched+0x13c/0x1f4
[ 4054.290209] rt_spin_lock+0x54/0x11c
[ 4054.290219] input_event+0x48/0x80
[ 4054.290230] gpio_keys_irq_timer+0x4c/0x78
[ 4054.290243] __hrtimer_run_queues+0x1a4/0x438
[ 4054.290257] hrtimer_interrupt+0xe4/0x240
[ 4054.290269] arch_timer_handler_phys+0x2c/0x44
[ 4054.290283] handle_percpu_devid_irq+0x8c/0x14c
[ 4054.290297] handle_irq_desc+0x40/0x58
[ 4054.290307] generic_handle_domain_irq+0x1c/0x28
[ 4054.290316] gic_handle_irq+0x44/0xcc
Considering the gpio_keys_irq_isr() can run in any context, e.g. it can
be threaded, it seems there's no point in requesting the timer isr to
run in hard irq context.
Relax the hrtimer not to use the hard context.
📍 영향받는 시스템
PREEMPT_RT 패치가 적용된 Linux 커널 및 gpio-keys 드라이버를 사용하는 임베디드/실시간 시스템
⚔️ 공격 벡터
직접적인 원격 공격 경로는 명확하지 않으며, 주로 시스템 안정성(커널 패닉/버그 경고)에 영향을 주는 결함입니다.
🛡️ 대응 방법
해당 수정이 포함된 최신 Linux 커널 버전으로 업데이트하거나 배포판의 보안 업데이트를 적용하세요.
🔧 검증 코드
출력된 커널 버전을 배포판 보안 공지와 비교하고, CONFIG_PREEMPT_RT=y가 나오면 RT 커널이므로 패치 적용 여부를 우선 확인해야 하며, 설정이 없으면 이 취약점의 영향을 받지 않을 가능성이 높습니다.
uname -r && grep -E 'PREEMPT_RT|CONFIG_PREEMPT_RT' /boot/config-$(uname -r) 2>/dev/null