summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--src/md5sum.c26
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/misc/md5sum-bsd41
4 files changed, 69 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 879828e2b..8c218b773 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS -*- outline -*-
* Noteworthy changes in release ?.? (????-??-??) [?]
+** Improvements
+
+ md5sum --check now supports the -r format from the corresponding BSD tool.
+ This also affects sha1sum, sha224sum, sha384sum and sha512sum.
+
* Noteworthy changes in release 8.13 (2011-09-08) [stable]
diff --git a/src/md5sum.c b/src/md5sum.c
index ff9538a28..9de34a5e8 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -99,7 +99,7 @@
not include any newline character at the end of a line. */
#define MIN_DIGEST_LINE_LENGTH \
(DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
- + 2 /* blank and binary indicator */ \
+ + 1 /* blank */ \
+ 1 /* minimum filename length */ )
/* True if any of the files read were the standard input. */
@@ -126,6 +126,9 @@ static bool quiet = false;
improperly formatted. */
static bool strict = false;
+/* Whether a BSD reversed format checksum is detected. */
+static int bsd_reversed = -1;
+
/* For long options that have no equivalent short option, use a
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
enum
@@ -307,9 +310,24 @@ split_3 (char *s, size_t s_len,
s[i++] = '\0';
- if (s[i] != ' ' && s[i] != '*')
- return false;
- *binary = (s[i++] == '*');
+ /* If "bsd reversed" format detected. */
+ if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*'))
+ {
+ /* Don't allow mixing bsd and standard formats,
+ to minimize security issues with attackers
+ renaming files with leading spaces.
+ This assumes that with bsd format checksums
+ that the first file name does not have
+ a leading ' ' or '*'. */
+ if (bsd_reversed == 0)
+ return false;
+ bsd_reversed = 1;
+ }
+ else if (bsd_reversed != 1)
+ {
+ bsd_reversed = 0;
+ *binary = (s[i++] == '*');
+ }
/* All characters between the type indicator and end of line are
significant -- that includes leading and trailing white space. */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b920abafc..eeb4cab2d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -198,6 +198,7 @@ TESTS = \
misc/id-context \
misc/id-groups \
misc/md5sum \
+ misc/md5sum-bsd \
misc/md5sum-newline \
misc/md5sum-parallel \
misc/mknod \
diff --git a/tests/misc/md5sum-bsd b/tests/misc/md5sum-bsd
new file mode 100755
index 000000000..324530c86
--- /dev/null
+++ b/tests/misc/md5sum-bsd
@@ -0,0 +1,41 @@
+#!/bin/sh
+# make sure `md5sum -c' works for alternate BSD format (md5 -r)
+
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+print_ver_ md5sum
+
+# Note we start this list with a name
+# that's unambiguous in BSD format.
+# I.E. one not starting with ' ' or '*'
+for i in 'a' ' b' '*c' 'dd' ' '; do
+ echo "$i" > "$i"
+ md5sum "$i" >> check.md5sum
+done
+sed 's/ / /' check.md5sum > check.md5
+
+# Note only a single format is supported per run
+md5sum --strict -c check.md5sum || fail=1
+md5sum --strict -c check.md5 || fail=1
+
+# If we skip the first entry in the BSD format checksums
+# then it'll be detected as standard format and error.
+# This unlikely caveat was thought better than mandating
+# an option to avoid the ambiguity.
+tail -n+2 check.md5 | md5sum --strict -c && fail=1
+
+Exit $fail