K&R第2版中getop()函数实现是否存在缓冲区溢出漏洞?
关于K&R《C程序设计语言》getop()函数的缓冲区溢出问题
先给出原函数代码:
int getch(void); void ungetch(int); /* getop: get next character or numeric operand */ int getop(char s[]) { int i, c; while ((s[0] = c = getch()) == ' ' || c == '\t') ; s[1] = '\0'; if (!isdigit(c) && c != '.') return c; /* not a number */ i = 0; if (isdigit(c)) /* collect integer part */ while (isdigit(s[++i] = c = getch())) ; if (c == '.') /* collect fraction part */ while (isdigit(s[++i] = c = getch())) ; s[i] = '\0'; if (c != EOF) ungetch(c); return NUMBER; }
问题1:该函数是否存在缓冲区溢出漏洞?
答案是肯定的。这个函数完全没有对数组s的索引i做上限检查,当输入的数字(整数+小数部分)长度超过s的分配空间时,代码会持续往s的内存边界之外写入数据,这已经构成了缓冲区溢出漏洞。这种越界写入属于C语言中的未定义行为,可能引发各种不可预料的问题。
问题2:为何测试时用大小为2的数组输入超长数字串,程序没崩溃反而返回inf?
这是多个因素共同作用的结果:
- 缓冲区溢出的后果是未定义行为,崩溃只是其中一种可能,并非必然。越界写入的内存如果是程序未使用的区域,或者没有破坏关键的程序结构(比如栈帧返回地址、函数指针等),程序可能不会立刻崩溃。
- 后续处理
s的代码(比如将字符串转换为浮点数的逻辑)会读取这个超长数字串。由于现代浮点数(如double类型)有最大表示范围(约为1.7×10^308),当数字超过这个范围时,解析函数会将其视为无穷大(inf)并返回,这就出现了你看到的结果。 - 这种“正常运行”完全是偶然的,换一个编译环境、输入内容或者内存布局,程序很可能会崩溃、出现异常结果,甚至被利用执行恶意代码。
内容的提问来源于stack exchange,提问作者MrIo
相关产品推荐
相关产品推荐

