Subject: bug#76360: cksum crc broken with VMULL on musl

From: Paul Eggert <[email-masked]>
Date: Mon, 17 Feb 2025 02:34:11 -0800

Thanks for the bug report. I installed the attached patches; please give 
them a try, as I don't have easy access to that platform.

From c98e90b074429adb3492d7b79c3a69bad5c07f5f Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Mon, 17 Feb 2025 02:23:52 -0800
Subject: [PATCH 1/2] cksum: fix test for missing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* tests/cksum/cksum.sh: Don’t output confusing diagnostic.
Problem reported by Alyssa Ross (Bug#76360).
---
 tests/cksum/cksum.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/cksum/cksum.sh b/tests/cksum/cksum.sh
index baab500e0..83f61ad2f 100755
--- a/tests/cksum/cksum.sh
+++ b/tests/cksum/cksum.sh
@@ -20,7 +20,7 @@
 print_ver_ cksum printf

-returns_ 1 cksum missing || fail=1
+returns_ 1 cksum missing 2> /dev/null || fail=1
 
 # Pass in expected crc and crc32b for file "in"
 # Sets fail=1 upon failure
-- 
2.45.2

From 7eada35b4fbb48e7fe430d1b18dae7d191f84f8e Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Mon, 17 Feb 2025 02:27:09 -0800
Subject: [PATCH 2/2] cksum: port to 32-bit uint_fast32_t
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/cksum_vmull.c (cksum_vmull): Don’t assume
uint_fast32_t can hold 64 bits.
Problem reported by Alyssa Ross (Bug#76360).
---
 NEWS              | 3 +++
 src/cksum_vmull.c | 7 +++++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index c6edf16d4..981ffa7b4 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   output are the same terminal device and the output is append-only.
   [bug introduced in coreutils-9.6]
 
+  'cksum -a crc' misbehaved on aarch64 with 32-bit uint_fast32_t.
+  [bug introduced in coreutils-9.6]
+
   'ls -Z dir' would crash.
   [bug introduced in coreutils-9.6]
 
diff --git a/src/cksum_vmull.c b/src/cksum_vmull.c
index 7611c4244..0ff81e225 100644
--- a/src/cksum_vmull.c
+++ b/src/cksum_vmull.c
@@ -92,7 +92,9 @@ cksum_vmull (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
           data = bswap_neon (data);
           /* XOR in initial CRC value (for us 0 so no effect), or CRC value
              calculated for previous BUFLEN buffer from fread */
-          xor_crc = vcombine_u64 (vcreate_u64 (0), vcreate_u64 (crc << 32));
+
+          uint64_t wcrc = crc;
+          xor_crc = vcombine_u64 (vcreate_u64 (0), vcreate_u64 (wcrc << 32));
           crc = 0;
           data = veorq_u64 (data, xor_crc);
           data3 = vld1q_u64 ((uint64_t *) (datap + 1));
@@ -193,7 +195,8 @@ cksum_vmull (FILE *fp, uint_fast32_t *crc_out, uintmax_t *length_out)
         {
           data = vld1q_u64 ((uint64_t *) (datap));
           data = bswap_neon (data);
-          xor_crc = vcombine_u64 (vcreate_u64 (0), vcreate_u64 (crc << 32));
+          uint64_t wcrc = crc;
+          xor_crc = vcombine_u64 (vcreate_u64 (0), vcreate_u64 (wcrc << 32));
           crc = 0;
           data = veorq_u64 (data, xor_crc);
           while (bytes_read >= 32)
-- 
2.45.2