🇰🇷 한글 설명
Linux kernel의 네트워크 모듈에서 스레드된 busypoll 활성화 시 RCU(Read-Copy-Update) 태스크 grace period가 교착 상태에 빠지는 버그입니다. napi_threaded_poll_loop의 반복 횟수가 적어서 last_qs 타임스탬프가 계속 리셋되어 RCU 쿼리스센트 상태가 보고되지 않습니다. 패치는 last_qs를 외부 루프에서 관리하도록 변경하여 문제를 해결합니다.
💡 쉬운 설명
Linux 커널의 네트워크 최적화 기능에서 시스템 모니터링이 무한히 대기하는 버그입니다. NIC 드라이버에서 특정 기능을 활성화하면 시스템이 응답 불가 상태에 빠질 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net: Fix rcu_tasks stall in threaded busypoll
I was debugging a NIC driver when I noticed that when I enable
threaded busypoll, bpftrace hangs when starting up. dmesg showed:
rcu_tasks_wait_gp: rcu_tasks grace period number 85 (since boot) is 10658 jiffies old.
rcu_tasks_wait_gp: rcu_tasks grace period number 85 (since boot) is 40793 jiffies old.
rcu_tasks_wait_gp: rcu_tasks grace period number 85 (since boot) is 131273 jiffies old.
rcu_tasks_wait_gp: rcu_tasks grace period number 85 (since boot) is 402058 jiffies old.
INFO: rcu_tasks detected stalls on tasks:
00000000769f52cd: .N nvcsw: 2/2 holdout: 1 idle_cpu: -1/64
task:napi/eth2-8265 state:R running task stack:0 pid:48300 tgid:48300 ppid:2 task_flags:0x208040 flags:0x00004000
Call Trace:
<TASK>
? napi_threaded_poll_loop+0x27c/0x2c0
? __pfx_napi_threaded_poll+0x10/0x10
? napi_threaded_poll+0x26/0x80
? kthread+0xfa/0x240
? __pfx_kthread+0x10/0x10
? ret_from_fork+0x31/0x50
? __pfx_kthread+0x10/0x10
? ret_from_fork_asm+0x1a/0x30
</TASK>
The cause is that in threaded busypoll, the main loop is in
napi_threaded_poll rather than napi_threaded_poll_loop, where the
latter rarely iterates more than once within its loop. For
rcu_softirq_qs_periodic inside napi_threaded_poll_loop to report its
qs state, the last_qs must be 100ms behind, and this can't happen
because napi_threaded_poll_loop rarely iterates in threaded busypoll,
and each time napi_threaded_poll_loop is called last_qs is reset to
latest jiffies.
This patch changes so that in threaded busypoll, last_qs is saved
in the outer napi_threaded_poll, and whether busy_poll_last_qs
is NULL indicates whether napi_threaded_poll_loop is called for
busypoll. This way last_qs would not reset to latest jiffies on
each invocation of napi_threaded_poll_loop.
📍 영향받는 시스템
Linux kernel 5.14+ (NAPI threaded busypoll 지원 버전), 특히 고성능 NIC 드라이버 활용 시스템
⚔️ 공격 벡터
로컬 권한자가 네트워크 인터페이스에서 threaded busypoll을 활성화하거나 특정 NIC 드라이버 설정으로 트리거 가능
🛡️ 대응 방법
Linux kernel을 최신 버전으로 업데이트하여 rcu_tasks 스케줄링 로직 패치 적용
🔧 검증 코드
kernel 버전이 5.14 이상이면 패치 적용 여부를 /boot/config 파일에서 CONFIG_NAPI_THREADED_POLL 설정 확인하거나 커널 changelog에서 rcu_tasks 관련 fix 확인
uname -r | grep -E '5\.(14|[2-9][0-9]|[1-9][0-9]{2,})' && echo 'Check kernel changelog or CONFIG_NAPI_THREADED_POLL'