Vincent Zheng
Vincent Zheng

Reputation: 122

C - Buffer Overflow Issue

Here is the source code for the program

#include <stdio.h>
% filename: test.c
int main(){
  int local = 0;
  char buff[7];
  printf("Password: ");
  gets(buff);

  if (local)
    printf("Buff: %s, local:%d\n", buff, local);
  return 0;
}

I using "gcc test.c -fno-stack-protector -o test" to compile this file, and when I run the file, in order to make the gets overflow, I need to enter at least 13 characters. The way I think is since I only declare 7 bytes to the buff, which means when user enter at least 8 characters, overflow happened. But seems like not this case, why?

Upvotes: 0

Views: 99

Answers (3)

paxdiablo
paxdiablo

Reputation: 881093

There's no guarantee that the items on your stack will be allocated packed tightly together, in fact I'm pretty certain they're not even guaranteed to be put in the same order.

If you want to understand why it's not failing as you seem to expect, your best bet is to look at the assembler output, with something like gcc -S.

For what it's worth, gcc 4.8.3 under CygWin fails at eight characters as one might expect. It overflows at seven characters but, because the overflowing character is the NUL terminator, that still leaves local as zero.

Bottom line, undefined behaviour is exactly that. It's most annoying feature (to developers) is that it sometimes works, meaning that we sometimes miss it until the code gets out into production. If UB were somehow tied to electrodes connected to the private parts of developers, I guarantee there'd be far fewer bugs :-)

Upvotes: 0

ouah
ouah

Reputation: 145829

The stack layout is implementation dependent.

There is no guarantee that local object will be after or before buff object or that both will be contiguous.

In your case, what is likely is 5-bytes (1 + 4) of padding were inserted after buff object. Such padding is very common and is usually inserted by the compiler for performance reasons. The size of the padding can vary between compilers, compiler versions, compiler options or even from different source codes.

To have a better idea of the layout just print the addresses of both buff and local objects:

printf("%p %p\n", (void *) buff, (void *) local);

Upvotes: 1

Pranit Kothari
Pranit Kothari

Reputation: 9841

gets(buff);

There is no default bound check in C. At the best program will crash, usually it will get unallocated memory, so it just works fine. Even sometime you overrun already used memory, and may not realize it till you get into problem.

Upvotes: 0

Related Questions