Subject: Re: bug#8683: printf out-of-bounds memory access

From: Pádraig Brady <[email-masked]>
Date: Wed, 18 May 2011 00:55:50 +0100

On 17/05/11 16:54, Pádraig Brady wrote:
> On 17/05/11 16:31, Paul Marinescu wrote:
>> In coreutils 8.12 (latest), printf can make an out-of-bounds access when
>> an integer argument consists only of a single or double quote.

I'll apply the attached fix soon.

thanks again,
Pádraig.
>From 4d8f6b9f5716077bd423b98324547087f485425e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Wed, 18 May 2011 00:01:55 +0100
Subject: [PATCH] printf: fix an out-of-bounds memory access

* src/printf.c (STRTOX): Don't access memory after a
string containing a single quote character.
* tests/misc/printf: Add tests for various combinations
of single quote characters combined with a numeric format.
* THANKS.in: Add bug reporter.
* NEWS: Mention the fix.

Reported-by: Paul Marinescu <[email-masked]>
---
 NEWS              |    5 +++++
 THANKS.in         |    1 +
 src/printf.c      |    2 +-
 tests/misc/printf |   23 +++++++++++++++++++++++
 4 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/NEWS b/NEWS
index 7a7f761..88593ab 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes
+
+  printf '%d' '"' no longer accesses out-of-bounds memory in the diagnostic.
+  [bug introduced in sh-utils-1.16]
+
 ** New features
 
   split accepts a new --filter=CMD option.  With it, split filters output
diff --git a/THANKS.in b/THANKS.in
index 3156834..9120ba3 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -449,6 +449,7 @@ Patrick Mauritz                     [email-masked]
 Paul D. Smith                       [email-masked]
 Paul Ghaleb                         [email-masked]
 Paul Jarc                           [email-masked]
+Paul Marinescu                      [email-masked]
 Paul Nevai                          [email-masked]
 Paul Sauer                          [email-masked]
 Paul Slootman                       [email-masked]
diff --git a/src/printf.c b/src/printf.c
index e05947c..24070b8 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -160,7 +160,7 @@ FUNC_NAME (char const *s)						 \
   char *end;								 \
   TYPE val;								 \
                                                                          \
-  if (*s == '\"' || *s == '\'')						 \
+  if ((*s == '\"' || *s == '\'') && *(s + 1))				 \
     {									 \
       unsigned char ch = *++s;						 \
       val = ch;								 \
diff --git a/tests/misc/printf b/tests/misc/printf
index 6404761..8f5f7d4 100755
--- a/tests/misc/printf
+++ b/tests/misc/printf
@@ -96,4 +96,27 @@ EOF
 
 compare out exp || fail=1
 
+# Verify handling of single quote chars
+
+"$prog" '%d\n' '"a'  >out 2>err   # valid
+"$prog" '%d\n' '"a"' >>out 2>>err # invalid
+"$prog" '%d\n' '"'   >>out 2>>err # invalid
+"$prog" '%d\n' 'a'   >>out 2>>err # invalid
+
+cat <<EOF > exp
+97
+97
+0
+0
+EOF
+
+cat <<EOF > exp_err
+$prog: warning: ": character(s) following character constant have been ignored
+$prog: ": expected a numeric value
+$prog: a: expected a numeric value
+EOF
+
+compare out exp || fail=1
+compare err exp_err || fail=1
+
 Exit $fail
-- 
1.7.4