Why not a segmentation fault??

Hi,

Why I don't receive a segmentation fault in the following sample.

int main(void)
{
char buff[10];
sprintf(buff,"Hello world");
printf("%s\n",buff);
}

If I define a buffer of 10 elements and I'm trying to put inside it twelve elements, Should I receive a sigsev signal???

Thanks in advance!

Actually, not quite.
SegFault (in this case) goes when the EIP register point's to a invalid memory address to execute, and just 2 bytes aren't enough to reach the EIP, however try with 500 chars ;), you should get your SegFault.

Hi Zarnick,

So, you mean that when I overwrite the return instruction pointer on the procedure stack I should receive a SegFault, but if I don't reach it I don't? and why not 2 bytes aren't enough??

Sorry, I don't want to be annoying!

Thanks!!

Another reason to use snprintf() instead of sprintf() because sprintf() does not check for bounds.

I wouldn't know for sure why 2 bytes are just not enough, I think it's something to do with the pointers used to allocate the enough memory for your char[10] string. But I can be wrong on this one.

And at least from what I can remember, I never saw a segfault that wasn't about the EIP register being overruned, as always, I can be wrong.

Shamrock -
He is trying to create a SIGSEGV. To test some other code. This corrupts the stack on HPUX PA_RISC boxes, and then dumps core:

#include <stdlib.h>
#include <string.h>

int main()
{
	char buff[10]={0x0};
	char *p=buff;
	p-=20;
    memset(p,0x0, sizeof(buff));
    return 0;	
}

Hi All,

Certainly I'm fixing an application with this type of code and I've replaced the sprintf by snprintf function, but I have to explain to my boss why I'm doing it and I need to show him the application crashing.

The original message in the printf function overcomes the boundaries only for 2 bytes and it doesn't crash, I don't know how to do it and I don't know if its behavior is deterministic or not.

Thanks to all of you for your support!!!!!

Unfortunately the libraries in use may confuse the issue for you.
This code:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>



void handlesegfault(int sig) {
                 printf("Segv detected..exiting.\n");
                 exit(1);
}

int main(void) {
int y = 0;
char x[12];

               signal(SIGSEGV,handlesegfault);
               while (1) {
                         bzero(x,(y++));
                         printf("%s at %d\n",x,y);
               }
}

..never segfaults under linux/*BSD with recent glibc. instead it overwrites the count variable starting over...Sometimes it's better to show that an implementation is wrong theoretically and logically rather than depend on implementations to fail dramatically.

Hi ramen_noodle,

It is a very interesting example. I didn't know this type of glibc "protection". Is there any way to disable this behavior?? perhaps a gcc parameter?

Thanks a lot!

Is there a minimum size of the stack in a C program?
If I have only one variable (type int) in a function, what will be the size of the stack?

I know that it depends on the implementation but, is there an standard size?

Thanks!!!

The stack frame is one page minimum. the pagesize command is found on a lot of machines, try it. If you do not have it you'll have to run something like this:

#include <unistd.h>
int main()
{
     printf("%d\n", getpagesize() );
     return 0;
}

if your system does not have getpagesize(void) you can use sysconf(_SC_PAGESIZE).

Thank you very much!! you know a lot of Linux programming!

Do you think that my problem may be because of the size of the stack??

My problem is in the first post of this thread, and the question is "Why 2 bytes are not enough to get a segmentation fault message ?? "

Thanks again!

In your case SIGSEGV is caused by a stack overflow. The size of each stack frame varies by OS since it is allocated by the processor at runtime. It is not the same as the system pagesize. Max size of a stack frame is determined by the number of bits taken up by the displacement field. On AIX the stu/stwu instruction pushes a frame onto the stack which has 16 (signed) bits allocated giving a max size of 32K. Generate assembly code listing of your C program and figure out which instruction is used to allocate a frame on the stack. If it uses mnemonics like SP (stack pointer) then it might be easy to decode else compiler generated assembly is confusing. Read more about it here

You can also get stack frame size from cc -s myfile.c by address subtraction.
And one some systems the minimum stack frame is one page - you can actually allocate stackframes for pthreads, if you're willing to suffer through it, as well as set the size of the stack and the address of the stack. eg., pthread_attr_setstacksize(), pthread_attr_setstackaddr(), pthread_attr_getstackaddr()....

glibc backtrace() with some programming examples to print the stack frame in C using glibc:
Stack Backtracing Inside Your Program

Thanks!

I was editing the assembly code generated by "gcc -S" and I realized that:

If I define in the main function a buffer as follows

char[8]

the first four lines in the assembly code are:

pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp

but if I change it by

char[9]

I get

pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp

and if I change it by

char[17]

I get

pushl %ebp
movl %esp, %ebp
subl $40, %esp
andl $-16, %esp

and so on.

I think the size of the stack depends on the compiler. Every 8 bytes I request, the compiler allocates 16 more.

It is right??

Please tell me if I'm being stupid!

Thank you very much for your support!

In a way, I'm getting the feeling you are on the wrong track. I mean yes, you have reached useful insights about how a particular version of a particular compiler allocates and manages memory, but if as you were saying a few posts back the driver is that you need to explain to your management why you want to fix insecure code ... I'd be looking for a different employer, or hit them over the head with Smashing the Stack for Fun and Profit by Aleph One

You are right era! I'm going to explain to my boss how to work a stack overflow bug and all its consequences.

Thanks all of you!!

Note that it's not a stack overflow bug but the fact that sprintf() does not check for bounds which causes the routine to overflow its frame.

I mean the program that I'm fixing has a buffer overflow bug, because don't validates the length of string! Thanks a lot for your support!

Let me add sth...
When some object is created say Char arr[MAX].. that is always be the part of some Segment and if the Object is occupying less than 512 bytes
Then its default segment would be of 512 bytes.So for a char arr[10] bytes we can go upto 502 bytes.That is why no segment in the case.