This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: Integer overflow in functions from scanf() family in MinGW, Cygwin, Borland/Embarcadero C environments (Windows)
- From: Brian Inglis <Brian dot Inglis at SystematicSw dot ab dot ca>
- To: cygwin at cygwin dot com
- Date: Sun, 5 Mar 2017 15:50:59 -0700
- Subject: Re: Integer overflow in functions from scanf() family in MinGW, Cygwin, Borland/Embarcadero C environments (Windows)
- Authentication-results: sourceware.org; auth=none
- References: <001101d295e9$65841800$308c4800$@gmail.com>
- Reply-to: Brian dot Inglis at SystematicSw dot ab dot ca
On 2017-03-05 12:48, Lukas' Home Page wrote:
> I find out a strange and bad beaviour in functions from scanf() family when
> reading one-byte int variable in MinGW, Cygwin and Borland/Embarcadero C
> environments (on Windows, on Linux this doesn't happen). This bug is
> corelated with MSVCRT library which isn't written in C99 standard (it's
> written in C89 i think).
> So, the point is, when you're reading one byte using scanf() function, AND
> you are using %hhu format specifier, you have Integer Overflow bug in your
> code, because MinGW links to old MSVCRT (C89 version) even if you compile
> with -std=c99 parameter.
> This works, because scanf() in old MSVCRT library doesn't know "h" format
> specifier. BUT! The problem is, that scanf try to interpret format specifier
> anyway, omits unsupported "h" specifier and it's loading full integer ("u")
> to memory (it should omit not supported part of format - whole "%hhu" format
> part, not just only "h"). The C99 specification says on 361 page: "If a
> conversion specification is invalid, the behavior is undefined." - but it is
> WRONG, because the behaviour SHOULD BE DEFINED AS OMITING THE WHOLE
> UNSUPPORTED PART OF FORMAT (not only single specifier, but whole part).
Dealing safely with anything other than int, double, and width limited strings
using scanf requires a lot of care, by the implementation and the developer.
Undefined behaviour puts the onus on you as a developer to avoid invoking
whatever behaviour the implementation defaults to.
I can suggest looking into the inttypes.h SCNu* macros and stdint.h.
Options -Wall and -Wextra should produce format warnings.
Cygwin uses newlib and Mingw may use its own scanf library.
Cygwin provides a Mingw port, so any problems should be reported upstream.
> In exploit (below), compiler doesn't even display warnings (event if you
> compile program with -std=c99 and -Wextra parameters). I compile on Windows
> 7 using that command:
> gcc main.c -o main.exe -Wextra
> #include <stdio.h>
> #include <stdbool.h>
> typedef volatile unsigned char uint8_t;
> int main()
> {
> bool allowAccess = false; // allowAccess should be always FALSE
> uint8_t userNumber;
> char format[] = "%hhu";
> char buffer[] = "257\n";
> sscanf(buffer, format, &userNumber);
> if (allowAccess)
> {
> printf("Access granted: secret information - Lech Walesa was a Bolek
> agent\n");
> }
> printf("Entered number is: %d\n", userNumber);
> return 0;
> }
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple