CVE-2024-58090: Add .vulnerable file
The root cause commit that introduced the bug is commit
9414232fa0cc28e2f51b8c76d260f2748f7953fc by Ingo Molnar on December 29,
2006.
Technical Details:
1. What the commit did: It removed the __resched_legal() function that
checked if preempt_count() \!= 0, replacing it with a check that only
looks at the PREEMPT_ACTIVE bit.
2. The bug introduced: After this commit, cond_resched() would no
longer detect when interrupts are disabled (via local_irq_disable()
or being in interrupt context), because it only checks the
PREEMPT_ACTIVE bit instead of the full preempt_count value.
3. Why this matters: When interrupts are disabled, the HARDIRQ_MASK
bits in preempt_count are set, but the new code ignores these bits.
This allows cond_resched() to proceed and call schedule() even when
interrupts are disabled, which eventually enables interrupts in an
invalid context.
4. The chain of events:
- cond_resched() is called with interrupts disabled
- It only checks \!(preempt_count() & PREEMPT_ACTIVE) which passes
- It calls __cond_resched() → schedule()
- schedule() eventually enables interrupts, violating the invariant
5. Ingo's reasoning was flawed: While he claimed __resched_legal() was
"conceptually broken" because it could "mask buggy cond_resched()
calls", his change actually introduced a worse bug by allowing
cond_resched() to be called with interrupts disabled, which then
causes the scheduler to enable interrupts in an invalid context.
The fix in commit 82c387ef7568c0d96a918a5a78d9cad6256cfa15 (December
2024) correctly addresses this 18-year-old bug by adding back the check
for \!irqs_disabled().
Signed-off-by: Sasha Levin <sashal@kernel.org>
1 file changed