Click here to Skip to main content
15,116,815 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,

I have some simple question. The code below is
vulnerable to buffer overflow right? When I execute it
with large string (>20) I get segmentation fault
1. char dest[20];
2. char * p = new char[100];
3. cin>>p;
4. cout<<endl<<p;
5. strcpy(dest,p);
6. return 0;

My question is (and strange thing happens) if I replace line 1 with
char *dest = new char [20];
then everything seems to work fine, even content of p gets printed
even if I enter large string (e.g., 50 characters).
Just curious what is happening in this case. Apparently strcpy still overwrote
the large string to dest -- and no segmentation fault heppened.why?


Don't rely on it. The new instruction moves the data from the stack to the heap - when you declare it as char dest[20] it is a local array, so it goes on the stack. When you use the strcpy, it overwrites the end of your array, and then starts to write over the return address from strcpy. So when strcpy tries to return having finished copying, the address is no longer valid, and you get an error.

When you replace it with new it allocates the new array on the heap, not the stack, so despite it overwriting data it does not affect the strcpy return address so the fault is not noticed. Yet.

Always check your dimensions!
nv3 29-Oct-12 7:50am
Couldn't have said it better. +5
[no name] 29-Oct-12 9:56am
Hi thanks. One more question: why is strncpy(dest, src, size) considered a secure
alternative of strcpy??
I can still break it - for example, by specifying in "size" variable a value which is bigger than the size of "dest" buffer isn't it?? e.g., in my example above: strncpy(dest, p,300);
OriginalGriff 29-Oct-12 10:33am
It's considered safer because it does limit the damage it can do - without the length parameter, it keeps on copying until it meets a null byte. This could be a long way off if you feed it the wrong string!
Normally, you feed it the length of the destination string, so it can't do any damage even if you do loose the terminating null in the source.
[no name] 29-Oct-12 12:10pm
Hi thanks for your reply. Yes, just calling strncpy(dest, p,300);
still breaks the code I wrote in the initial code with segmentation fault.
Because compiler still does not know that dest can't contain 300 characters.
OriginalGriff 29-Oct-12 12:56pm
Not because the compiler doesn't know - it does - but because it doesn't know what strncpy does. All it knows is that it needs two pointer and an integer - it has no idea what it does with them! :laugh:
In your first case dest is allocated on the stack in in the second case it is allocated on the heap.

When both strings are on the heap, you have a memory image like this:
dest: at some address
p:    at dest + 20 + alignment (4 with 8 byte alignment) + heap info

If you now copy more than 20 characters including the NULL byte to dest, this will overflow into p (strcpy can't handle copying of overlapping memory but in this case it will work). Printing now dest will show the full string while printing p will show only the end of the string. The heap at p is corrupted. But you will not recognize this when not using p anymore.

The organization of stack memory is different from the heap memory: It uses memory in a reverse direction (starting at the initial size subtracting the size of the required memory). So the memory image looks like this (highest addresses first):
current stack top at some address
dest: top - 20

When now copying more than 20 bytes to dest, this will overwrite the stack content on top. On the stack are other local variables, function parameters, and the return addresses of functions. In your case the return address of some function is most likely overwritten resulting in the access violation.

So the difference is between corrupted stack and heap memory where the stack corruption is much more dangerous because it effects program execution while heap memory mainly contains data (which may also lead to access violations when the memory contains pointers).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900