It's not a usual case, but for consistency "-a sha2" should support
e.g. untagged checksums that are a mix of sha256sum and sha512sum.

* src/cksum.c (split_3): Reset the sha2 variant search if
the generic sha2 is specified.  It's ok to reset the global
CKSUM_ALGORITHM as its subsequent use is conflicting with
the specific chosen variant.
* tests/cksum/cksum-c.sh: Add test cases.
* NEWS: Mention the bug fix.

Discovered by Anthropic's OSS Scanner, as bug ANT-2026-83HIODH2.
Discovered by SecBuddyF (with Hy4-preview) of Tencent KeenSecurityLab.
---
 NEWS                   |  6 ++++++
 src/cksum.c            |  4 ++++
 tests/cksum/cksum-c.sh | 14 ++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/NEWS b/NEWS
index c83aeba3b..641117607 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,12 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   was used, even when the look-up inside the chroot succeeded.
   [bug introduced in coreutils-8.23]
 
+  'cksum --check -a sha2' now verifies all lines in a checksum file that
+  mixes SHA2 digest lengths.  Previously only lines with the same length
+  as the first tagged line were verified, with other lines being treated
+  as invalid, and thus, without --strict, not impacting the exit status.
+  [bug introduced in coreutils-9.9]
+
   cut, expand, fold, join, numfmt, unexpand, and uniq, no longer consider
   the \u0085 (next line) character as a separator on non-GLIBC platforms.
   [bug introduced in coreutils-9.11]
diff --git a/src/cksum.c b/src/cksum.c
index e0338ead4..bc454e906 100644
--- a/src/cksum.c
+++ b/src/cksum.c
@@ -373,6 +373,7 @@ static int const algorithm_bits[] =
 static_assert (countof (algorithm_bits) == countof (algorithm_args));
 
 static bool algorithm_specified = false;
+static bool sha2_specified = false;
 static bool legacy_mode = false;
 enum Algorithm cksum_algorithm = crc;
 
@@ -925,6 +926,8 @@ split_3 (char *s, idx_t s_len,
   /* Check for BSD-style checksum line. */
 
 #if HASH_ALGO_CKSUM
+  if (sha2_specified)
+    cksum_algorithm = sha2;  /* Recheck for specific variant.  */
   if (! algorithm_specified || cksum_algorithm == sha2)
     {
       ptrdiff_t algo_tag = algorithm_from_tag (s + i);
@@ -1615,6 +1618,7 @@ main (int argc, char **argv)
         cksum_algorithm = XARGMATCH_EXACT ("--algorithm", optarg,
                                            algorithm_args, algorithm_types);
         algorithm_specified = true;
+        sha2_specified = cksum_algorithm == sha2;
         break;
 
       case DEBUG_PROGRAM_OPTION:
diff --git a/tests/cksum/cksum-c.sh b/tests/cksum/cksum-c.sh
index 496ab5f62..2271da270 100755
--- a/tests/cksum/cksum-c.sh
+++ b/tests/cksum/cksum-c.sh
@@ -37,6 +37,20 @@ for file in sha384-tag.sum sha2-tag.sum; do
   done
 done
 
+# Ensure -a sha2 checks all lines in a file with mixed SHA2 lengths.
+# coreutils-9.9 to 9.12 only checked lines with the first tagged length.
+cksum -a sha2 -l 224 input > sha2-mixed.sum &&
+cksum -a sha2 -l 512 input >> sha2-mixed.sum &&
+cksum -a sha2 -l 256 --untagged input >> sha2-mixed.sum &&
+cksum -a sha2 -l 384 input >> sha2-mixed.sum || framework_failure_
+cksum -a sha2 --strict --check sha2-mixed.sum || fail=1
+# A mismatch in a line of a different length than the first must be detected
+cksum -a sha2 -l 224 input > sha2-mixed-bad.sum &&
+echo "SHA512 (input) = $(printf '%0128d' 0)" >> sha2-mixed-bad.sum \
+  || framework_failure_
+returns_ 1 cksum -a sha2 --check sha2-mixed-bad.sum > out 2>&1 || fail=1
+grep 'input: FAILED' out || fail=1
+
 # Ensure invalid length is handled appropriately
 # coreutils-9.8 had undefined behavior with the following:
 printf '%s\n' 'SHA2-128 (/dev/null) = 38b060a751ac96384cd9327eb1b1e36a' \
-- 
2.55.0


Reply via email to