Reputation: 520
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
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
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
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
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
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
Reputation: 17268
Because there is no way to prevent buffer overflow. fgets is safer as the maximum buffer length is specified.
Upvotes: 1