Skip to content

Commit 04a06b1

Browse files
sjp38akpm00
authored andcommitted
mm/damon/sysfs: use dynamically allocated repeat mode damon_call_control
DAMON sysfs interface is using a single global repeat mode damon_call_control variable for refresh_ms handling, for all DAMON contexts. As a result, when there are more than one context, the single global damon_call_control is unexpectedly over-written (corrupted). Particularly the ->link field is overwritten by the multiple contexts and this can cause a user hangup, and/or a kernel crash. Fix it by using dynamically allocated damon_call_control object per DAMON context. Link: https://lkml.kernel.org/r/[email protected] Link: https://lore.kernel.org/[email protected] [1] Link: https://lore.kernel.org/[email protected] [2] Fixes: d809a7c ("mm/damon/sysfs: implement refresh_ms file internal work") Signed-off-by: SeongJae Park <[email protected]> Reported-by: Yunjeong Mun <[email protected]> Closes: https://lore.kernel.org/[email protected] Signed-off-by: Andrew Morton <[email protected]>
1 parent e6a0deb commit 04a06b1

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

mm/damon/sysfs.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,14 +1534,10 @@ static int damon_sysfs_repeat_call_fn(void *data)
15341534
return 0;
15351535
}
15361536

1537-
static struct damon_call_control damon_sysfs_repeat_call_control = {
1538-
.fn = damon_sysfs_repeat_call_fn,
1539-
.repeat = true,
1540-
};
1541-
15421537
static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
15431538
{
15441539
struct damon_ctx *ctx;
1540+
struct damon_call_control *repeat_call_control;
15451541
int err;
15461542

15471543
if (damon_sysfs_kdamond_running(kdamond))
@@ -1554,18 +1550,29 @@ static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond)
15541550
damon_destroy_ctx(kdamond->damon_ctx);
15551551
kdamond->damon_ctx = NULL;
15561552

1553+
repeat_call_control = kmalloc(sizeof(*repeat_call_control),
1554+
GFP_KERNEL);
1555+
if (!repeat_call_control)
1556+
return -ENOMEM;
1557+
15571558
ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]);
1558-
if (IS_ERR(ctx))
1559+
if (IS_ERR(ctx)) {
1560+
kfree(repeat_call_control);
15591561
return PTR_ERR(ctx);
1562+
}
15601563
err = damon_start(&ctx, 1, false);
15611564
if (err) {
1565+
kfree(repeat_call_control);
15621566
damon_destroy_ctx(ctx);
15631567
return err;
15641568
}
15651569
kdamond->damon_ctx = ctx;
15661570

1567-
damon_sysfs_repeat_call_control.data = kdamond;
1568-
damon_call(ctx, &damon_sysfs_repeat_call_control);
1571+
repeat_call_control->fn = damon_sysfs_repeat_call_fn;
1572+
repeat_call_control->data = kdamond;
1573+
repeat_call_control->repeat = true;
1574+
repeat_call_control->dealloc_on_cancel = true;
1575+
damon_call(ctx, repeat_call_control);
15691576
return err;
15701577
}
15711578

0 commit comments

Comments
 (0)