【问题标题】:Can't find the possible buffer overflow in a piece of code在一段代码中找不到可能的缓冲区溢出
【发布时间】:2025-12-08 06:30:01
【问题描述】:

我一直在编写以下代码,有人告诉我它存在缓冲区溢出的风险。

现在诚然,我对缓冲区溢出的了解可能不如我想的那么可靠,但我认为缓冲区溢出是指正在写入的数据不适合缓冲区的边界并且会溢出到相邻的内存位置。

我认为这个问题可能与 fread 有关,它不是一个安全的函数,但通读文档似乎并没有告诉我它不安全,比如 strcpy() 与strncpy()。所以我很不确定问题可能出在哪里或如何处理它。此外,如果有人对我可以去哪里(或读什么书)有任何建议,这将有助于扩大我对该主题或其他漏洞弱点的了解,我将不胜感激。

bool readLong(FILE *f, long *n)
{
    unsigned char *ptr,tmp;

    if (fread(n,8,1,f) != 1)
        return false;

    ptr = (unsigned char *)n;
    tmp = ptr[0];
    ptr[0] = ptr[7];
    ptr[7] = tmp;
    tmp = ptr[1];
    ptr[1] = ptr[6];
    ptr[6] = tmp;
    tmp = ptr[2];
    ptr[2] = ptr[5];
    ptr[5] = tmp;
    tmp = ptr[3];
    ptr[3] = ptr[4];
    ptr[4] = tmp;

    return true;
}

【问题讨论】:

  • 首先,是什么让您如此确定 long 在您的系统上是 8 个字节?
  • 我们不知道fn 会传递什么。如果将一字节缓冲区传递给它们,则会出现缓冲区溢出,因为将对它们执行多字节读取和写入。
  • if (fread(n,sizeof *n,1,f) != 1) 是第一个改进。其余代码不应假定 long 为 8 个字节。并且不应该假设某个字节序。
  • 你的意思是&n
  • @stark,不,因为它已经是一个指针。

标签: c buffer-overflow


【解决方案1】:

您正在尝试将fread 8 个字节转换为long。虽然 long 可能在您的系统上是 8 个字节,但这绝不是保证。如果它只有 4 个字节长,那么你肯定会破坏周围的内存。当您为 ptr[7] 赋值时也会出现这种情况。

你应该做的是fread(n,sizeof(*n),1,f)。您也可以将ptr[7] 替换为ptr[sizeof(long)-1]

【讨论】:

  • 不仅ptr[7],而且ptr[6]ptr[5]ptr[4]都超出了4字节long的范围。
  • 哦,是的。谢谢你的收获。