我怎么能让这个缓冲区溢出?

How could I make this buffer overflow?

void display(const char *path)
{
  char msg[128];
  int8_t size;
  memset(msg, 0, 128);

  FILE *file = fopen(path, "r");
  size_t n = fread(&size, 1, 1, file);
  if (n == 0 || size > 128)
    return;
  n = fread(msg, 1, size, file);

  puts(msg);
}


int main(int argc, char *argv[])
{
  if (argc != 2)
    return 1;

  display(argv[1]);
  return 0;
}

我怎么能让这个缓冲区溢出?我的意思是,缓冲区是 128 字节。但是代码不检查大小是否大于 128?如果是,那么它会提早 return,如果不是,它只会从文件复制不到 128 个字节到 msg?

int8_t size; 是一个 8 位有符号值,因此它落在 [-128,127].

范围内

执行此代码时:

  size_t n = fread(&size, 1, 1, file);
  if (n == 0 || size > 128)
    return;

如果 size 设置了最高有效位(即 size >= 0x80),则它被视为负数,因此 escaping/avoiding 检查。

假设代码读取值为 0x8F 的大小(十进制为 143),但由于 int8_t 类型的大小为 8 位,取值范围为 [-128,127],因此最高有效位已设置并指示有符号值,这意味着该值为 -113。

因此 size(n == 0 || size > 128) 中小于 128 仅仅是因为 -113 > 128 是假的。

这意味着代码将读取比数组大小更多的字节。它将读取 143 个字节,但数组大小仅为 128,从而触发基于堆栈的缓冲区溢出。