2

I've already read a somewhat similar question (why this code works in C) but it doesn't actually gets to explain why is this piece of code actually working:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct example
{
    char length[2];
} STRUCT;

int main (void)
{
    STRUCT test;
    strcpy(test.length, "********");
    puts(test.length);
    return 0;
}

I'm using CodeBlocks to compile it, so I guess it is allocating more space in my string to store the extra asterisks by default... I really don't know. Maybe I'm just lucky, but everytime I run it it works.

In the example (link) I showed above he put 2 elements in an array of 2, here I'm using a lot of more space than the string can handle, or could.

Community
  • 1
  • 1
matt_s
  • 25
  • 3
  • 1
    http://en.wikipedia.org/wiki/Buffer_overflow and yes, you are lucky. Writing outside of the bounds of what you've allocated is undefined behavior and could cause any issues ranging from absolutely none all the way to crashing your OS (or probably worse) – Ricky Mutschlechner Jul 23 '14 at 18:08
  • 4
    The program exhibits [*undefined behavior*](http://en.wikipedia.org/wiki/Undefined_behavior) and is ill-formed. It's just luck that gets it to run, luck and [nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html). – Some programmer dude Jul 23 '14 at 18:10
  • 1
    welcome to the world of undefined behavior. This is the worst kind of undefined behavior - the code works. It will work for years until something truly nasty will happen; sometimes ending up on CNN or slashdot – pm100 Jul 23 '14 at 18:11
  • "Why does this work?" is usually not a valid question in C. If something that shouldn't work appears to work, that's probably a symptom of undefined behavior, which really needs no explanation unless you're looking for a way to exploit it as a security vulnerability. Otherwise, just avoid doing it. – R.. GitHub STOP HELPING ICE Jul 23 '14 at 18:28
  • the STRUCT is implemented on the stack. Overrunning the end of the length item means data is being written to the bytes on the stack following the place where the struct is allocated. This means the stack frame is corrupted, amongst other things. Since nothing else is being put on the stack in the called function (hopefully, depends on the compiler) it runs, however, it is a bomb waiting to explode. – user3629249 Jul 24 '14 at 05:42

6 Answers6

3

C doesn't check for array boundaries. it leads to buffer overflows and undefined behavior as Ricky Mutschlechner stated in comment.

macfij
  • 3,093
  • 1
  • 19
  • 24
1

This is an example of undefined behavior (as people have mentioned in the comments).

As to why specifically this works, it's more than likely due to stack alignment. So, when you declare STRUCT test, even though it only requires two bytes on the stack, the compiler will align the stack down (via adding extra padding to the structure), so you get extra unused space after test, which strcpy writes into. Because no other part of the program uses this space, it gives the illusion of working without problems.

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57
1

You are just lucky.

The struct is only declared to be two bytes long, but the compiler or the run time may either allocate more or just not care about the memory locations after the struct -- the fact is that the strcpy will override the memory after the struct, and it will eventually, if used in a larger context, override some memory which will be critical for something else and it will create a catastrophic error depending on what type of memory you have overridden and what it was used for.

In your case the program just exit, so the chance (by luck) is that nobody will use the memory which you have corrupted.

Soren
  • 14,402
  • 4
  • 41
  • 67
0

It works because the written to (but not allocated) memory is not used by other parts of this application. I do not know the details how memory allocation works and in how big chunks. Just search for more detail.

It will not crash an OS but will cause a segmentation fault at its worst.

nvd
  • 2,995
  • 28
  • 16
0

It is just overflowing your stack , since test is on stack. For now it might not be any causing any problem , but if you declare some more variables on stack along with test , that might cause some problems

bsguru
  • 432
  • 4
  • 21
0

You are writing in the stack memory which is situated after test.length. To illustrate the problem better, I added two lines to your code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct example
{
    char length[2];
} STRUCT;

int main (void)
{
    STRUCT test;
    unsigned int foo = 42;
    strcpy(test.length, "********");
    puts(test.length);
    printf("%u", foo);
    return 0;
}

You would expect the printf to print 42, but the variable foo gets overwritten by the strcpy. The real output is, for instance on gcc, the following (you can test it here):

********
707406378
Étienne
  • 4,773
  • 2
  • 33
  • 58