summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2025-02-17 02:27:09 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2025-02-17 02:31:50 -0800
commit7eada35b4fbb48e7fe430d1b18dae7d191f84f8e (patch)
treecb4b9de7a1bdfb7311f451c014b6a8c4bfb60f82
parentcksum: fix test for missing (diff)
downloadcoreutils-7eada35b4fbb48e7fe430d1b18dae7d191f84f8e.tar.gz
coreutils-7eada35b4fbb48e7fe430d1b18dae7d191f84f8e.zip
cksum: port to 32-bit uint_fast32_t
* src/cksum_vmull.c (cksum_vmull): Don’t assume uint_fast32_t can hold 64 bits. Problem reported by Alyssa Ross (Bug#76360).
-rw-r--r--NEWS3
-rw-r--r--src/cksum_vmull.c7
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)