From 7da844cc86e1209acbe820771b0e9a35fd89da3b Mon Sep 17 00:00:00 2001 From: Pádraig Brady
Date: Fri, 16 Sep 2011 11:47:35 +0100
Subject: md5sum: handle BSD reversed format checksums
* src/md5sum.c (split_3): Detect and handle BSD reversed
format checksums.
* tests/misc/md5sum-bsd: Add a new test.
* tests/Makefile.am: Reference new test.
* NEWS: Mention the improvement
Suggested by Rimas Kudelis.
---
NEWS | 5 +++++
src/md5sum.c | 26 ++++++++++++++++++++++----
tests/Makefile.am | 1 +
tests/misc/md5sum-bsd | 41 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 69 insertions(+), 4 deletions(-)
create mode 100755 tests/misc/md5sum-bsd
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