SQL 3.3 xmalloc 溢出示例 - 为什么?

问题描述 投票:0回答:1

网上很多地方都可以找到下面的例子:

以下摘自 OpenSSH 3.3 的代码演示了整数溢出的经典案例: (错误代码) 示例语言:C

nresp = packet_get_int();
if (nresp > 0) {
  response = xmalloc(nresp*sizeof(char*));
  for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL);
}

如果 nresp 的值为 1073741824 并且 sizeof(char*) 有其典型值 值为4,则运算结果

nresp*sizeof(char*)
溢出,xmalloc() 的参数将为 0。大多数 malloc() 实现将愉快地分配一个 0 字节缓冲区,从而导致 随后的循环迭代会溢出堆缓冲区响应。

如果 nresp 是一个 int 并且 sizeof() 返回一个 size_t(在 x86_64 中本质上是 unsigned long),则结果应该是 unsigned long。上面的问题是 xmalloc 的参数是 int 吗?或者该示例是否假设 IA32?如果不是,那是什么问题?

c integer-overflow
1个回答
0
投票

即使

nresp >= 0
sizeof(char*)
是一个很小的值,像
nresp*sizeof(char*)
这样的计算也存在溢出风险,因为它是
int * size_t

C 没有指定

size_t
int
更宽,尽管 v 是某种 unsigned 类型。
size_t
只能比
int
多 1 位,当
sizeof(char*)
大于 2 时,可能会发生溢出。

强大的代码可防止/检测潜在的溢出。

int nresp = packet_get_int();  
if (nresp > 0) {
    response = nresp > SIZE_MAX/sizeof(char*) ? NULL : xmalloc(nresp*sizeof(char*));
    if (response == NULL) {
      ; // TBD code to handle allocation failure.
    } else {
      for (i = 0; i < nresp; i++) response[i] = packet_get_string(NULL);
    }
  }
}



© www.soinside.com 2019 - 2024. All rights reserved.