0

If I try to run this code and give for example "Hello" (more than 3 chars) as an input for scanf, the array str doesn't overflow. This sounds a little bit strange to me, but of course I'm missing something. Does anyone know what's the problem here? Thanks a lot!

char str[3];
scanf("%s", str);
printf("%s\n", str);
10
  • 2
    Overwriting the bounds of your array is undefined behavior. If by "doesn't overflow" you mean "prints out without seg-faulting",, you just got lucky this time. "Hello" can't fit in str, so you are overflowing it. Or really unlucky,, since you will think everything is fine and then your program will crash when you least expect it. Commented Jul 28, 2017 at 23:19
  • 1
    Not really related, but just to note that inputting more than 2 chars would invoke ub. There are a few of runtime tools you can use to catch this kind of error and warning flags won't catch this but are still useful for catching other ub invoking code, such as attempting to read uninitialised variables. Commented Jul 28, 2017 at 23:26
  • 1
    Use 'char str[4096];' and 'sscanf("%4096s",str);'. That should be big enough? Commented Jul 29, 2017 at 0:11
  • 2
    @MartinJames-- that should be scanf("%4095s", str); to leave room for the null terminator. To use sscanf() you need to add another argument for the input string. Commented Jul 29, 2017 at 0:16
  • 3
    Possible duplicate of Why doesn't scanf() generate memory clobbering errors when filling array. Commented Jul 29, 2017 at 11:40

3 Answers 3

2

You said, "the array str doesn't overflow", but how do you know? How did you expect the overflow to manifest itself?

In fact, the array did overflow. You just got "lucky", and there were no (visible) repercussions.

One of the tricky things to understand about computer programming is that enforcement of the rules can be pretty inconsistent. (Computer programming is not unlike life in this regard.) If the signal at the intersection says "Don't Walk", but no cars are coming so you cross the street anyway, how surprised are you if no policeman instantly appears and writes you a ticket for jaywalking? That's basically what happened here.

Sign up to request clarification or add additional context in comments.

Comments

1

I tried to run your code, and it does segfault:

./main 
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue
ofejnhofewnhouwnofwbeqofenoifwenofwenoubwuiowgebouwegfougewfnbnbboue
Segmentation fault (core dumped)

I don't know how many characters you are trying to pass in scanf() but you have to know that sometimes the compiler performs a padding between saved ESP/EIP and the initial variable.

Especially, here, you are creating a memory area of 3 bytes on the stack, the compiler will first round it to 4 (or 8 on x64?). But even then, it might add more space.

In gdb, a disass main gives me:

   0x000000000040057d <+0>: push   %rbp
   0x000000000040057e <+1>: mov    %rsp,%rbp
   0x0000000000400581 <+4>: sub    $0x20,%rsp

sub 0x20 is 32 bytes, obviously way more than 3 bytes.

Do not expect a strict "dummy" C to assembler directives, nowadays the compilers perform a lot of optimizations and decisions than you might be aware of.

Trying to find the exact range of bytes between your buffer and EIP usually requires to perform a brute-force, but a clever hacker might find more interesting approaches... ;-)

1 Comment

Got it. Thank you :)
1

C runtime does not issue an error/warning message but produces incorrect result. To check the Overflow/Underflow is your responsibility.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.