ptx: avoid heap overrun for backslash at end of optarg string

* src/ptx.c (copy_unescaped_string): Ignore a lone backslash
at end of string.  Reported by Cristian Cadar, Daniel Dunbar
and Dawson Engler.  Details here:
<http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/13005>.
* tests/misc/Makefile.am (TESTS): Add ptx-overrun.
* tests/misc/ptx-overrun: New file.  Test for the above fix.
* NEWS: Mention the fix.

Signed-off-by: Jim Meyering <meyering@redhat.com>
This commit is contained in:
Jim Meyering 2008-03-21 10:37:26 +01:00
parent 4f812540a2
commit a0851554bd
5 changed files with 54 additions and 1 deletions

5
NEWS
View File

@ -16,6 +16,11 @@ GNU coreutils NEWS -*- outline -*-
when the destination had two or more hard links. It no longer does that.
[bug introduced in coreutils-5.3.0]
"ptx -F'\' long-file-name" would overrun a malloc'd buffer and corrupt
the heap. That was triggered by a lone backslash (or odd number of them)
at the end of the option argument to --flag-truncation=STRING (-F),
--word-regexp=REGEXP (-W), or --sentence-regexp=REGEXP (-S).
"rmdir --ignore-fail-on-non-empty" detects and ignores the failure
in more cases when a directory is empty.

3
THANKS
View File

@ -105,12 +105,14 @@ Colin Plumb colin@nyx.net
Colin Watson cjw44@riva.ucam.org
Collin Rogowski collin@rogowski.de
Cray-Cyber Project http://www.cray-cyber.org
Cristian Cadar cristic@stanford.edu
Cyril Bouthors cyril@bouthors.org
Dale Scheetz dwarf@polaris.net
Dan Hagerty hag@gnu.ai.it.edu
Dan Jacobson http://www.geocities.com/jidani
Dan Pascu dan@services.iiruc.ro
Daniel Bergstrom noa@melody.se
Daniel Dunbar ddunbar@stanford.edu
Daniel P. Berrangé berrange@redhat.com
Dániel Varga danielv@axelero.hu
Danny Levinson danny.levinson@overture.com
@ -125,6 +127,7 @@ David Godfrey dave@delta.demon.co.uk
David Luyer david_luyer@pacific.net.au
David Madore david.madore@ens.fr
David Malone dwmalone@cnri.dit.ie
Dawson Engler engler@stanford.edu
Dean Gaudet dean-savannah@arctic.org
Deepak Goel deego@gnufans.org
Dennis Henriksen opus@flamingo.osrl.dk

View File

@ -388,6 +388,10 @@ copy_unescaped_string (const char *string)
string++;
break;
case '\0': /* lone backslash at end of string */
/* ignore it */
break;
default:
*cursor++ = '\\';
*cursor++ = *string++;

View File

@ -1,6 +1,6 @@
# Make miscellaneous coreutils tests. -*-Makefile-*-
# Copyright (C) 2001-2007 Free Software Foundation, Inc.
# Copyright (C) 2001-2008 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
@ -38,6 +38,7 @@ TESTS = \
ls-time \
ls-misc \
date \
ptx-overrun \
xstrtol \
od \
mktemp \

40
tests/misc/ptx-overrun Executable file
View File

@ -0,0 +1,40 @@
#!/bin/sh
# Trigger a heap-clobbering bug in ptx from coreutils-6.10 and earlier.
# Copyright (C) 2008 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/>.
if test "$VERBOSE" = yes; then
set -x
ptx --version
fi
. $srcdir/../test-lib.sh
# Using a long file name makes an abort more likely.
# Even with no file name, valgrind detects the buffer overrun.
f=01234567890123456789012345678901234567890123456789
touch $f empty || framework_failure
fail=0
# Specifying a regular expression ending in a lone backslash
# would cause ptx to write beyond the end of a malloc'd buffer.
ptx -F '\' $f < /dev/null > out || fail=1
ptx -S 'foo\' $f < /dev/null >> out || fail=1
ptx -W 'bar\\\' $f < /dev/null >> out || fail=1
compare out empty || fail=1
(exit $fail); exit $fail