FAILED: patch "[PATCH] mm/damon/sysfs: fix use-after-free in state_show()" failed to apply to 6.16-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.16-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.16.y
git checkout FETCH_HEAD
git cherry-pick -x 3260a3f0828e06f5f13fac69fb1999a6d60d9cff
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025091318-salsa-tarantula-9209@gregkh' --subject-prefix 'PATCH 6.16.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3260a3f0828e06f5f13fac69fb1999a6d60d9cff Mon Sep 17 00:00:00 2001
From: Stanislav Fort <[email protected]>
Date: Fri, 5 Sep 2025 13:10:46 +0300
Subject: [PATCH] mm/damon/sysfs: fix use-after-free in state_show()
state_show() reads kdamond->damon_ctx without holding damon_sysfs_lock. This allows a use-after-free race:
CPU 0 CPU 1
----- -----
state_show() damon_sysfs_turn_damon_on()
ctx = kdamond->damon_ctx; mutex_lock(&damon_sysfs_lock);
damon_destroy_ctx(kdamond->damon_ctx);
kdamond->damon_ctx = NULL;
mutex_unlock(&damon_sysfs_lock);damon_is_running(ctx); /* ctx is freed */mutex_lock(&ctx->kdamond_lock); /* UAF */
(The race can also occur with damon_sysfs_kdamonds_rm_dirs() and damon_sysfs_kdamond_release(), which free or replace the context under damon_sysfs_lock.)
Fix by taking damon_sysfs_lock before dereferencing the context, mirroring the locking used in pid_show().
The bug has existed since state_show() first accessed kdamond->damon_ctx.
mm/damon/sysfs.c +9 -5
@@ -1260,14 +1260,18 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, {struct damon_sysfs_kdamond *kdamond =container_of (kobj, struct damon_sysfs_kdamond, kobj); -struct damon_ctx *ctx = kdamond->damon_ctx; -bool running; +struct damon_ctx *ctx; +bool running = false; -if (!ctx) - running = false; -else +if (!mutex_trylock (&damon_sysfs_lock)) +return -EBUSY ; + + ctx = kdamond->damon_ctx; +if (ctx) running =damon_is_running (ctx); +mutex_unlock (&damon_sysfs_lock); +return sysfs_emit (buf,"%s\n" , running ? damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON ] : damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_OFF ]);
SeongJae Park
maintainerPATCH 1/1 mm/damon/sysfs: fix use-after-free in state_show()
From: Stanislav Fort <[email protected]>
state_show() reads kdamond->damon_ctx without holding damon_sysfs_lock. This allows a use-after-free race:
CPU 0 CPU 1
----- -----
state_show() damon_sysfs_turn_damon_on()
ctx = kdamond->damon_ctx; mutex_lock(&damon_sysfs_lock);
damon_destroy_ctx(kdamond->damon_ctx);
kdamond->damon_ctx = NULL;
mutex_unlock(&damon_sysfs_lock);damon_is_running(ctx); /* ctx is freed */mutex_lock(&ctx->kdamond_lock); /* UAF */
(The race can also occur with damon_sysfs_kdamonds_rm_dirs() and damon_sysfs_kdamond_release(), which free or replace the context under damon_sysfs_lock.)
Fix by taking damon_sysfs_lock before dereferencing the context, mirroring the locking used in pid_show().
The bug has existed since state_show() first accessed kdamond->damon_ctx.
--- mm/damon/sysfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
mm/damon/sysfs.c +9 -5
@@ -1243,14 +1243,18 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, {struct damon_sysfs_kdamond *kdamond =container_of (kobj, struct damon_sysfs_kdamond, kobj); -struct damon_ctx *ctx = kdamond->damon_ctx; -bool running; +struct damon_ctx *ctx; +bool running = false; -if (!ctx) - running = false; -else +if (!mutex_trylock (&damon_sysfs_lock)) +return -EBUSY ; + + ctx = kdamond->damon_ctx; +if (ctx) running =damon_sysfs_ctx_running (ctx); +mutex_unlock (&damon_sysfs_lock); +return sysfs_emit (buf,"%s\n" , running ? damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON ] : damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_OFF ]);
Signature · 1 line
2.39.5
Sasha Levin
maintainerPATCH 1/2 mm/damon/sysfs: use DAMON core API damon_is_running()
In reply to [email protected]From: SeongJae Park <[email protected]>
[ Upstream commit d2b5be741a5045272b9d711908eab017632ac022 ]
DAMON core implements a static function to see if a given DAMON context is running. DAMON sysfs interface is implementing the same one on its own. Make the core function non-static and reuse it from the DAMON sysfs interface.
Stable-dep-of: 3260a3f0828e ("mm/damon/sysfs: fix use-after-free in state_show()")
--- include/linux/damon.h | 1 + mm/damon/core.c | 8 +++++++- mm/damon/sysfs.c | 14 ++------------ 3 files changed, 10 insertions(+), 13 deletions(-)
include/linux/damon.h +1 -0
@@ -934,6 +934,7 @@ static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrsint damon_start (struct damon_ctx **ctxs,int nr_ctxs,bool exclusive);int damon_stop (struct damon_ctx **ctxs,int nr_ctxs); +bool damon_is_running (struct damon_ctx *ctx);int damon_call (struct damon_ctx *ctx,struct damon_call_control *control);int damos_walk (struct damon_ctx *ctx,struct damos_walk_control *control);
mm/damon/core.c +7 -1
@@ -1340,7 +1340,13 @@ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs)return err; } -static bool damon_is_running (struct damon_ctx *ctx) +/** +* damon_is_running() - Returns if a given DAMON context is running. +* @ctx: The DAMON context to see if running. +* +* Return: true if @ctx is running, false otherwise. +*/ +bool damon_is_running (struct damon_ctx *ctx) {bool running;
mm/damon/sysfs.c +2 -12
@@ -1163,16 +1163,6 @@ static void damon_sysfs_kdamond_rm_dirs(struct damon_sysfs_kdamond *kdamond)kobject_put (&kdamond->contexts->kobj); } -static bool damon_sysfs_ctx_running (struct damon_ctx *ctx) -{ -bool running; - -mutex_lock (&ctx->kdamond_lock); - running = ctx->kdamond !=NULL ; -mutex_unlock (&ctx->kdamond_lock); -return running; -} -/* * enum damon_sysfs_cmd - Commands for a specific kdamond. */
@@ -1249,7 +1239,7 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,if (!ctx) running = false;else - running =damon_sysfs_ctx_running (ctx); + running =damon_is_running (ctx); return sysfs_emit(buf, "%s\n", running ? damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON] :
@@ -1403,7 +1393,7 @@ static inline bool damon_sysfs_kdamond_running( struct damon_sysfs_kdamond *kdamond) {return kdamond->damon_ctx && -damon_sysfs_ctx_running (kdamond->damon_ctx); +damon_is_running (kdamond->damon_ctx); } static int damon_sysfs_apply_inputs(struct damon_ctx *ctx,
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 2/2 mm/damon/sysfs: fix use-after-free in state_show()
From: Stanislav Fort <[email protected]>
[ Upstream commit 3260a3f0828e06f5f13fac69fb1999a6d60d9cff ]
state_show() reads kdamond->damon_ctx without holding damon_sysfs_lock. This allows a use-after-free race:
CPU 0 CPU 1
----- -----
state_show() damon_sysfs_turn_damon_on()
ctx = kdamond->damon_ctx; mutex_lock(&damon_sysfs_lock);
damon_destroy_ctx(kdamond->damon_ctx);
kdamond->damon_ctx = NULL;
mutex_unlock(&damon_sysfs_lock);damon_is_running(ctx); /* ctx is freed */mutex_lock(&ctx->kdamond_lock); /* UAF */
(The race can also occur with damon_sysfs_kdamonds_rm_dirs() and damon_sysfs_kdamond_release(), which free or replace the context under damon_sysfs_lock.)
Fix by taking damon_sysfs_lock before dereferencing the context, mirroring the locking used in pid_show().
The bug has existed since state_show() first accessed kdamond->damon_ctx.
--- mm/damon/sysfs.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
mm/damon/sysfs.c +9 -5
@@ -1233,14 +1233,18 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, {struct damon_sysfs_kdamond *kdamond =container_of (kobj, struct damon_sysfs_kdamond, kobj); -struct damon_ctx *ctx = kdamond->damon_ctx; -bool running; +struct damon_ctx *ctx; +bool running = false; -if (!ctx) - running = false; -else +if (!mutex_trylock (&damon_sysfs_lock)) +return -EBUSY ; + + ctx = kdamond->damon_ctx; +if (ctx) running =damon_is_running (ctx); +mutex_unlock (&damon_sysfs_lock); +return sysfs_emit (buf,"%s\n" , running ? damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON ] : damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_OFF ]);
Signature · 1 line
2.51.0