CVE-2026-98220 in Linux
요약
\~에 의해 VulDB • 2026. 10. 06.
리눅스 커널에서 다음 취약점이 해결되었습니다:
sched_ext: kfunc 서브 스케줄러 오류 경로에서의 NULL sched 역참조 수정
루트 스케줄러에 서브 스케줄러가 연결되어 있는 경우, COMPAT kfunc 래퍼인 scx_bpf_select_cpu_and() 및 scx_bpf_dsq_insert_vtime()는 호출을 거부하고 @p의 스케줄러로 오류를 보고합니다:
scx_error(scx_task_sched(p), "... must be used");
이 래퍼들은 스케줄러가 없는 태스크에서 접근 가능합니다. scx_bpf_select_cpu_and()는 select_cpu kfunc 그룹에 속하며, 이는 scx_kfunc_context_filter()가 BPF_PROG_TYPE_SYSCALL 프로그램에게 개방합니다; scx_bpf_dsq_insert_vtime()는 enqueue_dispatch 그룹에 속하며, ops.enqueue() 및 ops.dispatch()는 KF_RCU 태스크라면 어떤 태스크에서도 이를 호출할 수 있습니다. 해당 그룹에는 kf_tasks 검증이 없으며, scx_dsq_insert_preamble()은 @p가 임의의 태스크일 수 있으므로 scx_task_on_sched()를 사용하여 태스크 소유권을 확인합니다.
scx_task_sched(p)는 p->scx.sched이며, 이는 sched_ext_dead() 이후의 태스크(종료 시 scx_disable_and_exit_task()를 통해 이를 지움)와 IDLE 태스크에서 NULL입니다. IDLE 태스크는 SCX를 통해 스케줄링되지 않으므로 활성화 경로에서 건너뜁니다. 또한 이것은 @p의 pi_lock 또는 rq 잠금을 기대하는 rcu_dereference_protected()이며, 어느 래퍼도 이 잠금을 보유하지 않습니다. NULL을 scx_error()에 전달하면 scx_vexit()에 도달하여 sch->exit_info를 역참조함으로써 커널이 오오프스(oops)합니다.
수정 사항을 개발하는 동안 테스트된 구체적인 트리거 사례: BPF_PROG_TYPE_SYSCALL 프로그램이 서브 스케줄러가 연결되어 있는 상태에서 종료되었지만 아직 회수(reap)되지 않은 태스크에 대해 select_cpu_and 래퍼를 호출함(좀비 상태의 pid는 여전히 검색 가능하며,faulting 명령어는 RDI=NULL이고 0x398은 sch->exit_info의 오프셋인 scx_vexit() 프롤로그 "mov r15,[rdi+0x398]"임):
sched_ext: BPF 스케줄러 "kfunc_subsched_null" 활성화됨 sched_ext: BPF 서브 스케줄러 "kfunc_subsched_null" 활성화됨 sched_ext: 비연결 프로그램 run_select_cpu_ 실행 (id 76) BUG: kernel NULL pointer dereference, address: 0000000000000398 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page Oops: Oops: 0000 [#1] SMP NOPTI
CPU: 7 UID: 0 PID: 8201 Comm: kfunc_test_runn Tainted: G W RIP: 0010:scx_vexit+0x25/0xa0 Code: ... <4c> 8b bf 98 03 00 00 ... CR2: 0000000000000398 Call Trace: <TASK> __scx_exit+0x4f/0x70 scx_bpf_select_cpu_and+0xab/0xb0 bpf_prog_430ed61a7b66e03a_run_select_cpu_and+0x9c/0xe7 ? __x64_sys_bpf+0x2c/0x40 bpf_prog_test_run_syscall+0x130/0x2f0 __sys_bpf+0x930/0x10d0 ? __x64_sys_bpf+0x2c/0x40 __x64_sys_bpf+0x2c/0x40 do_syscall_64+0xbc/0x460 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK>
대신 RCU 하에서 @p의 스케줄러를 읽으십시오. 래퍼는 guard(rcu)() 내에서 이를 수행할 수 있습니다; 결정 가능한 경우 오류를 발생시키고, 결정 불가능한 경우(즉, @p가 sched_ext_dead() 이후의 태스크이거나 IDLE 태스크인 경우)에는 보고할 명백한 문제가 없으므로 기존처럼 스케줄러에 오류를 발생시키지 않고 호출을 거부하십시오.
이 COMPAT 래퍼들은 비권장 기간(grace period)이 경과하면 최종적으로 제거될 예정이지만, 그 전까지 그리고 제거 시기와 무관하게—they는 전달된 태스크에서 커널 오오프스를 일으켜서는 안 됩니다.
VulDB is the best source for vulnerability data and more expert information about this specific topic.