为什么这个用户对 fgets() 的输入会导致程序中止?

Why does this user input to fgets() cause the program to abort?

#include  <stdio.h>

int main()
{
    char buf[100];
    char s[100];
    int x = 1;
    fgets(s, 100, stdin);
    snprintf(buf, sizeof buf, s);
    printf("Buffer size is: (%d) \nData input: %s \n", strlen(buf), buf );
    printf("X equals: %d/ in hex: %x\nMemory address for x: (%p) \n", x, x, &x);
    return 0;
}

当我运行这个简单的c程序时,程序开始执行,等待stdin输入,然后执行打印语句。

一切正常,但当我向标准输入输入“%n”时,我收到:

*** %n in writable segment detected ***
Aborted

发生了什么,为什么 fgets() 的这个输入导致了这个?

来自 https://linux.die.net/man/3/snprintf:

Code such as printf(foo); often indicates a bug, since foo may contain a % character. If foo comes from untrusted user input, it may contain %n, causing the printf() call to write to memory and creating a security hole.

snprintf的第三个参数是格式字符串(与上面的情况相同)。

让用户输入格式说明符(特别是 %n,请参阅 What is the use of the %n format specifier in C?)会使您的程序出现安全漏洞。这里程序读取内存中的一些垃圾值(因为没有指定进一步的参数)并写入它,这就是为什么 %n 特别危险的原因(这里似乎它被拦截 before 通过 C 库写入内存,不错的功能)

正如 Craig 评论的那样,始终使用您的 格式字符串来处理用户输入:

snprintf(buf,sizeof buf,"%s",s)