diff mbox series

btrfs-progs: Fix xxhash on big endian machines

Message ID 20200316090512.21519-1-nborisov@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: Fix xxhash on big endian machines | expand

Commit Message

Nikolay Borisov March 16, 2020, 9:05 a.m. UTC
xxhash's state and results are always in little, but in progs after the
hash was calculated it was copied to the final buffer via memcpy,
meaning it'd be parsed as a big endian number on big endian machines.
This is incompatible with the kernel implementation of xxhash which
results in erroneous "checksum didn't match" errors on mount.

Fix it by using put_unaligned_le64 which always ensures the resulting
checksum will be copied in little endian format as the kernel expects
it.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=206835
Fixes: f070ece2e98f ("btrfs-progs: add xxhash64 to mkfs")
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 crypto/hash.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

--
2.17.1

Comments

Johannes Thumshirn March 16, 2020, 9:26 a.m. UTC | #1
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
David Sterba March 16, 2020, 10:56 p.m. UTC | #2
On Mon, Mar 16, 2020 at 11:05:12AM +0200, Nikolay Borisov wrote:
> xxhash's state and results are always in little, but in progs after the
> hash was calculated it was copied to the final buffer via memcpy,
> meaning it'd be parsed as a big endian number on big endian machines.
> This is incompatible with the kernel implementation of xxhash which
> results in erroneous "checksum didn't match" errors on mount.
> 
> Fix it by using put_unaligned_le64 which always ensures the resulting
> checksum will be copied in little endian format as the kernel expects
> it.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=206835
> Fixes: f070ece2e98f ("btrfs-progs: add xxhash64 to mkfs")
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>

Added to devel, thanks.
David Sterba March 17, 2020, 8:34 p.m. UTC | #3
On Mon, Mar 16, 2020 at 11:05:12AM +0200, Nikolay Borisov wrote:
> xxhash's state and results are always in little, but in progs after the
> hash was calculated it was copied to the final buffer via memcpy,
> meaning it'd be parsed as a big endian number on big endian machines.
> This is incompatible with the kernel implementation of xxhash which
> results in erroneous "checksum didn't match" errors on mount.
> 
> Fix it by using put_unaligned_le64 which always ensures the resulting
> checksum will be copied in little endian format as the kernel expects
> it.
> 
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=206835
> Fixes: f070ece2e98f ("btrfs-progs: add xxhash64 to mkfs")
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> ---
>  crypto/hash.c | 7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/crypto/hash.c b/crypto/hash.c
> index 48623c798739..4009e84e8b2c 100644
> --- a/crypto/hash.c
> +++ b/crypto/hash.c
> @@ -19,12 +19,7 @@ int hash_xxhash(const u8 *buf, size_t length, u8 *out)
>  	XXH64_hash_t hash;
> 
>  	hash = XXH64(buf, length, 0);
> -	/*
> -	 * NOTE: we're not taking the canonical form here but the plain hash to
> -	 * be compatible with the kernel implementation!
> -	 */
> -	memcpy(out, &hash, 8);
> -
> +	put_unaligned_le64(&hash, out);

This does not work, the test mkfs/019 fails.
diff mbox series

Patch

diff --git a/crypto/hash.c b/crypto/hash.c
index 48623c798739..4009e84e8b2c 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -19,12 +19,7 @@  int hash_xxhash(const u8 *buf, size_t length, u8 *out)
 	XXH64_hash_t hash;

 	hash = XXH64(buf, length, 0);
-	/*
-	 * NOTE: we're not taking the canonical form here but the plain hash to
-	 * be compatible with the kernel implementation!
-	 */
-	memcpy(out, &hash, 8);
-
+	put_unaligned_le64(&hash, out);
 	return 0;
 }