Skip to content

Commit 14773bf

Browse files
Tetsuo Handaakpm00
authored andcommitted
mm: shrinkers: fix double kfree on shrinker name
syzbot is reporting double kfree() at free_prealloced_shrinker() [1], for destroy_unused_super() calls free_prealloced_shrinker() even if prealloc_shrinker() returned an error. Explicitly clear shrinker name when prealloc_shrinker() called kfree(). [[email protected]: zero shrinker->name in all cases where shrinker->name is freed] Link: https://lkml.kernel.org/r/YtgteTnQTgyuKUSY@castle Link: https://syzkaller.appspot.com/bug?extid=8b481578352d4637f510 [1] Link: https://lkml.kernel.org/r/[email protected] Fixes: e33c267 ("mm: shrinkers: provide shrinkers with names") Reported-by: syzbot <[email protected]> Signed-off-by: Tetsuo Handa <[email protected]> Acked-by: Roman Gushchin <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 187e7c4 commit 14773bf

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

mm/shrinker_debug.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ void shrinker_debugfs_remove(struct shrinker *shrinker)
251251
lockdep_assert_held(&shrinker_rwsem);
252252

253253
kfree_const(shrinker->name);
254+
shrinker->name = NULL;
254255

255256
if (!shrinker->debugfs_entry)
256257
return;

mm/vmscan.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,10 @@ int prealloc_shrinker(struct shrinker *shrinker, const char *fmt, ...)
644644
return -ENOMEM;
645645

646646
err = __prealloc_shrinker(shrinker);
647-
if (err)
647+
if (err) {
648648
kfree_const(shrinker->name);
649+
shrinker->name = NULL;
650+
}
649651

650652
return err;
651653
}
@@ -660,6 +662,7 @@ void free_prealloced_shrinker(struct shrinker *shrinker)
660662
{
661663
#ifdef CONFIG_SHRINKER_DEBUG
662664
kfree_const(shrinker->name);
665+
shrinker->name = NULL;
663666
#endif
664667
if (shrinker->flags & SHRINKER_MEMCG_AWARE) {
665668
down_write(&shrinker_rwsem);
@@ -704,8 +707,10 @@ int register_shrinker(struct shrinker *shrinker, const char *fmt, ...)
704707
return -ENOMEM;
705708

706709
err = __register_shrinker(shrinker);
707-
if (err)
710+
if (err) {
708711
kfree_const(shrinker->name);
712+
shrinker->name = NULL;
713+
}
709714
return err;
710715
}
711716
#else

0 commit comments

Comments
 (0)