-2

I have a hard time to understand why the below code is not resulting in a bufferoverflow and instead some how seems to resize the char example from 1 to 16.

I checked the snprintf documentation but nothing to be found about this.

//set char example size 1
char example[1];

//set example to args->arg2 which is a 15 character + 1 null byte.
//trying to put something to big into something too small, in my mind causing not a resize but a bof.

snprintf(example, 16, "%s", args->arg2); 

fprintf(stdout,"[%s],example);

The fprintf in the end does not display 1 character nor does char example overflows but instead it seems to be resized and displays the full string of 16.

What am i misunderstanding here ?

9
  • 4
    Undefined behavior is undefined. Commented Apr 19, 2019 at 2:35
  • GCC adds optimization code to mitigate buffer overflow attacks. You could try turning off optimization or use TCC (Tiny C Compiler). Commented Apr 19, 2019 at 2:36
  • 3
    Then your understanding of undefined behavior is incorrect. Commented Apr 19, 2019 at 2:38
  • 1
    The compiler corrects nothing. If you use a compiler that detects overruns on the stack then it would exit with that message. If you add more data on the stack it may change the behavior. If you run it on Tuesday it may change the behavior. It is simply incorrect code with an undefined result because of that. Commented Apr 19, 2019 at 2:43
  • 1
    My GCC refuses to compile with -O3 -Wall -Wextra -Werror, with error: ‘_builtin__snprintf_chk’: specified bound 16 exceeds the size 1 of the destination [-Werror=stringop-overflow=]. This too is allowed by the standard. Commented Apr 19, 2019 at 5:27

1 Answer 1

1

Your array is not resized. Instead what happens is that there is some memory following it (in fact it's your call stack, which is why overruns like this are dangerous), and snprintf 'trusts' you and writes into that memory. fprintf after that happily reads whatever snprintf wrote there.

It works for you now, but it is undefined behavior, which means that, sooner or later, it will break.

Sign up to request clarification or add additional context in comments.

4 Comments

so basically when the string snprintf is trying to write into the char example and it doesnt fit it will not stop writing but continues in the stackmemory (an overflow), i can understand that. but still i'm not understanding how the fprintf displays not only the 1 byte from memory but the full string if the array is not resized according to your answer.
@Jefke22: fprintf reads till it finds a zero byte. It doesn't know the size of the array, and it cannot, because after compilation the size of the array is 'lost'.
Well this last answer explains everything for me !! basically snprintf writes the string into the first byte (char example[1]) then because it trusts me it continues to overflow and write along in the stackmemory. after that the printf just starts reading where the char example[1] byte is until it finds a null byte and stops.
@Jefke22: It's not 'defined'` It can only be explained. (After all computers are deterministic machines). Undefined means that there's nothing in the contract between you and the compiler that defines that behavior, therefore it can change, break, or do absolutely everything unexpected.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.