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&amp;#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() -&gt; 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&amp;#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 =&gt; T2-&gt;pid); fd = perf_event_open(pid =&gt; T1-&gt;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&amp;#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.

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:*:*:*:*:*:*