Consider the following code for Linux:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int staticvar; const int constvar = 0; int main(void) { int stackvar; char buf[200]; int *p; p = malloc(sizeof(int)); sprintf(buf, "cat /proc/%d/maps", getpid()); system(buf); printf("&staticvar=%p\n", &staticvar); printf("&constvar=%p\n", &constvar); printf("&stackvar=%p\n", &stackvar); printf("p=%p\n", p); printf("undefined behaviour: &p[500]=%p\n", &p[500]); printf("undefined behaviour: &p[50000000]=%p\n", &p[50000000]); p[500] = 999999; //undefined behaviour printf("undefined behaviour: p[500]=%d\n", p[500]); return 0; }
It prints a process memory card and addresses some types of memory.
[ osboxes@osboxes ~]$ gcc tmp.c -g -static -Wall -Wextra -m32 [ osboxes@osboxes ~]$ ./a.out 08048000-080ef000 r-xp 00000000 fd:00 919429 /home/osboxes/a.out 080ef000-080f2000 rw-p 000a6000 fd:00 919429 /home/osboxes/a.out 080f2000-080f3000 rw-p 00000000 00:00 0 0824d000-0826f000 rw-p 00000000 00:00 0 [heap] f779c000-f779e000 r--p 00000000 00:00 0 [vvar] f779e000-f779f000 r-xp 00000000 00:00 0 [vdso] ffe4a000-ffe6b000 rw-p 00000000 00:00 0 [stack] &staticvar=0x80f23a0 &constvar=0x80c2fcc &stackvar=0xffe69b88 p=0x824e2a0 undefined behaviour: &p[500]=0x824ea70 undefined behaviour: &p[50000000]=0x1410a4a0 undefined behaviour: p[500]=999999
Or why is this address in p [500] even writable?
The heap from 0824d000-0826f000 and & p [500] is randomly 0x824ea70, so the memory can be written and read, but this memory area can contain real data that will be changed! In the case of the exemplary program, most likely, it is not used, so writing to this memory is not harmful to the process.
& p [50000000] randomly equals 0x1410a4a0, which is not on the page that the kernel maps to the process, and therefore is unacceptable and unreadable, therefore, seg fails.
If you compile it with -fsanitize=address , memory accesses will be checked, and many, but not all illegal memory accesses will be reported by AddressSanitizer , Slowing is about two times slower than without AddressSanitizer.
[ osboxes@osboxes ~]$ gcc tmp.c -g -Wall -Wextra -m32 -fsanitize=address [ osboxes@osboxes ~]$ ./a.out [...] undefined behaviour: &p[500]=0xf5c00fc0 undefined behaviour: &p[50000000]=0x1abc9f0 ================================================================= ==2845==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf5c00fc0 at pc 0x8048972 bp 0xfff44568 sp 0xfff44558 WRITE of size 4 at 0xf5c00fc0 thread T0
If so, does this mean that there are pages that are dedicated to your code / instruction / text segments and are marked as unregistered, completely separate from your pages, on which your stack / variables are located (where things change) and are marked as writable?
Yes, see the output of the process memory card above. r-xp means readable and executable, rw-p means readable and writable.