Incorrect read / write sometimes creates a segmentation error, and sometimes not

Code example:

int main () { char b[] = {"abcd"}; char *c = NULL; printf("\nsize: %d\n",sizeof(b)); c = (char *)malloc(sizeof(char) * 3); memcpy(c,b,10); // here invalid read and invalid write printf("\nb: %s\n",b); printf("\nc: %s\n",c); return 0; } 

See in the code. I made some invalid reads and invalid entries, but this small program works fine and does not create core dump .

But once in my large library, when I make 1 byte of invalid read or invalid write, it always created a core dump.

Question:

Why do I sometimes get a core dump from an invalid read / write and sometimes I don't get a kernel dump?

+2
source share
3 answers

What you are trying to do is buffer overflow and in your sample code more heap overflow . The reason you see a failure only occasionally depends on the area of ​​memory that you are accessing, and if you have permission to access her / her recording (which was well explained by Dan Fego). I think the example provided by Dan Fego is more about stack overflow (patch is welcome!). gcc has protection related to buffer overflows on the stack (stack splitting). You can see this (stack overflow) in the following example:

 #include <stdio.h> #include <string.h> int main (void) { char b[] = { "abcdefghijk"}; char c [8]; memcpy (c, b, sizeof c + 1); // here invalid read and invalid write printf ("\nsize: %d\n", sizeof b); printf ("\nc: %s\n", c); return 0; } 

Output Example:

 $ ./a.out size: 12 c: abcdefghi    *** stack smashing detected ***: ./a.out terminated 

This protection can be disabled using the -fno-stack-protector option in gcc.
Buffer overflows are one of the main causes of a security vulnerability. Unfortunately, a function like memcpy does not check for these problems, but there are ways to protect against these problems.
Hope this helps!

+5
source

It totally depends on what you rewrite or act out when you do an invalid read / write. In particular, if you rewrite some pointer that is dereferenced, for example, say the most significant byte of one of them, you could get something dereferenced in a completely different (and completely invalid) memory area.

So, for example, if the stack was arranged in such a way that memcpy overwrites part b end of c , when you try to call printf() with b as an argument, it tries to take this pointer and look for it to print the line. Since this is no longer a valid pointer, this will call segfault. But since things like stacking depend on the platform (and possibly the compiler?), You cannot see the same behavior with similar examples in different programs.

+6
source

you create a string <char c , but copy 10 characters to it. this is mistake.

it is called bufferoverflow: you write in memory that does not belong to you. therefore the behavior is undefined. it may be a failure, it may work fine, or it may change another variable you created.

so the point is to allocate enough memory for c to contain the contents of b:

 c = (char *)malloc(sizeof(char) * (sizeof(b)+1)); // +1 is for the '\0' char that ends every string in c. 

2 - when copying b to c do not forget to end the line char: '\0' . it is mandatory in standard c. therefore printf("%s",c); knows where to end the line.

3 - you copied 10 characters from b to c , but b contained only 5 characters (a, b, c, d and '\ 0'), so the behavior of memcpy is undefined (for example: memcpy may try to read memory that cannot be read ...).

You can only copy your existing memory: 5 characters b .

4 - I think a good instruction to define b : char b="abcd"; or char b={'a','b','c','d',0};

0
source

Source: https://habr.com/ru/post/1388854/


All Articles