Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.

Link: https://lkml.kernel.org/r/20250905101046.2288-1-disclosure@aisle.com
Fixes: a61ea561c871 ("mm/damon/sysfs: link DAMON for virtual address spaces monitoring")
Signed-off-by: Stanislav Fort <disclosure@aisle.com>
Reported-by: Stanislav Fort <disclosure@aisle.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Stanislav Fort and committed by
Andrew Morton
3260a3f0 0ce9398a

+9 -5
+9 -5
mm/damon/sysfs.c
··· 1260 1260 { 1261 1261 struct damon_sysfs_kdamond *kdamond = container_of(kobj, 1262 1262 struct damon_sysfs_kdamond, kobj); 1263 - struct damon_ctx *ctx = kdamond->damon_ctx; 1264 - bool running; 1263 + struct damon_ctx *ctx; 1264 + bool running = false; 1265 1265 1266 - if (!ctx) 1267 - running = false; 1268 - else 1266 + if (!mutex_trylock(&damon_sysfs_lock)) 1267 + return -EBUSY; 1268 + 1269 + ctx = kdamond->damon_ctx; 1270 + if (ctx) 1269 1271 running = damon_is_running(ctx); 1272 + 1273 + mutex_unlock(&damon_sysfs_lock); 1270 1274 1271 1275 return sysfs_emit(buf, "%s\n", running ? 1272 1276 damon_sysfs_cmd_strs[DAMON_SYSFS_CMD_ON] :