Remote Code Execution from Unbounded gets() in C Standard I/O

Critical Risk Memory Safety
cgetsbuffer-overflowrcestdiodeprecatedmemory-corruption

What it is

Remote code execution (RCE) is possible if attackers overflow buffers using gets(), hijack control flow, and execute arbitrary code. The gets() function reads input without bounds checking, allowing buffer overflows that can overwrite return addresses and other critical memory. Denial of service and data corruption are also likely.

#include <stdio.h>

// VULNERABLE: gets() has no bounds checking
int main() {
    char buffer[100];
    
    printf("Enter your name: ");
    gets(buffer);  // BUFFER OVERFLOW!
    
    printf("Hello, %s!\n", buffer);
    return 0;
}
#include <stdio.h>
#include <string.h>

// SECURE: fgets() with size limit
int main() {
    char buffer[100];
    
    printf("Enter your name: ");
    if (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        // Remove trailing newline
        size_t len = strlen(buffer);
        if (len > 0 && buffer[len-1] == '\n') {
            buffer[len-1] = '\0';
        }
        printf("Hello, %s!\n", buffer);
    } else {
        printf("Error reading input\n");
    }
    return 0;
}

💡 Why This Fix Works

The vulnerable code uses gets() which reads unlimited input, allowing buffer overflow. The secure version uses fgets() with sizeof(buffer) to enforce size limits and prevent overflow. The trailing newline from fgets() is removed for consistent behavior.

Why it happens

Using gets() which has no way to limit input size, making buffer overflow inevitable with long input.

Root causes

Using Deprecated gets() Function

Using gets() which has no way to limit input size, making buffer overflow inevitable with long input.

Legacy Code Not Updated

Old codebases still using gets() that haven't been updated to use safer alternatives.

Lack of Input Validation

No bounds checking or input length validation when reading user input.

Fixes

1

Replace gets() with fgets()

Use fgets(buffer, sizeof(buffer), stdin) which enforces size limits.

2

Use gets_s() if Available

On C11 systems with bounds-checking interfaces, use gets_s(buffer, size).

3

Enable Compiler Warnings

Enable warnings that detect deprecated function usage (-Wdeprecated-declarations).

Detect This Vulnerability in Your Code

Sourcery automatically identifies remote code execution from unbounded gets() in c standard i/o and many other security issues in your codebase.