🇰🇷 한글 설명
Linux 커널의 BPF 구성 요소에서 bpf_timer_init() 호출 시 메모리 제어 그룹(memcg) 계정 처리 과정 중 락(lock)을 중복 획득하는 취약점이 발견되었습니다. 이로 인해 rq_lock과 같은 핵심 락이 중복 획득되어 시스템이 멈추는 하드락업(hardlockup) 현상이 발생할 수 있습니다.
💡 쉬운 설명
컴퓨터의 핵심 자원을 관리하는 규칙이 충돌하여 시스템이 완전히 멈춰버릴 수 있는 문제입니다. 특정 작업이 메모리를 요청할 때 시스템 내부의 잠금 장치가 꼬이면서 발생합니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
bpf: Tell memcg to use allow_spinning=false path in bpf_timer_init()
Currently, calling bpf_map_kmalloc_node() from __bpf_async_init() can
cause various locking issues; see the following stack trace (edited for
style) as one example:
...
[10.011566] do_raw_spin_lock.cold
[10.011570] try_to_wake_up (5) double-acquiring the same
[10.011575] kick_pool rq_lock, causing a hardlockup
[10.011579] __queue_work
[10.011582] queue_work_on
[10.011585] kernfs_notify
[10.011589] cgroup_file_notify
[10.011593] try_charge_memcg (4) memcg accounting raises an
[10.011597] obj_cgroup_charge_pages MEMCG_MAX event
[10.011599] obj_cgroup_charge_account
[10.011600] __memcg_slab_post_alloc_hook
[10.011603] __kmalloc_node_noprof
...
[10.011611] bpf_map_kmalloc_node
[10.011612] __bpf_async_init
[10.011615] bpf_timer_init (3) BPF calls bpf_timer_init()
[10.011617] bpf_prog_xxxxxxxxxxxxxxxx_fcg_runnable
[10.011619] bpf__sched_ext_ops_runnable
[10.011620] enqueue_task_scx (2) BPF runs with rq_lock held
[10.011622] enqueue_task
[10.011626] ttwu_do_activate
[10.011629] sched_ttwu_pending (1) grabs rq_lock
...
The above was reproduced on bpf-next (b338cf849ec8) by modifying
./tools/sched_ext/scx_flatcg.bpf.c to call bpf_timer_init() during
ops.runnable(), and hacking the memcg accounting code a bit to make
a bpf_timer_init() call more likely to raise an MEMCG_MAX event.
We have also run into other similar variants (both internally and on
bpf-next), including double-acquiring cgroup_file_kn_lock, the same
worker_pool::lock, etc.
As suggested by Shakeel, fix this by using __GFP_HIGH instead of
GFP_ATOMIC in __bpf_async_init(), so that e.g. if try_charge_memcg()
raises an MEMCG_MAX event, we call __memcg_memory_event() with
@allow_spinning=false and avoid calling cgroup_file_notify() there.
Depends on mm patch
"memcg: skip cgroup_file_notify if spinning is not allowed":
https://lore.kernel.org/bpf/
[email protected]/
v0 approach s/bpf_map_kmalloc_node/bpf_mem_alloc/
https://lore.kernel.org/bpf/
[email protected]/
v1 approach:
https://lore.kernel.org/bpf/
[email protected]/
📍 영향받는 시스템
Linux kernel (특히 bpf-next 및 관련 BPF 기능이 활성화된 커널)
⚔️ 공격 벡터
특정 BPF 프로그램을 실행하여 메모리 제어 그룹의 한계치(MEMCG_MAX)를 유도함으로써 시스템 락업 유발
🛡️ 대응 방법
커널 패치를 통해 __bpf_async_init()에서 GFP_ATOMIC 대신 __GFP_HIGH를 사용하도록 업데이트하여 락 충돌 방지
🔧 검증 코드
현재 실행 중인 커널 버전을 확인하여 해당 취약점이 해결된 최신 패치 버전인지 확인하십시오.