ext4: Fix buffer double free in ext4_alloc_branch()
[firefly-linux-kernel-4.4.55.git] / fs / ext4 / indirect.c
index 8a57e9fcd1b987bdab029e7658ae100d10949d5a..f85bafd474dc8cd9dee7d743d48047b50589068a 100644 (file)
@@ -389,7 +389,13 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
        return 0;
 failed:
        for (; i >= 0; i--) {
-               if (i != indirect_blks && branch[i].bh)
+               /*
+                * We want to ext4_forget() only freshly allocated indirect
+                * blocks.  Buffer for new_blocks[i-1] is at branch[i].bh and
+                * buffer at branch[0].bh is indirect block / inode already
+                * existing before ext4_alloc_branch() was called.
+                */
+               if (i > 0 && i != indirect_blks && branch[i].bh)
                        ext4_forget(handle, 1, inode, branch[i].bh,
                                    branch[i].bh->b_blocknr);
                ext4_free_blocks(handle, inode, NULL, new_blocks[i],