🇰🇷 한글 설명
Linux 커널에서 인터럽트가 비활성화된 상태에서 스케줄링이 발생하는 문제가 수정되었습니다. kexec jump 중 syscore 콜백이 태스크를 깨우면서 NEED_RESCHED 플래그가 설정되고, 이후 cond_resched()가 인터럽트가 꺼진 컨텍스트에서 스케줄러를 호출하여 경고가 발생했습니다. 이는 PREEMPT_NONE 및 PREEMPT_VOLUNTARY 모델에 영향을 주며, cond_resched()에 인터럽트 상태 검사를 추가하여 해결했습니다.
💡 쉬운 설명
컴퓨터가 재부팅 준비 중 특정 작업이 잘못된 시점에 작업 전환을 일으켜 경고가 발생하던 문제입니다. 이번 수정으로 인터럽트가 꺼진 동안에는 작업 전환이 일어나지 않도록 막아 안정성이 높아졌습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
sched/core: Prevent rescheduling when interrupts are disabled
David reported a warning observed while loop testing kexec jump:
Interrupts enabled after irqrouter_resume+0x0/0x50
WARNING: CPU: 0 PID: 560 at drivers/base/syscore.c:103 syscore_resume+0x18a/0x220
kernel_kexec+0xf6/0x180
__do_sys_reboot+0x206/0x250
do_syscall_64+0x95/0x180
The corresponding interrupt flag trace:
hardirqs last enabled at (15573): [<ffffffffa8281b8e>] __up_console_sem+0x7e/0x90
hardirqs last disabled at (15580): [<ffffffffa8281b73>] __up_console_sem+0x63/0x90
That means __up_console_sem() was invoked with interrupts enabled. Further
instrumentation revealed that in the interrupt disabled section of kexec
jump one of the syscore_suspend() callbacks woke up a task, which set the
NEED_RESCHED flag. A later callback in the resume path invoked
cond_resched() which in turn led to the invocation of the scheduler:
__cond_resched+0x21/0x60
down_timeout+0x18/0x60
acpi_os_wait_semaphore+0x4c/0x80
acpi_ut_acquire_mutex+0x3d/0x100
acpi_ns_get_node+0x27/0x60
acpi_ns_evaluate+0x1cb/0x2d0
acpi_rs_set_srs_method_data+0x156/0x190
acpi_pci_link_set+0x11c/0x290
irqrouter_resume+0x54/0x60
syscore_resume+0x6a/0x200
kernel_kexec+0x145/0x1c0
__do_sys_reboot+0xeb/0x240
do_syscall_64+0x95/0x180
This is a long standing problem, which probably got more visible with
the recent printk changes. Something does a task wakeup and the
scheduler sets the NEED_RESCHED flag. cond_resched() sees it set and
invokes schedule() from a completely bogus context. The scheduler
enables interrupts after context switching, which causes the above
warning at the end.
Quite some of the code paths in syscore_suspend()/resume() can result in
triggering a wakeup with the exactly same consequences. They might not
have done so yet, but as they share a lot of code with normal operations
it's just a question of time.
The problem only affects the PREEMPT_NONE and PREEMPT_VOLUNTARY scheduling
models. Full preemption is not affected as cond_resched() is disabled and
the preemption check preemptible() takes the interrupt disabled flag into
account.
Cure the problem by adding a corresponding check into cond_resched().
📍 영향받는 시스템
수정 이전 Linux 커널(PREEMPT_NONE 또는 PREEMPT_VOLUNTARY 스케줄링 모델을 사용하는 시스템, kexec jump 사용 환경)
⚔️ 공격 벡터
원격 공격 경로는 확인되지 않았으며, 커널 내부 스케줄링 타이밍 문제로 경고 출력 및 불안정 동작을 유발하는 수준입니다.
🛡️ 대응 방법
배포판의 보안 업데이트로 최신 Linux 커널을 설치하고 재부팅합니다.
🔧 검증 코드
출력된 커널 버전이 배포판이 제공하는 CVE-2024-58090 수정 패치 포함 버전 이상인지 배포판 보안 공지(예: Ubuntu USN, Red Hat RHSA)와 비교하여 확인합니다.