-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 ?

Jefke22
  • 21
  • 5
  • 4
    Undefined behavior is undefined. – Retired Ninja Apr 19 '19 at 02:35
  • GCC adds optimization code to mitigate buffer overflow attacks. You could try turning off optimization or use TCC (Tiny C Compiler). – simptri Apr 19 '19 at 02:36
  • Yes but even if i set the char example size to 1, 2, 3, 4 you name it. In the end it still displays the full 15 character string. Constantly so that is not undefined behaviour to me ?! – Jefke22 Apr 19 '19 at 02:37
  • @simptri well i also thought for a second the compiled might autoadjust the char size.. i dont want to simulate a bufferoverflow but just understnad in my mind why the to me above bad looking code is still resulting in the right result time over time :-) – Jefke22 Apr 19 '19 at 02:38
  • 3
    Then your understanding of undefined behavior is incorrect. – Retired Ninja Apr 19 '19 at 02:38
  • @RetiredNinja probably but really no other cause for this constant right result ? looks like simptri his answer makes more sense to me. somehow the compiler prevents and correct this "bad behaviour" – Jefke22 Apr 19 '19 at 02:39
  • https://stackoverflow.com/questions/23226217/why-buffer-overflow-doesnt-affect-to-this-code/23226252#23226252 – Retired Ninja Apr 19 '19 at 02:41
  • 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. – Retired Ninja Apr 19 '19 at 02: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. – Antti Haapala -- Слава Україні Apr 19 '19 at 05:27

1 Answers1

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.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • 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 Apr 19 '19 at 02:44
  • @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'. – Yakov Galka Apr 19 '19 at 02:46
  • 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 Apr 19 '19 at 02:50
  • 2
    @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. – Yakov Galka Apr 19 '19 at 02:55