🇰🇷 한글 설명
Linux 커널의 netpoll 구성 요소에서 메모리 할당 중 스핀락(spinlock)을 보유한 상태로 재귀적 잠금 시도가 발생하여 데드락이 발생하는 취약점입니다. 시스템 메모리가 부족할 때 메모리 할당 실패로 인한 OOM 경고 출력 과정에서 동일한 락을 다시 요청하게 되어 시스템이 멈출 수 있습니다.
💡 쉬운 설명
컴퓨터의 메모리가 부족할 때 시스템이 오류 메시지를 출력하려다, 이미 사용 중인 자원을 다시 붙잡으려고 시도하면서 시스템이 완전히 멈춰버리는 문제입니다. 이는 소프트웨어 내부의 논리적 충돌로 인해 발생합니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
netpoll: Fix deadlock in memory allocation under spinlock
Fix a AA deadlock in refill_skbs() where memory allocation while holding
skb_pool->lock can trigger a recursive lock acquisition attempt.
The deadlock scenario occurs when the system is under severe memory
pressure:
1. refill_skbs() acquires skb_pool->lock (spinlock)
2. alloc_skb() is called while holding the lock
3. Memory allocator fails and calls slab_out_of_memory()
4. This triggers printk() for the OOM warning
5. The console output path calls netpoll_send_udp()
6. netpoll_send_udp() attempts to acquire the same skb_pool->lock
7. Deadlock: the lock is already held by the same CPU
Call stack:
refill_skbs()
spin_lock_irqsave(&skb_pool->lock) <- lock acquired
__alloc_skb()
kmem_cache_alloc_node_noprof()
slab_out_of_memory()
printk()
console_flush_all()
netpoll_send_udp()
skb_dequeue()
spin_lock_irqsave(&skb_pool->lock) <- deadlock attempt
This bug was exposed by commit 248f6571fd4c51 ("netpoll: Optimize skb
refilling on critical path") which removed refill_skbs() from the
critical path (where nested printk was being deferred), letting nested
printk being called from inside refill_skbs()
Refactor refill_skbs() to never allocate memory while holding
the spinlock.
Another possible solution to fix this problem is protecting the
refill_skbs() from nested printks, basically calling
printk_deferred_{enter,exit}() in refill_skbs(), then, any nested
pr_warn() would be deferred.
I prefer this approach, given I _think_ it might be a good idea to move
the alloc_skb() from GFP_ATOMIC to GFP_KERNEL in the future, so, having
the alloc_skb() outside of the lock will be necessary step.
There is a possible TOCTOU issue when checking for the pool length, and
queueing the new allocated skb, but, this is not an issue, given that
an extra SKB in the pool is harmless and it will be eventually used.
📍 영향받는 시스템
Linux Kernel (netpoll 모듈을 사용하는 환경)
⚔️ 공격 벡터
직접적인 공격은 어려우나, 극심한 메모리 압박(Memory Pressure) 상황을 유도하여 시스템 중단을 일으킬 수 있음
🛡️ 대응 방법
커널 패치를 적용하여 메모리 할당 시 락을 해제하거나, printk 호출을 지연(deferred)시키는 방식으로 업데이트해야 함
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 해당 취약점이 해결된 패치 버전인지 확인합니다.