Sam*_*Sam 4 c buffer gcc segmentation-fault
当我遇到这种情况时,我正在对一个主题进行一些研究.假设以下C代码:
#include <stdio.h>
int main() {
char name[1];
scanf("%s",name);
printf("Hi %s",name);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我编译-fno-stack-protector
并使用超过1的输入进行测试,就像John
,令我惊讶的是,它的工作原理!
当输入长于1时,它不应该抛出分段错误吗?
最终它打破了Alexander
输入(9),但它适用于任何小于9的内容.
为什么它的输入长于名称数组长度?
PS:我使用Ubuntu(64位),gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04)和CLion作为IDE.
这是未定义的行为.您的程序有一个缓冲区溢出,因为它只分配一个字符,这足以存储空的以空字符结尾的字符串.
但是,缓冲区附近的内存尚未分配给您的程序.scanf
将您的输入放入该内存,因为它不知道您的字符串缓冲区有多长.当预先确定的字节序列放入你的字符串时,这是一个很大的危险和无数黑客攻击的来源,希望覆盖一些重要元素,并最终获得控制权.
这就是为什么使用%s
而不指定大小是危险的.您需要始终添加适当的大小限制%s
,否则您的程序将面临缓冲区溢出的危险.
char name[120];
scanf("%119s",name);
Run Code Online (Sandbox Code Playgroud)
此程序是安全的,因为即使恶意用户输入超过120个字符,scanf
也会忽略%119s
格式中指定的第119个字符的所有内容.