RE: [PATCH] mm/damon/core: dangling walk_control pointer in damos_walk() on inactive context

From: Raul Pazemecxas De Andrade

Date: Mon Feb 16 2026 - 11:27:11 EST


From 7d82f231f99949d041045789d3ed912ad7e25546 Mon Sep 17 00:00:00 2001
From: Raul Pazemecxas De Andrade <raul_pazemecxas@xxxxxxxxxxx>
Date: Mon, 16 Feb 2026 13:06:04 -0300
Subject: [PATCH] mm/damon/core: clear walk_control on inactive context in
 damos_walk()

damos_walk() sets ctx->walk_control to the caller-provided control
structure before checking whether the context is running. If the context
is inactive (damon_is_running() returns false), the function returns
-EINVAL without clearing ctx->walk_control. This leaves a dangling
pointer to a stack-allocated structure that will be freed when the
caller returns.

This is structurally identical to the bug fixed in commit f9132fbc2e83
("mm/damon/core: remove call_control in inactive contexts") for
damon_call(), which had the same pattern of linking a control object
and returning an error without unlinking it.

The dangling walk_control pointer can cause:
1. Use-after-free if the context is later started and kdamond
   dereferences ctx->walk_control (e.g., in damos_walk_cancel()
   which writes to control->canceled and calls complete())
2. Permanent -EBUSY from subsequent damos_walk() calls, since the
   stale pointer is non-NULL

Fix this by clearing ctx->walk_control under walk_control_lock before
returning -EINVAL, mirroring the fix pattern from f9132fbc2e83.

Reported-by: Raul Pazemecxas De Andrade <raul_pazemecxas@xxxxxxxxxxx>
Fixes: bf0eaba0ff9c ("mm/damon/core: implement damos_walk()")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Raul Pazemecxas De Andrade <raul_pazemecxas@xxxxxxxxxxx>
---
 mm/damon/core.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index 5e2724a4f..fb00879af 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1559,8 +1559,13 @@ int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control)
      }
      ctx->walk_control = control;
      mutex_unlock(&ctx->walk_control_lock);
-     if (!damon_is_running(ctx))
+     if (!damon_is_running(ctx)) {
+           mutex_lock(&ctx->walk_control_lock);
+           if (ctx->walk_control == control)
+                 ctx->walk_control = NULL;
+           mutex_unlock(&ctx->walk_control_lock);
            return -EINVAL;
+     }
      wait_for_completion(&control->completion);
      if (control->canceled)
            return -ECANCELED;
-- 
2.51.2
________________________________________
De: Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx>
Enviadas: Segunda-feira, 16 de Fevereiro de 2026 12:52
Para: Raul Pazemecxas De Andrade <raul_pazemecxas@xxxxxxxxxxx>
Cc: sj@xxxxxxxxxx <sj@xxxxxxxxxx>; security@xxxxxxxxxx <security@xxxxxxxxxx>; damon@xxxxxxxxxxxxxxx <damon@xxxxxxxxxxxxxxx>; linux-mm@xxxxxxxxx <linux-mm@xxxxxxxxx>; linux-kernel@xxxxxxxxxxxxxxx <linux-kernel@xxxxxxxxxxxxxxx>
Assunto: Re: [BUG] mm/damon/core: dangling walk_control pointer in damos_walk() on inactive context


On Mon, Feb 16, 2026 at 03:34:44PM +0000, Raul Pazemecxas De Andrade wrote:

> Root cause

> ----------

>

> Commit bf0eaba0ff9c ("mm/damon/core: implement damos_walk()")

> introduced this function without cleanup on the -EINVAL error path.

>

> The sibling function damon_call() had the exact same bug and was

> fixed in f9132fbc2e83 by adding damon_call_handle_inactive_ctx()

> which removes the control object when the context is inactive.

> damos_walk() has no equivalent cleanup.



Can you submit a patch to resolve this to get credit for fixing the bug?



thanks,



greg k-h