CVE-2026-43439
Publication date:
08/05/2026
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
cgroup: fix race between task migration and iteration<br />
<br />
When a task is migrated out of a css_set, cgroup_migrate_add_task()<br />
first moves it from cset->tasks to cset->mg_tasks via:<br />
<br />
list_move_tail(&task->cg_list, &cset->mg_tasks);<br />
<br />
If a css_task_iter currently has it->task_pos pointing to this task,<br />
css_set_move_task() calls css_task_iter_skip() to keep the iterator<br />
valid. However, since the task has already been moved to ->mg_tasks,<br />
the iterator is advanced relative to the mg_tasks list instead of the<br />
original tasks list. As a result, remaining tasks on cset->tasks, as<br />
well as tasks queued on cset->mg_tasks, can be skipped by iteration.<br />
<br />
Fix this by calling css_set_skip_task_iters() before unlinking<br />
task->cg_list from cset->tasks. This advances all active iterators to<br />
the next task on cset->tasks, so iteration continues correctly even<br />
when a task is concurrently being migrated.<br />
<br />
This race is hard to hit in practice without instrumentation, but it<br />
can be reproduced by artificially slowing down cgroup_procs_show().<br />
For example, on an Android device a temporary<br />
/sys/kernel/cgroup/cgroup_test knob can be added to inject a delay<br />
into cgroup_procs_show(), and then:<br />
<br />
1) Spawn three long-running tasks (PIDs 101, 102, 103).<br />
2) Create a test cgroup and move the tasks into it.<br />
3) Enable a large delay via /sys/kernel/cgroup/cgroup_test.<br />
4) In one shell, read cgroup.procs from the test cgroup.<br />
5) Within the delay window, in another shell migrate PID 102 by<br />
writing it to a different cgroup.procs file.<br />
<br />
Under this setup, cgroup.procs can intermittently show only PID 101<br />
while skipping PID 103. Once the migration completes, reading the<br />
file again shows all tasks as expected.<br />
<br />
Note that this change does not allow removing the existing<br />
css_set_skip_task_iters() call in css_set_move_task(). The new call<br />
in cgroup_migrate_add_task() only handles iterators that are racing<br />
with migration while the task is still on cset->tasks. Iterators may<br />
also start after the task has been moved to cset->mg_tasks. If we<br />
dropped css_set_skip_task_iters() from css_set_move_task(), such<br />
iterators could keep task_pos pointing to a migrating task, causing<br />
css_task_iter_advance() to malfunction on the destination css_set,<br />
up to and including crashes or infinite loops.<br />
<br />
The race window between migration and iteration is very small, and<br />
css_task_iter is not on a hot path. In the worst case, when an<br />
iterator is positioned on the first thread of the migrating process,<br />
cgroup_migrate_add_task() may have to skip multiple tasks via<br />
css_set_skip_task_iters(). However, this only happens when migration<br />
and iteration actually race, so the performance impact is negligible<br />
compared to the correctness fix provided here.
Severity CVSS v4.0: Pending analysis
Last modification:
12/05/2026