CVE-2025-37747
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
05/11/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
perf: Fix hang while freeing sigtrap event<br />
<br />
Perf can hang while freeing a sigtrap event if a related deferred<br />
signal hadn&#39;t managed to be sent before the file got closed:<br />
<br />
perf_event_overflow()<br />
task_work_add(perf_pending_task)<br />
<br />
fput()<br />
task_work_add(____fput())<br />
<br />
task_work_run()<br />
____fput()<br />
perf_release()<br />
perf_event_release_kernel()<br />
_free_event()<br />
perf_pending_task_sync()<br />
task_work_cancel() -> FAILED<br />
rcuwait_wait_event()<br />
<br />
Once task_work_run() is running, the list of pending callbacks is<br />
removed from the task_struct and from this point on task_work_cancel()<br />
can&#39;t remove any pending and not yet started work items, hence the<br />
task_work_cancel() failure and the hang on rcuwait_wait_event().<br />
<br />
Task work could be changed to remove one work at a time, so a work<br />
running on the current task can always cancel a pending one, however<br />
the wait / wake design is still subject to inverted dependencies when<br />
remote targets are involved, as pictured by Oleg:<br />
<br />
T1 T2<br />
<br />
fd = perf_event_open(pid => T2->pid); fd = perf_event_open(pid => T1->pid);<br />
close(fd) close(fd)<br />
<br />
perf_event_overflow() perf_event_overflow()<br />
task_work_add(perf_pending_task) task_work_add(perf_pending_task)<br />
<br />
fput() fput()<br />
task_work_add(____fput()) task_work_add(____fput())<br />
<br />
task_work_run() task_work_run()<br />
____fput() ____fput()<br />
perf_release() perf_release()<br />
perf_event_release_kernel() perf_event_release_kernel()<br />
_free_event() _free_event()<br />
perf_pending_task_sync() perf_pending_task_sync()<br />
rcuwait_wait_event() rcuwait_wait_event()<br />
<br />
Therefore the only option left is to acquire the event reference count<br />
upon queueing the perf task work and release it from the task work, just<br />
like it was done before 3a5465418f5f ("perf: Fix event leak upon exec and file release")<br />
but without the leaks it fixed.<br />
<br />
Some adjustments are necessary to make it work:<br />
<br />
* A child event might dereference its parent upon freeing. Care must be<br />
taken to release the parent last.<br />
<br />
* Some places assuming the event doesn&#39;t have any reference held and<br />
therefore can be freed right away must instead put the reference and<br />
let the reference counting to its job.
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:*:*:*:*:*:*:*:* | 5.15.165 (including) | 5.16 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.1.103 (including) | 6.2 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.6.44 (including) | 6.7 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.10.3 (including) | 6.12.24 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.13 (including) | 6.13.12 (excluding) |
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.14 (including) | 6.14.3 (excluding) |
| cpe:2.3:o:linux:linux_kernel:6.15:rc1:*:*:*:*:*:* |
To consult the complete list of CPE names with products and versions, see this page



