delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/12/11/12:14:15

Sender: rich AT phekda DOT freeserve DOT co DOT uk
Message-ID: <3DF76AAD.DC2F0E0A@phekda.freeserve.co.uk>
Date: Wed, 11 Dec 2002 16:41:17 +0000
From: Richard Dawe <rich AT phekda DOT freeserve DOT co DOT uk>
X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.23 i586)
X-Accept-Language: de,fr
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: scanf buffer overflow; support 'hh' conversion specifier [PATCH]
References: <Pine DOT SUN DOT 3 DOT 91 DOT 1021211162528 DOT 6492C-100000 AT is>
Reply-To: djgpp-workers AT delorie DOT com

Hello.

Eli Zaretskii wrote:
>
> Richard Dawe wrote:
[snip]
> > "The conversion specifiers A, E, F, G, and X are also valid and behave the
> > same as, respectively, a, e, f, g, and x."
> >
> > So we can't treat X as some Borland special-case, if we want to comply
> > with the C standard.
> 
> Oh, yes we can: if the result is the same, the users won't notice.
> 
> Do you see any difference between what v2.03 does with X and what C99
> says it should?

Yes:

2.03: Ignores the 'h' conversion width specifier and treats it like 'l', but
honours 'll'. This causes a buffer overflow (memory corruption) problem when
the width is less than 32b short). Note that the problem would also occur if
2.03 supported the 'hh' conversion width specifier for chars.

C99: X should behave like x. Should honour conversion width specifiers.

The 2.03-behaviour is caused by this code to handle captial type specifiers
(D, etc.) from src/libc/ansi/stdio/doscan.c:102-115:

/* The following if clause is an extension of ANSI/Posix spec: it
   allows to use %D, %U, %I etc. to store value in a long (rather
   than an int) and %lD, %lU etc. to store value in a long long.
   This extension is supported by some compilers (e.g. Borland C).
   Old pre-ANSI compilers, such as Turbo C 2.0, also interpreted
   %E, %F and %G to store in a double (rather than a float), but
   this contradicts the ANSI Standard, so we don't support it.  */
if (ch == 'd' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'x')
{
  if (size==LONG && ch != 'x') /* ANSI: %lX is long, not long long */
    size = LONGDOUBLE;
  else if (size != LONGDOUBLE)
    size = LONG;
}

2.03 & %hX: size == SHORT => size == LONG after this code -> memory
corruption. (Something similar would happen for %hhX, if 2.03 supported it.)

Bye, Rich =]

-- 
Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ]

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019