mm/damon/dbgfs: fix memory leak when using debugfs_lookup()
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 Sep 2022 19:11:49 +0000 (19:11 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Oct 2022 08:39:37 +0000 (10:39 +0200)
commit 1552fd3ef7dbe07208b8ae84a0a6566adf7dfc9d upstream.

When calling debugfs_lookup() the result must have dput() called on it,
otherwise the memory will leak over time.  Fix this up by properly calling
dput().

Link: https://lkml.kernel.org/r/20220902191149.112434-1-sj@kernel.org
Fixes: 75c1c2b53c78b ("mm/damon/dbgfs: support multiple contexts")
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mm/damon/dbgfs.c

index 70a5cb977ed0e4eea11bddc361e36057066eff78..e670fb6b1126051d302cd201e474bca9bbdb01e4 100644 (file)
@@ -443,6 +443,7 @@ static int dbgfs_rm_context(char *name)
        struct dentry *root, *dir, **new_dirs;
        struct damon_ctx **new_ctxs;
        int i, j;
+       int ret = 0;
 
        if (damon_nr_running_ctxs())
                return -EBUSY;
@@ -457,14 +458,16 @@ static int dbgfs_rm_context(char *name)
 
        new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs),
                        GFP_KERNEL);
-       if (!new_dirs)
-               return -ENOMEM;
+       if (!new_dirs) {
+               ret = -ENOMEM;
+               goto out_dput;
+       }
 
        new_ctxs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_ctxs),
                        GFP_KERNEL);
        if (!new_ctxs) {
-               kfree(new_dirs);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_new_dirs;
        }
 
        for (i = 0, j = 0; i < dbgfs_nr_ctxs; i++) {
@@ -484,7 +487,13 @@ static int dbgfs_rm_context(char *name)
        dbgfs_ctxs = new_ctxs;
        dbgfs_nr_ctxs--;
 
-       return 0;
+       goto out_dput;
+
+out_new_dirs:
+       kfree(new_dirs);
+out_dput:
+       dput(dir);
+       return ret;
 }
 
 static ssize_t dbgfs_rm_context_write(struct file *file,