我知道有可能溢出普通代码:
字符串[9];
扫描(“%s”,字符串)。
但是scanf("%8s", string)有可能溢出吗? 8 只是一个例子。
我知道“%8s”就像一个分隔符,但我也注意到当我输入超过 8 个字符的字符串时,程序将终止,原因是:
* 检测到堆栈粉碎 *:./a.out 终止
======= 回溯:=========
...
显然,GCC 默认启用了一个检测堆栈粉碎的标志。由于这是一个堆栈粉碎,那么我的猜测是仍然有可能溢出并执行任意代码。
与破坏 scanf("%s") 调用者的正常溢出相反,如果 scanf("%8s") 可以溢出,它将在 scanf 函数内溢出,以便当 scanf 尝试返回时,控制权被获得。
但 scanf 是一个需要模式切换(从用户模式切换到内核模式)的系统调用,并且在内部它会调用诸如读取标准输入等内容。所以不确定我们是否可以在内核模式下溢出或其他什么......
欢迎评论!!
更新 >>
char string[9] 在上面的例子中假设。 char string[8] 在下面的真实代码中。
问题实际上是关于安全 scanf("%8s") 和 GCC 因堆栈粉碎而中止之间看似矛盾的故事。
简化代码:
void foo(pass some pointer) {
char input[8];
int input_number = 0;
while (1) { // looping console
printf some info;
scanf("%8s", input);
input_number = atoi(input);
if ((strlen(input) == 1) && (strncmp(input, "q", 1) == 0)) {
input_number = -1;
}
switch (input_number) {
case -1: to quit the console if input = 'q';
default: to print info that pointer refers to;
...
}
}
}
注意:
- foo 被别人调用了。
- 虽然字符串实际上是8个字节 带有“%8s”的代码,我不认为这个 导致粉碎。
最佳答案
参见 http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html :
Each directive is composed of one of the following...An optional non-zero decimal integer that specifies the maximum field width.
s
Matches a sequence of bytes that are not white-space characters. The application shall ensure that the corresponding argument is a pointer to the initial byte of an array of char, signed char, or unsigned char large enough to accept the sequence and a terminating null character code, which shall be added automatically.
所以它不会溢出 9 字节的字符串缓冲区。
关于c - 溢出 scanf ("%8s",字符串)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1787892/