0

I wrote this small piece of code based on 'memcpy' man page. I executed it but I did not get any error. Normally, I should get 'seg fault' because I tried to copy a message to small size destination.

char str1[1];
char str2[] = "Big Message";

memcpy(&str1, &str2, strlen(str2));
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Mourad Karim
  • 161
  • 1
  • 1
  • 11

5 Answers5

8

Undefined behavior is undefined. Anything could happen. It could run, crash and burn, take out the internet, crash a car through your wall.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • 2
    [another interesting link](http://blog.regehr.org/archives/213) to understand what undefined behaviour implies – Caninonos Jul 31 '15 at 15:40
  • 1
    If compiler detect undefined behavior. Why It generate executable and not generate a compilation error? – Mourad Karim Jul 31 '15 at 15:55
  • A compiler is not required to throw an error on using undefined behavior. see: http://stackoverflow.com/questions/4417883/why-doesnt-compile-issue-an-error-for-code-that-results-in-undefined-behavior – NathanOliver Jul 31 '15 at 15:56
  • 3
    Because that's what UB means. Compilable code with valid syntax, that will burn everything around you. – Mateusz Grzejek Jul 31 '15 at 15:56
4

Why did you expect to get a "seg fault"?

"Seg fault" is something that happens on some platforms when you attempt to access an address region that's protected by the OS and/or hardware. In your case you memcpy did not run into any such regions.

In fact, getting a "seg fault" in response to such error is a rare and lucky occurrence. Most of the time you will simply quietly destroy your own data located in the adjacent memory region.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

Segfault (thanks to @zneak) means accessing memory in a way that virtual memory won't let you. In most cases, this is due to trying to dereference a NULL pointer.

In this case, you instead have a buffer overrun (which means undefined behavior, which means that it could very well work on your computer and crash and burn on another).

Jashaszun
  • 9,207
  • 3
  • 29
  • 57
  • 6
    Segfault means accessing memory in a way virtual memory will not let you. It isn't necessarily dereferencing the NULL pointer. It could be dereferencing an unmapped address, writing to a read-only location, or executing an unexecutable location. – zneak Jul 31 '15 at 15:37
2

Stepping past the bounds of an array is undefined behavior in C. This means that it is illegal, but the language is not required to do anything specifically if/when it happens.

In other words, if you get a segfault, that's awesome! It'll be easier to debug. But unfortunately, you won't necessarily get one. In your case, you're merely overwriting adjacent memory. C has no runtime information about array bounds, and as such cannot enforce them.

On the Linux system, the stack is allocated as a large, contiguous block of read-write (and sometimes executable) memory. You won't get a segmentation fault unless you write so much data that you pass the bounds of the stack itself.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • "C has no runtime information about array bounds, and as such cannot enforce them." is more like "C does not specify runtime array bounds,", A given implementation _could_ enforce them. – chux - Reinstate Monica Aug 01 '15 at 02:48
2

If you want to check for some illegal memory accesses compile it with -fsanitize=address (at least gcc 4.8 required and libasan must be installed) and you'll get an error report:

==4926==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd1f1a4bf1 at pc 0x7f259efeadc4 bp 0x7ffd1f1a4bc0 sp 0x7ffd1f1a4368
WRITE of size 11 at 0x7ffd1f1a4bf1 thread T0
    #0 0x7f259efeadc3 in __asan_memcpy (/lib64/libasan.so.2+0x8cdc3)
    #1 0x4008c0 in main (/home/m/a.out+0x4008c0)
    #2 0x7f259ebbe78f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #3 0x400728 in _start (/home/m/a.out+0x400728)

Address 0x7ffd1f1a4bf1 is located in stack of thread T0 at offset 33 in frame
    #0 0x400805 in main (/home/m/a.out+0x400805)

  This frame has 2 object(s):
    [32, 33) 'str1' <== Memory access at offset 33 overflows this variable
    [96, 108) 'str2'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow ??:0 __asan_memcpy
4566976
  • 2,419
  • 1
  • 10
  • 14