From 7361146db70d7618943cba5722045f49ac13ac40 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Fri, 11 Dec 2015 21:31:29 -0800 Subject: [PATCH] sed: fix a heap-clobbering buffer overrun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sed/execute.c (str_append_modified): Upon encountering an incomplete multi-byte sequence in an substitution replacement string do not treat mbrtowc's return value of -2 as a large, positive number. * testsuite/subst-mb-incomplete.sh: New file/test. * testsuite/Makefile.am (T): Add it. Reported by Hanno Böck in http://debbugs.gnu.org/22127. Hanno used the AFL fuzzer to find the segfault-inducing input from which I derived the test's input. Introduced by v4.2.2-76-g78e8e58, this bug was never in a release. --- sed/execute.c | 8 ++++---- testsuite/Makefile.am | 1 + testsuite/subst-mb-incomplete.sh | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100755 testsuite/subst-mb-incomplete.sh diff --git a/sed/execute.c b/sed/execute.c index 7bc394a..5bebfc2 100644 --- a/sed/execute.c +++ b/sed/execute.c @@ -231,15 +231,15 @@ str_append_modified(struct line *to, const char *string, size_t length, continue; } - if (n > 0) - string += n, length -= n; - else + if (n == 0 || n == (size_t) -2) { - /* Incomplete sequence, copy it manually. */ + /* L'\0' or an incomplete sequence: copy it manually. */ str_append(to, string, length); return; } + string += n, length -= n; + /* Convert the first character specially... */ if (type & (REPL_UPPERCASE_FIRST | REPL_LOWERCASE_FIRST)) { diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 0c065ed..b37e402 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -12,6 +12,7 @@ T = \ in-place-hyphen.sh \ invalid-mb-seq-UMR.sh \ range-overlap.sh \ + subst-mb-incomplete.sh \ temp-file-cleanup.sh TESTS = $(check_PROGRAMS) $(SEDTESTS) $(T) diff --git a/testsuite/subst-mb-incomplete.sh b/testsuite/subst-mb-incomplete.sh new file mode 100755 index 0000000..41c6e13 --- /dev/null +++ b/testsuite/subst-mb-incomplete.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Ensure that sed no longer writes beyond the end of a heap buffer when +# performing a substitution with a replacement string containing an +# incomplete multi-byte character. + +# Copyright (C) 2015 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 . +. "${srcdir=.}/init.sh"; path_prepend_ ../sed +print_ver_ sed + +require_en_utf8_locale_ + +echo > in || framework_failure_ +printf '\233\375\200\n' > exp-out || framework_failure_ + +fail=0 +LC_ALL=en_US.utf8 sed $(printf 's/^/\\L\233\375\\\200/') in > out 2> err + +compare exp-out out || fail=1 +compare /dev/null err || fail=1 + +Exit $fail -- 2.6.2