CVE-2025-37821
Severity CVSS v4.0:
Pending analysis
Type:
CWE-476
NULL Pointer Dereference
Publication date:
08/05/2025
Last modified:
12/11/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
sched/eevdf: Fix se->slice being set to U64_MAX and resulting crash<br />
<br />
There is a code path in dequeue_entities() that can set the slice of a<br />
sched_entity to U64_MAX, which sometimes results in a crash.<br />
<br />
The offending case is when dequeue_entities() is called to dequeue a<br />
delayed group entity, and then the entity&#39;s parent&#39;s dequeue is delayed.<br />
In that case:<br />
<br />
1. In the if (entity_is_task(se)) else block at the beginning of<br />
dequeue_entities(), slice is set to<br />
cfs_rq_min_slice(group_cfs_rq(se)). If the entity was delayed, then<br />
it has no queued tasks, so cfs_rq_min_slice() returns U64_MAX.<br />
2. The first for_each_sched_entity() loop dequeues the entity.<br />
3. If the entity was its parent&#39;s only child, then the next iteration<br />
tries to dequeue the parent.<br />
4. If the parent&#39;s dequeue needs to be delayed, then it breaks from the<br />
first for_each_sched_entity() loop _without updating slice_.<br />
5. The second for_each_sched_entity() loop sets the parent&#39;s ->slice to<br />
the saved slice, which is still U64_MAX.<br />
<br />
This throws off subsequent calculations with potentially catastrophic<br />
results. A manifestation we saw in production was:<br />
<br />
6. In update_entity_lag(), se->slice is used to calculate limit, which<br />
ends up as a huge negative number.<br />
7. limit is used in se->vlag = clamp(vlag, -limit, limit). Because limit<br />
is negative, vlag > limit, so se->vlag is set to the same huge<br />
negative number.<br />
8. In place_entity(), se->vlag is scaled, which overflows and results in<br />
another huge (positive or negative) number.<br />
9. The adjusted lag is subtracted from se->vruntime, which increases or<br />
decreases se->vruntime by a huge number.<br />
10. pick_eevdf() calls entity_eligible()/vruntime_eligible(), which<br />
incorrectly returns false because the vruntime is so far from the<br />
other vruntimes on the queue, causing the<br />
(vruntime - cfs_rq->min_vruntime) * load calulation to overflow.<br />
11. Nothing appears to be eligible, so pick_eevdf() returns NULL.<br />
12. pick_next_entity() tries to dereference the return value of<br />
pick_eevdf() and crashes.<br />
<br />
Dumping the cfs_rq states from the core dumps with drgn showed tell-tale<br />
huge vruntime ranges and bogus vlag values, and I also traced se->slice<br />
being set to U64_MAX on live systems (which was usually "benign" since<br />
the rest of the runqueue needed to be in a particular state to crash).<br />
<br />
Fix it in dequeue_entities() by always setting slice from the first<br />
non-empty cfs_rq.
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
Vulnerable products and versions
| CPE | From | Up to |
|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.12 (including) | 6.12.29 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.13 (including) | 6.14.5 (excluding) |
| cpe:2.3:o:linux:linux_kernel:6.15:rc1:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.15:rc2:*:*:*:*:*:* | ||
| cpe:2.3:o:linux:linux_kernel:6.15:rc3:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page



