diff mbox

[3.11.y.z,extended,stable] Patch "xfs: fix directory hash ordering bug" has been added to staging queue

Message ID 1398072734-17245-1-git-send-email-luis.henriques@canonical.com
State New
Headers show

Commit Message

Luis Henriques April 21, 2014, 9:32 a.m. UTC
This is a note to let you know that I have just added a patch titled

    xfs: fix directory hash ordering bug

to the linux-3.11.y-queue branch of the 3.11.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.11.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.11.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

From d7f726a0b549e7c62294527d95f7cbeec44854f5 Mon Sep 17 00:00:00 2001
From: Mark Tinguely <tinguely@sgi.com>
Date: Fri, 4 Apr 2014 07:10:49 +1100
Subject: xfs: fix directory hash ordering bug

commit c88547a8119e3b581318ab65e9b72f27f23e641d upstream.

Commit f5ea1100 ("xfs: add CRCs to dir2/da node blocks") introduced
in 3.10 incorrectly converted the btree hash index array pointer in
xfs_da3_fixhashpath(). It resulted in the the current hash always
being compared against the first entry in the btree rather than the
current block index into the btree block's hash entry array. As a
result, it was comparing the wrong hashes, and so could misorder the
entries in the btree.

For most cases, this doesn't cause any problems as it requires hash
collisions to expose the ordering problem. However, when there are
hash collisions within a directory there is a very good probability
that the entries will be ordered incorrectly and that actually
matters when duplicate hashes are placed into or removed from the
btree block hash entry array.

This bug results in an on-disk directory corruption and that results
in directory verifier functions throwing corruption warnings into
the logs. While no data or directory entries are lost, access to
them may be compromised, and attempts to remove entries from a
directory that has suffered from this corruption may result in a
filesystem shutdown.  xfs_repair will fix the directory hash
ordering without data loss occuring.

[dchinner: wrote useful a commit message]

Reported-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
[ luis: backported to 3.11: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 fs/xfs/xfs_da_btree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--
1.9.1

Comments

Mark Tinguely April 21, 2014, 1:41 p.m. UTC | #1
Added Greg to CC.

This would also work for Linux 3.10-stable. Greg is looking for such a 
patch.

--Mark Tinguely.

On 04/21/14 04:32, Luis Henriques wrote:
> This is a note to let you know that I have just added a patch titled
>
>      xfs: fix directory hash ordering bug
>
> to the linux-3.11.y-queue branch of the 3.11.y.z extended stable tree
> which can be found at:
>
>   http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.11.y-queue
>
> If you, or anyone else, feels it should not be added to this tree, please
> reply to this email.
>
> For more information about the 3.11.y.z tree, see
> https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
>
> Thanks.
> -Luis
>
> ------
>
>> From d7f726a0b549e7c62294527d95f7cbeec44854f5 Mon Sep 17 00:00:00 2001
> From: Mark Tinguely<tinguely@sgi.com>
> Date: Fri, 4 Apr 2014 07:10:49 +1100
> Subject: xfs: fix directory hash ordering bug
>
> commit c88547a8119e3b581318ab65e9b72f27f23e641d upstream.
>
> Commit f5ea1100 ("xfs: add CRCs to dir2/da node blocks") introduced
> in 3.10 incorrectly converted the btree hash index array pointer in
> xfs_da3_fixhashpath(). It resulted in the the current hash always
> being compared against the first entry in the btree rather than the
> current block index into the btree block's hash entry array. As a
> result, it was comparing the wrong hashes, and so could misorder the
> entries in the btree.
>
> For most cases, this doesn't cause any problems as it requires hash
> collisions to expose the ordering problem. However, when there are
> hash collisions within a directory there is a very good probability
> that the entries will be ordered incorrectly and that actually
> matters when duplicate hashes are placed into or removed from the
> btree block hash entry array.
>
> This bug results in an on-disk directory corruption and that results
> in directory verifier functions throwing corruption warnings into
> the logs. While no data or directory entries are lost, access to
> them may be compromised, and attempts to remove entries from a
> directory that has suffered from this corruption may result in a
> filesystem shutdown.  xfs_repair will fix the directory hash
> ordering without data loss occuring.
>
> [dchinner: wrote useful a commit message]
>
> Reported-by: Hannes Frederic Sowa<hannes@stressinduktion.org>
> Signed-off-by: Mark Tinguely<tinguely@sgi.com>
> Reviewed-by: Ben Myers<bpm@sgi.com>
> Signed-off-by: Dave Chinner<david@fromorbit.com>
> [ luis: backported to 3.11: adjusted context ]
> Signed-off-by: Luis Henriques<luis.henriques@canonical.com>
> ---
>   fs/xfs/xfs_da_btree.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
> index eca6f9d..79ddbaf 100644
> --- a/fs/xfs/xfs_da_btree.c
> +++ b/fs/xfs/xfs_da_btree.c
> @@ -1334,7 +1334,7 @@ xfs_da3_fixhashpath(
>   		node = blk->bp->b_addr;
>   		xfs_da3_node_hdr_from_disk(&nodehdr, node);
>   		btree = xfs_da3_node_tree_p(node);
> -		if (be32_to_cpu(btree->hashval) == lasthash)
> +		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
>   			break;
>   		blk->hashval = lasthash;
>   		btree[blk->index].hashval = cpu_to_be32(lasthash);
> --
> 1.9.1
>
diff mbox

Patch

diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index eca6f9d..79ddbaf 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1334,7 +1334,7 @@  xfs_da3_fixhashpath(
 		node = blk->bp->b_addr;
 		xfs_da3_node_hdr_from_disk(&nodehdr, node);
 		btree = xfs_da3_node_tree_p(node);
-		if (be32_to_cpu(btree->hashval) == lasthash)
+		if (be32_to_cpu(btree[blk->index].hashval) == lasthash)
 			break;
 		blk->hashval = lasthash;
 		btree[blk->index].hashval = cpu_to_be32(lasthash);