Description
In the Linux kernel, the following vulnerability has been resolved:

mm/damon/core: fix damon_call() vs kdamond_fn() exit race

Patch series "mm/damon/core: fix damon_call()/damos_walk() vs kdmond exit
race".

damon_call() and damos_walk() can leak memory and/or deadlock when they
race with kdamond terminations. Fix those.


This patch (of 2);

When kdamond_fn() main loop is finished, the function cancels all
remaining damon_call() requests and unset the damon_ctx->kdamond so that
API callers and API functions themselves can know the context is
terminated. damon_call() adds the caller's request to the queue first.
After that, it shows if the kdamond of the damon_ctx is still running
(damon_ctx->kdamond is set). Only if the kdamond is running, damon_call()
starts waiting for the kdamond's handling of the newly added request.

The damon_call() requests registration and damon_ctx->kdamond unset are
protected by different mutexes, though. Hence, damon_call() could race
with damon_ctx->kdamond unset, and result in deadlocks.

For example, let's suppose kdamond successfully finished the damon_call()
requests cancelling. Right after that, damon_call() is called for the
context. It registers the new request, and shows the context is still
running, because damon_ctx->kdamond unset is not yet done. Hence the
damon_call() caller starts waiting for the handling of the request.
However, the kdamond is already on the termination steps, so it never
handles the new request. As a result, the damon_call() caller threads
infinitely waits.

Fix this by introducing another damon_ctx field, namely
call_controls_obsolete. It is protected by the
damon_ctx->call_controls_lock, which protects damon_call() requests
registration. Initialize (unset) it in kdamond_fn() before letting
damon_start() returns and set it just before the cancelling of remaining
damon_call() requests is executed. damon_call() reads the obsolete field
under the lock and avoids adding a new request.

After this change, only requests that are guaranteed to be handled or
cancelled are registered. Hence the after-registration DAMON context
termination check is no longer needed. Remove it together.

Note that the deadlock will not happen when damon_call() is called for
repeat mode request. In tis case, damon_call() returns instead of waiting
for the handling when the request registration succeeds and it shows the
kdamond is running. However, if the request also has dealloc_on_cancel,
the request memory would be leaked.

The issue is found by sashiko [1].
Published: 2026-05-27
Score: n/a
EPSS: n/a
KEV: No
Impact: n/a
Action: n/a
AI Analysis

Impact

The vulnerability is a race condition in the Linux kernel damon subsystem. When damon_call() and damos_walk() run concurrently with kdamond termination, a mismatch between the damon_ctx->kdamond flag and its unset operation can cause damon_call() to wait forever or ignore cancellation of pending requests. This leads to deadlock or memory leakage, potentially exhausting system resources and causing instability.

Affected Systems

The affected product is the Linux kernel. Any kernel version prior to the patch that implements the fix is vulnerable. There is no specific version range provided, so all current LTS and mainstream kernels are at risk until the patch is applied.

Risk and Exploitability

Since the issue is an internal race, it does not rely on external input and is not listed in KEV, and the EPSS is not available. The severity is not quantified, but the potential for service interruption makes the risk notable if an attacker can execute privileged code that triggers damon_call during a kdamond teardown. The patch prevents deadlock and memory leaks by protecting the obsolete field and removing the redundant runtime check.

Generated by OpenCVE AI on May 27, 2026 at 20:27 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Upgrade the kernel to a version that includes the damon_call and damos_walk race condition fix (commits 2691332, 55da816, e6a053a6).
  • If immediate kernel upgrade is not feasible, identify and refactor any code that calls damon_call() during system shutdown or kdamond termination to prevent new requests from being queued.
  • As a temporary mitigation, pause or disable any composite device management operations that invoke damon_call() during shutdown by modifying system scripts or services to postpone these operations until after kdamond finishes.

Generated by OpenCVE AI on May 27, 2026 at 20:27 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Wed, 27 May 2026 14:15:00 +0000

Type Values Removed Values Added
Description In the Linux kernel, the following vulnerability has been resolved: mm/damon/core: fix damon_call() vs kdamond_fn() exit race Patch series "mm/damon/core: fix damon_call()/damos_walk() vs kdmond exit race". damon_call() and damos_walk() can leak memory and/or deadlock when they race with kdamond terminations. Fix those. This patch (of 2); When kdamond_fn() main loop is finished, the function cancels all remaining damon_call() requests and unset the damon_ctx->kdamond so that API callers and API functions themselves can know the context is terminated. damon_call() adds the caller's request to the queue first. After that, it shows if the kdamond of the damon_ctx is still running (damon_ctx->kdamond is set). Only if the kdamond is running, damon_call() starts waiting for the kdamond's handling of the newly added request. The damon_call() requests registration and damon_ctx->kdamond unset are protected by different mutexes, though. Hence, damon_call() could race with damon_ctx->kdamond unset, and result in deadlocks. For example, let's suppose kdamond successfully finished the damon_call() requests cancelling. Right after that, damon_call() is called for the context. It registers the new request, and shows the context is still running, because damon_ctx->kdamond unset is not yet done. Hence the damon_call() caller starts waiting for the handling of the request. However, the kdamond is already on the termination steps, so it never handles the new request. As a result, the damon_call() caller threads infinitely waits. Fix this by introducing another damon_ctx field, namely call_controls_obsolete. It is protected by the damon_ctx->call_controls_lock, which protects damon_call() requests registration. Initialize (unset) it in kdamond_fn() before letting damon_start() returns and set it just before the cancelling of remaining damon_call() requests is executed. damon_call() reads the obsolete field under the lock and avoids adding a new request. After this change, only requests that are guaranteed to be handled or cancelled are registered. Hence the after-registration DAMON context termination check is no longer needed. Remove it together. Note that the deadlock will not happen when damon_call() is called for repeat mode request. In tis case, damon_call() returns instead of waiting for the handling when the request registration succeeds and it shows the kdamond is running. However, if the request also has dealloc_on_cancel, the request memory would be leaked. The issue is found by sashiko [1].
Title mm/damon/core: fix damon_call() vs kdamond_fn() exit race
First Time appeared Linux
Linux linux Kernel
CPEs cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*
Vendors & Products Linux
Linux linux Kernel
References

Subscriptions

Linux Linux Kernel
cve-icon MITRE

Status: PUBLISHED

Assigner: Linux

Published:

Updated: 2026-05-27T12:56:31.784Z

Reserved: 2026-05-13T15:03:33.093Z

Link: CVE-2026-46025

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Awaiting Analysis

Published: 2026-05-27T14:17:21.013

Modified: 2026-05-27T14:48:03.013

Link: CVE-2026-46025

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-05-27T20:30:40Z

Weaknesses

No weakness.