From d66aed3d859719eb15613f99c7716bdbdc07378b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Jul 2014 13:24:40 -0700 Subject: [PATCH] 3.10-stable patches added patches: ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch ext4-fix-hole-punching-for-files-with-indirect-blocks.patch --- ...fer-double-free-in-ext4_alloc_branch.patch | 50 ++++++++++++++++ ...ching-for-files-with-indirect-blocks.patch | 57 +++++++++++++++++++ queue-3.10/series | 2 + 3 files changed, 109 insertions(+) create mode 100644 queue-3.10/ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch create mode 100644 queue-3.10/ext4-fix-hole-punching-for-files-with-indirect-blocks.patch diff --git a/queue-3.10/ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch b/queue-3.10/ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch new file mode 100644 index 00000000000..8d608e1c3ee --- /dev/null +++ b/queue-3.10/ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch @@ -0,0 +1,50 @@ +From c5c7b8ddfbf8cb3b2291e515a34ab1b8982f5a2d Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sun, 15 Jun 2014 23:46:28 -0400 +Subject: ext4: Fix buffer double free in ext4_alloc_branch() + +From: Jan Kara + +commit c5c7b8ddfbf8cb3b2291e515a34ab1b8982f5a2d upstream. + +Error recovery in ext4_alloc_branch() calls ext4_forget() even for +buffer corresponding to indirect block it did not allocate. This leads +to brelse() being called twice for that buffer (once from ext4_forget() +and once from cleanup in ext4_ind_map_blocks()) leading to buffer use +count misaccounting. Eventually (but often much later because there +are other users of the buffer) we will see messages like: +VFS: brelse: Trying to free free buffer + +Another manifestation of this problem is an error: +JBD2 unexpected failure: jbd2_journal_revoke: !buffer_revoked(bh); +inconsistent data on disk + +The fix is easy - don't forget buffer we did not allocate. Also add an +explanatory comment because the indexing at ext4_alloc_branch() is +somewhat subtle. + +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/indirect.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -390,7 +390,13 @@ static int ext4_alloc_branch(handle_t *h + 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], diff --git a/queue-3.10/ext4-fix-hole-punching-for-files-with-indirect-blocks.patch b/queue-3.10/ext4-fix-hole-punching-for-files-with-indirect-blocks.patch new file mode 100644 index 00000000000..e79c8878266 --- /dev/null +++ b/queue-3.10/ext4-fix-hole-punching-for-files-with-indirect-blocks.patch @@ -0,0 +1,57 @@ +From a93cd4cf86466caa49cfe64607bea7f0bde3f916 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 26 Jun 2014 12:30:54 -0400 +Subject: ext4: Fix hole punching for files with indirect blocks + +From: Jan Kara + +commit a93cd4cf86466caa49cfe64607bea7f0bde3f916 upstream. + +Hole punching code for files with indirect blocks wrongly computed +number of blocks which need to be cleared when traversing the indirect +block tree. That could result in punching more blocks than actually +requested and thus effectively cause a data loss. For example: + +fallocate -n -p 10240000 4096 + +will punch the range 10240000 - 12632064 instead of the range 1024000 - +10244096. Fix the calculation. + +Fixes: 8bad6fc813a3a5300f51369c39d315679fd88c72 +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/indirect.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -1331,16 +1331,24 @@ static int free_hole_blocks(handle_t *ha + blk = *i_data; + if (level > 0) { + ext4_lblk_t first2; ++ ext4_lblk_t count2; ++ + bh = sb_bread(inode->i_sb, le32_to_cpu(blk)); + if (!bh) { + EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk), + "Read failure"); + return -EIO; + } +- first2 = (first > offset) ? first - offset : 0; ++ if (first > offset) { ++ first2 = first - offset; ++ count2 = count; ++ } else { ++ first2 = 0; ++ count2 = count - (offset - first); ++ } + ret = free_hole_blocks(handle, inode, bh, + (__le32 *)bh->b_data, level - 1, +- first2, count - offset, ++ first2, count2, + inode->i_sb->s_blocksize >> 2); + if (ret) { + brelse(bh); diff --git a/queue-3.10/series b/queue-3.10/series index 7ffd4156c77..8c8895d6fc0 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -32,3 +32,5 @@ arm-omap2-fix-parser-bug-in-platform-muxing-code.patch arm64-bug-fix-in-stack-alignment-exception.patch b43-fix-frequency-reported-on-g-phy-with-new-firmware.patch cifs-fix-mount-failure-with-broken-pathnames-when-smb3-mount-with-mapchars-option.patch +ext4-fix-buffer-double-free-in-ext4_alloc_branch.patch +ext4-fix-hole-punching-for-files-with-indirect-blocks.patch -- 2.47.3