-1
char string[5] = "stringBiggerThan5";   // shows error. Okay.
strcpy(string, "big string");   // overflow. seg fault. Perfect!

But, adding a string to a char[], which is bigger than the array size, doesn't show any error:

char string[5];
strcat(string, "stringBiggerThan5");   // no error. Why??!

Again, no error:

char* simple_string_func() {
  static char string[5];
  strcpy(string, "hugeBigString");
  strcat(string, "tryingToOverflowYou");
  
  return string;    //returns all perfectly, without errors
}

Do notice that, doing bigger strcpy to static char[5] doesn't show overflow error or segementation fault now! Why?


Please do openly comment, if my approach to assigning strings for return in function is ideal/okay.

midnqp
  • 29
  • 1
  • 10
  • 1
    C have no bound checking. It's your responsibility as a programmer to make sure such things (which leads to *undefined behavior*) does not happen. – Some programmer dude Jan 17 '21 at 16:37
  • @Someprogrammerdude Adding & copying strings to `const char*` didn't lead to undefined behavior. However, doing `strcat` without `strcpy` first to a `static char*` lead to undefined behavior, while returning from a function. – midnqp Jan 17 '21 at 16:41
  • 1
    `char string[5];` has not been initialised, so `strcat()` is undefined behaviour no matter how big it is. – Weather Vane Jan 17 '21 at 16:42
  • 1
    I get waring from gcc ` warning: ‘__builtin_memcpy’ writing 14 bytes into a region of size 5 overflows the destination [-Wstringop-overflow=]` – Ôrel Jan 17 '21 at 16:47
  • @WeatherVane Okay, but `strcat` & `strcpy` just gets the work done swiftly. Can you tell me, if they yield to potential threats, or big issues/traps that I'll need to hunt down in the future? – midnqp Jan 17 '21 at 16:48
  • 1
    Buffer overflows (writing beyond the end of arrays) is an old and classic attack vector to exploit. One of the reasons e.g. [`gets` is so dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) that it was removed from C in the C11 standard. – Some programmer dude Jan 17 '21 at 16:54
  • The potential threat is always buffer overflow. – Weather Vane Jan 17 '21 at 16:54
  • Please tell me, what is the safest/ideal way to allocate memory for a might-get-huge variable? `char* fileContent = malloc(1000000);` or `char* fileContent[1000000];` or `any other way`. To me, both the cases seem like memory leaking. – midnqp Jan 18 '21 at 06:15
  • Just an idea, can I just allocate as much as I want (like 1 MB), and then `free();` when I see it's no longer required? If you have a better approach to memory allocation please add to the Answers. Please don't just give me a link to some other StackOverFlow questions, recursively. – midnqp Jan 18 '21 at 06:17

2 Answers2

0

The difference is between compile-time checks, which you saw, and run-time checks, which C doesn’t have.

I’d suggest you have another think about what you’re trying to do, focusing on the memory needed to hold the strings and where it comes from. Things are simpler if there are no threads involved, but your routines will currently have issues if they’re called twice, for instance.

Gwyn Evans
  • 1,361
  • 7
  • 17
0

Still the buffer overflow happens and undefined-behavior invokes when you try to put a larger character array than its given size. You will get an error during compilation with -O2 compiler flag (the last two lines clearly summarizes everything):

In file included from /usr/include/string.h:495,
                 from main.c:2:
In function ‘strcat’,
    inlined from ‘simple_string_func’ at main.c:6:3:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:128:10: warning: ‘__builtin___strcat_chk’ writing 14 bytes into a region of size 5 overflows the destination [-Wstringop-overflow=]
  128 |   return __builtin___strcat_chk (__dest, __src, __bos (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In function ‘strcat’,
    inlined from ‘simple_string_func’ at main.c:6:3,
    inlined from ‘main’ at main.c:12:24:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:128:10: warning: ‘__builtin___strcat_chk’ writing 14 bytes into a region of size 5 overflows the destination [-Wstringop-overflow=]
  128 |   return __builtin___strcat_chk (__dest, __src, __bos (__dest));
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*** buffer overflow detected ***: terminated
Aborted (core dumped)

strcat(3) documentation says:

The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte. The strings may not overlap, and the dest string must have enough space for the result. If dest is not large enough, program behavior is unpredictable.

You can clearly see the overflow with optimization level 2, even with static char[] live here.


Note that the attached compilation output was generated by gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • For `static char[5]`, despite the buffer overflow(by `-O2`), things just worked out swift. But for `char[5]`, it loudly showed `segmentation fault`. Please tell me, what's the default for only `char[5]`? Why it works for `static`? – midnqp Jan 17 '21 at 17:09
  • If buffer overflow is such a huge bug and a nasty thing, why does it work? That's my question. How am I being able to `strcat` beyond capacity, that's my question. – midnqp Jan 18 '21 at 06:02
  • @q-codes the compiler (at least MingW gcc) won't treat a warning like this as an error neither will it display any message and clearly show nothing, meaning successful compilation (if you're not in mood to use optimization or pedantic flags) – the compiler thinks the programmer has taken care of it. But on actual execution, UB is invoked. – Rohan Bari Jan 18 '21 at 10:44
  • Now, when I add strings beyond `char[] array size` allocation, does gcc automatically allocates the extra space to fit the concatenation? – midnqp Jan 18 '21 at 14:44
  • can you please also answer my last comments of the question? It'd be really cool. Because I desperately need the answers. – midnqp Jan 18 '21 at 14:47
  • @q-codes `strcat(flag, buffer)` will search for the null terminator, which will be outside the array, and then append buffer after that as mentioned in the documentation of [`strcat(3)`](https://man7.org/linux/man-pages/man3/strcat.3.html). So, this clearly causes a buffer overflow when writing. – Rohan Bari Jan 18 '21 at 16:18