c - 溢出 scanf ("%8s",字符串)?

标签 c scanf buffer-overflow

我知道有可能溢出普通代码:

字符串[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;
       ...
   } 

}

}

注意:

  1. foo 被别人调用了。
  2. 虽然字符串实际上是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/

相关文章:

c - 提供十六进制值作为 C 中获取的输入

C 缓冲区溢出显示消息(使用 Ubuntu 和 DDD)

c - 为什么我无法禁用堆栈保护?

c - 用于读取数据库的损坏的 C 代码

c - 如何使用 void * 数据创建结构体?

c - 在 MPI 中接收使用 malloc 分配的数组

c - 将floats打包成long long

c - 函数指针 - 变量未初始化

c - 在C中使用scanf解析输入

c - 在字符串中不使用空终止会产生什么影响?