JFS: fix memleak in jfs_mount
authorDongliang Mu <mudongliangabcd@gmail.com>
Sat, 4 Sep 2021 02:37:41 +0000 (10:37 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 26 Nov 2021 10:40:32 +0000 (11:40 +0100)
[ Upstream commit c48a14dca2cb57527dde6b960adbe69953935f10 ]

In jfs_mount, when diMount(ipaimap2) fails, it goes to errout35. However,
the following code does not free ipaimap2 allocated by diReadSpecial.

Fix this by refactoring the error handling code of jfs_mount. To be
specific, modify the lable name and free ipaimap2 when the above error
ocurrs.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/jfs/jfs_mount.c

index b5214c9ac47acdb2a0a1750ff2f2e51582382b42..f1a705d159043e1bfe88acf0e3484fb4cedf5069 100644 (file)
@@ -93,14 +93,14 @@ int jfs_mount(struct super_block *sb)
         * (initialize mount inode from the superblock)
         */
        if ((rc = chkSuper(sb))) {
-               goto errout20;
+               goto out;
        }
 
        ipaimap = diReadSpecial(sb, AGGREGATE_I, 0);
        if (ipaimap == NULL) {
                jfs_err("jfs_mount: Failed to read AGGREGATE_I");
                rc = -EIO;
-               goto errout20;
+               goto out;
        }
        sbi->ipaimap = ipaimap;
 
@@ -111,7 +111,7 @@ int jfs_mount(struct super_block *sb)
         */
        if ((rc = diMount(ipaimap))) {
                jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc);
-               goto errout21;
+               goto err_ipaimap;
        }
 
        /*
@@ -120,7 +120,7 @@ int jfs_mount(struct super_block *sb)
        ipbmap = diReadSpecial(sb, BMAP_I, 0);
        if (ipbmap == NULL) {
                rc = -EIO;
-               goto errout22;
+               goto err_umount_ipaimap;
        }
 
        jfs_info("jfs_mount: ipbmap:0x%p", ipbmap);
@@ -132,7 +132,7 @@ int jfs_mount(struct super_block *sb)
         */
        if ((rc = dbMount(ipbmap))) {
                jfs_err("jfs_mount: dbMount failed w/rc = %d", rc);
-               goto errout22;
+               goto err_ipbmap;
        }
 
        /*
@@ -151,7 +151,7 @@ int jfs_mount(struct super_block *sb)
                if (!ipaimap2) {
                        jfs_err("jfs_mount: Failed to read AGGREGATE_I");
                        rc = -EIO;
-                       goto errout35;
+                       goto err_umount_ipbmap;
                }
                sbi->ipaimap2 = ipaimap2;
 
@@ -163,7 +163,7 @@ int jfs_mount(struct super_block *sb)
                if ((rc = diMount(ipaimap2))) {
                        jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d",
                                rc);
-                       goto errout35;
+                       goto err_ipaimap2;
                }
        } else
                /* Secondary aggregate inode table is not valid */
@@ -180,7 +180,7 @@ int jfs_mount(struct super_block *sb)
                jfs_err("jfs_mount: Failed to read FILESYSTEM_I");
                /* open fileset secondary inode allocation map */
                rc = -EIO;
-               goto errout40;
+               goto err_umount_ipaimap2;
        }
        jfs_info("jfs_mount: ipimap:0x%p", ipimap);
 
@@ -190,41 +190,34 @@ int jfs_mount(struct super_block *sb)
        /* initialize fileset inode allocation map */
        if ((rc = diMount(ipimap))) {
                jfs_err("jfs_mount: diMount failed w/rc = %d", rc);
-               goto errout41;
+               goto err_ipimap;
        }
 
-       goto out;
+       return rc;
 
        /*
         *      unwind on error
         */
-      errout41:                /* close fileset inode allocation map inode */
+err_ipimap:
+       /* close fileset inode allocation map inode */
        diFreeSpecial(ipimap);
-
-      errout40:                /* fileset closed */
-
+err_umount_ipaimap2:
        /* close secondary aggregate inode allocation map */
-       if (ipaimap2) {
+       if (ipaimap2)
                diUnmount(ipaimap2, 1);
+err_ipaimap2:
+       /* close aggregate inodes */
+       if (ipaimap2)
                diFreeSpecial(ipaimap2);
-       }
-
-      errout35:
-
-       /* close aggregate block allocation map */
+err_umount_ipbmap:     /* close aggregate block allocation map */
        dbUnmount(ipbmap, 1);
+err_ipbmap:            /* close aggregate inodes */
        diFreeSpecial(ipbmap);
-
-      errout22:                /* close aggregate inode allocation map */
-
+err_umount_ipaimap:    /* close aggregate inode allocation map */
        diUnmount(ipaimap, 1);
-
-      errout21:                /* close aggregate inodes */
+err_ipaimap:           /* close aggregate inodes */
        diFreeSpecial(ipaimap);
-      errout20:                /* aggregate closed */
-
-      out:
-
+out:
        if (rc)
                jfs_err("Mount JFS Failure: %d", rc);