CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Mar 2009
    Posts
    166

    Windows strcpy overflow question

    Hello,

    I have the following code:

    char buf[5];
    strcpy(buf, "12345678");


    When I run this from the IDE in Release mode, it works fine, no crashes. However, when I change "12345678" to "123456789" then I get this compilation warning:

    warning C4789: destination of memory copy is too small

    And also it crashes when i run it.

    Can anyone explain why this is inconsistent, or what I am misunderstand?

    Regards,
    EK
    Last edited by ekhule; January 15th, 2013 at 10:18 AM.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Windows strcpy overflow question

    Quote Originally Posted by ekhule
    my guess is that it is also copying the null terminator?
    The standard behaviour of memcpy involves copying the null terminator.

    Quote Originally Posted by ekhule
    Can anyone explain why this is inconsistent, or what I am misunderstand?
    You are in the realm of undefined behaviour. Don't do this, then you don't have to misunderstand.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Windows strcpy overflow question

    Your definition of buffer
    Code:
    char buffer[5];
    allocates space for 4 characters plus the terminating null character (0). Therefore the maximum length of a string that should be copied to buffer is 4. Standard strcpy (as far as I am aware) copies starting from the memory location pointed by the source pointer to the memory location pointed by the destination pointer. This copy continues character by character until a null character is found in the source. strcpy does not know how much memory has been allocated for the destination and continues copying beyond the end of the allocated destination memory if a null has not been found in the source. Effectively strcpy performs

    Code:
    while (*d++ = *s++);
    In your case all your inputs including "12345" have too many characters to be copied correctly and safely to the destination (buffer - maximum number 4 plus the terminating null). Input of "1234" is OK but "12345" is not.

    Code:
    char buffer[5];
    strcpy(buffer, argv[1]);
    
    char buffer[5];
    strcpy(buffer, "12345678");
    When copying exceeds the memory allocated it overwrites whatever happens to be in memory following buffer. This could be other data, code etc. This is a prime example of what is called 'buffer overflow' where the contents of a buffer has 'overflowed' into adjacent memory. This is a prime source of security issues allowing unauthorised code to be executed by carefully crafted input.

    To make sure that buffer overflow does not occur, the new string safe functions should be used. These are the StringCch functions . If you must use the unsafe strcpy, strcat, gets etc functions then you need to make sure that the memory allocated for the destination is large enough to hold what is going to be copied to it.

    In your case you are probably overwriting code so that is why your program is crashing.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Windows strcpy overflow question

    Quote Originally Posted by ekhule View Post
    Can anyone explain why this is inconsistent, or what I am misunderstand?
    Here is what you're misunderstanding: you're using C++.

    When you overwrite memory like this in C++, there is no guarantee how your program will behave. Unlike other computer languages, with C++ (and C) you do not get an automatic "crash" or "message box" or some other error indicator when you do these "tricks" at runtime.

    You can do all sorts of illegal (but compilable) things in C++, and all seems to work -- until you try to run that program somewhere else, or you run the program at a different time of day, or you run that program on a customer's machine, or you change a couple of lines of code that are totally benign, but the program then crashes.

    Haven't you heard of programs that run perfectly in-house, and then when you go take that program to the customer site, things crash? It's situations just like this that causes those issues.

    C++ has something called undefined behaviour, meaning exactly that -- you write code that does something that isn't defined as to what will happen, and guess what? You don't know what will happen.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 14th, 2013 at 04:12 PM.

  5. #5
    Join Date
    Jan 2013
    Posts
    2

    Re: Windows strcpy overflow question

    I can stick a knife in the toaster and there is a chance I won't have to go to hospital...

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Windows strcpy overflow question

    Quote Originally Posted by 2kaud View Post
    To make sure that buffer overflow does not occur, the new string safe functions should be used. These are the StringCch functions . [...]
    Right, however, this is Win32 API. To avoid dependency on Win32, strcpy_s() from the C++ runtime library can be used as an alternative. It's still MS-specific (AFAIK), however.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Windows strcpy overflow question

    I'm assuming that you're asking this question to understand legacy C code.

    As you are using C++, the equivelent code in your first example would be.

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        string buffer(argv[1]);
        cout << "buffer content= " << buffer << "\n";
        cout << "String constructor executed\n";
    }
    No buffer overruns are possible.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  8. #8
    Join Date
    Jan 2013
    Posts
    2

    Re: Windows strcpy overflow question

    Quote Originally Posted by Eri523 View Post
    Right, however, this is Win32 API. To avoid dependency on Win32, strcpy_s() from the C++ runtime library can be used as an alternative. It's still MS-specific (AFAIK), however.
    Yes, it's an MS-specific recommendation that never made it to the new C11 standard. The C standard has had strncpy for years. Use that, if you desire fixed length fields... Just be aware that unlike the non-portable strcpy_s, strncpy might not append a null terminator to the end of your string. If you want that guarantee, end your fixed length field one byte earlier and put the terminator there yourself.

    Code:
    #include <string.h>
    int main(void) {
        char fubar[6];
        strncpy(fubar, "hello world", sizeof (fubar) - 1);
        fubar[sizeof (fubar) - 1] = '\0';
        printf("fubar contains: %s\n", fubar);
        return 0;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured