Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gets() function in C

Tags:

c

I need help again! I thought it is pretty cool to use the gets() function because it is like the scanf() wherein I could get an input with whitespace. But I read in one of the threads (student info file handling) that it is not good to use because according to them, it is a devil's tool for creating buffer overflows (which I don't understand)

If I use the gets() function, I could do this. ENTER YOUR NAME: Keanu Reeves.

If I use the scanf(), I could only do this. ENTER YOUR NAME: Keanu

So I heed their advice and replaced all my gets() code with fgets(). The problem is now some of my codes are not working anymore...are there any functions other than gets() and fgets() which could read the whole line and which ignores the whitespace.

like image 993
newbie Avatar asked Dec 03 '10 14:12

newbie


People also ask

What is the use of gets () function?

The gets() function reads characters from stdin and stores them in str until a newline character or end of file is found. The difference between gets() and fgets() is that gets() uses stdin stream. The gets() function provides no support to prevent buffer overflow if large input string are provided.

What is the use of gets () function in C?

The gets function is part of the <stdio. h> header file in C. Function gets allows space-separated strings to be entered by the user. It waits until the newline character \n or an end-of-file EOF is reached.

What is gets () in C with example?

C library function - gets() The C library function char *gets(char *str) reads a line from stdin and stores it into the string pointed to by str. It stops when either the newline character is read or when the end-of-file is reached, whichever comes first.

What is the purpose of gets () and puts () question?

The gets() allows the user to enter the space-separated strings. The puts() function in C/C++ is used to write a line or string to the output( stdout ) stream. It prints the passed string with a newline and returns an integer value.


2 Answers

it is a devil's tool for creating buffer overflows

Because gets does not take a length parameter, it doesn't know how large your input buffer is. If you pass in a 10-character buffer and the user enters 100 characters -- well, you get the point.

fgets is a safer alternative to gets because it takes the buffer length as a parameter, so you can call it like this:

fgets(str, 10, stdin); 

and it will read in at most 9 characters.

the problem is now some of my codes are not working anymore

This is possibly because fgets also stores the final newline (\n) character in your buffer -- if your code is not expecting this, you should remove it manually:

int len = strlen(str); if (len > 0 && str[len-1] == '\n')   str[len-1] = '\0'; 
like image 117
casablanca Avatar answered Sep 21 '22 09:09

casablanca


As other responses have noted, gets() doesn't check the buffer space. In addition to accidental overflow problems, this weakness can be used by malicious users to create all sorts of havoc.

One of the first widespread worms, released in 1988, used gets() to propogate itself throughout the internet. Here's an interesting excerpt from Expert C Programming by Peter Van Der Linden which discusses how it worked:

The Early Bug gets() the Internet Worm

The problems in C are not confined to just the language. Some routines in the standard library have unsafe semantics. This was dramatically demonstrated in November 1988 by the worm program that wriggled through thousands of machines on the Internet network. When the smoke had cleared and the investigations were complete, it was determined that one way the worm had propagated was through a weakness in the finger daemon, which accepts queries over the network about who is currently logged in. The finger daemon, in.fingerd, used the standard I/O routine gets().

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; in fact, it can't check the buffer space. If the caller provides a pointer to the stack, and more input than buffer space, gets() will happily overwrite the stack. The finger daemon contained the code:

main(argc, argv) char *argv[]; { char line[512]; ... gets(line); 

Here, line is a 512-byte array allocated automatically on the stack. When a user provides more input than that to the finger daemon, the gets() routine will keep putting it on the stack. Most architectures are vulnerable to overwriting an existing entry in the middle of the stack with something bigger, that also overwrites neighboring entries. The cost of checking each stack access for size and permission would be prohibitive in software. A knowledgeable 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 (also carefully deposited on the stack) that calls execv() to replace the running image with a shell. Voilà, you are now talking to a shell on a remote machine instead of the finger daemon, and you can issue commands to drag across a copy of the virus to another machine.

Ironically, the gets() routine is an obsolete function that provided compatibility with the very first version of the portable I/O library, and was replaced by standard I/O more than a decade ago. The manpage even strongly recommends that fgets() always be used instead. The fgets() routine sets a limit on the number of characters read, so it won't exceed the size of the buffer. The finger daemon was made secure with a two-line fix that replaced:

gets(line); 

by the lines:

if (fgets(line, sizeof(line), stdin) == NULL) exit(1); 

This swallows a limited amount of input, and thus can't be manipulated into overwriting important locations by someone running the program. However, the ANSI C Standard did not remove gets() from the language. Thus, while this particular program was made secure, the underlying defect in the C standard library was not removed.

like image 42
Darel Avatar answered Sep 22 '22 09:09

Darel