Dagoth Ulen
Dagoth Ulen

Reputation: 520

Why is gets() more dangerous than scanf()?

It seems to me that both have the potential to overflow the buffer. Yet I'm adviced to never use gets() but still encouraged to use scanf().

Is it just because of the formatting arguments allowed in scanf() or is there any other reason?

Upvotes: 6

Views: 1498

Answers (6)

greydet
greydet

Reputation: 5539

The gets function is not protected against buffer overflows.

With the scanf format string you can define the maximal length of the string to read from standard input and store in the given memory buffer. For example with scanf("%10s\n", str); a maximum of 10 characters will be read. The str buffer should be of 11 bytes to store the NULL terminating character.

Performance wise, if you only use scanf to workaround the buffer overflow issues of gets, prefer using the fgets function instead.

Upvotes: 10

Deepu
Deepu

Reputation: 7610

The nominal task of gets() is to read in a string from a stream. The caller tells it where to put the incoming characters. But gets() does not check the buffer space. If the caller provides a pointer to the stack, and more input than buffer space, gets() will overwrite the stack. Most systems are vulnerable to overwriting an existing entry in the middle of the stack with something bigger, that also overwrites neighboring entries. A malefactor can amend the return address in the procedure activation record on the stack by stashing the right binary patterns in the argument string. This will divert the flow of execution not back to where it came from, but to a special instruction sequence that calls execv() to replace the running image with a shell. This shell can issue commands to drag across a copy of the virus to the system. So gets() is not safe.

Upvotes: 1

P.P
P.P

Reputation: 121387

Because you can input more characters than size of the buffer and gets() will happily allow it. Moreover, gets() has been deprecated (in C11). So the comparison with scanf() is no longer valid. Besides scanf() has its own problems when dealing with unformatted data.

So a better option would be fgets() and then process it as per your needs.

Upvotes: 2

Fred Foo
Fred Foo

Reputation: 363587

still encouraged to use scanf().

A quick Google search for "scanf security" turns up ~212k results. The first is Wikipedia, which states that

uses of %s placeholders without length specifiers are inherently insecure and exploitable for buffer overflows.

So there's enough info about scanf security on the web. The difference with gets is that scanf has secure uses, while using gets is practically always a bad idea.

Upvotes: 1

Valeri Atamaniouk
Valeri Atamaniouk

Reputation: 5163

With gets it is not possible to prevent a buffer overflow in case of malformed input. scanf allows the control over amount of data read.

How to prevent scanf causing a buffer overflow in C?

Upvotes: 1

suspectus
suspectus

Reputation: 17268

Because there is no way to prevent buffer overflow. fgets is safer as the maximum buffer length is specified.

Upvotes: 1

Related Questions