安全使用支架

Safe Use of strcpy

本文关键字:安全      更新时间:2023-10-16

在我们公司的编码标准中使用普通的旧strcpy,因为它可能导致缓冲区溢出。我正在寻找我们在代码中链接的一些第三方库的来源。库源代码使用 strcpy 如下:

for (int i = 0; i < newArgc; i++)
{   
newArgv[i] = new char[strlen(argv[i]) + 1];
strcpy(newArgv[i], argv[i]);       
}

由于在为要复制到的缓冲区分配内存时使用 strlen,因此这看起来不错。是否有任何可能的方法可以利用这种正常的 strcpy,或者我认为它看起来是安全的?

我已经看到 strcpy 的幼稚使用导致缓冲区溢出情况,但这似乎没有,因为它总是使用 strlen 为缓冲区分配适量的空间,然后使用 argv[] 复制到该缓冲区作为源,应始终以 null 结尾。

老实说,我很好奇使用调试器运行此代码的人是否可以利用这一点,或者是否有任何其他策略试图破解我们的二进制文件(使用我们在其编译版本中链接的库源(可以用来利用这种使用 strcpy。感谢您的投入和专业知识。

可以安全地使用strcpy- 这只是非常艰苦的工作(这就是为什么你的编码标准禁止它(。

但是,您发布的代码不是漏洞。 没有办法用它覆盖内存位;我不会费心重写它。 (如果您决定重写它,请改用std::string

好吧,该代码存在多个问题:

  • 如果分配引发,则会发生内存泄漏。
  • 使用strcpy()而不是重用长度是次优的。请改用std::copy_n()memcpy()

据推测,没有数据竞赛,不是我们可以说的。

无论如何,性能的轻微下降是在那里使用strcpy()的唯一"错误"。至少如果你坚持自己手动管理你的字符串。

偏离编码标准应该总是可能的,但随后要很好地记录你决定这样做的原因。

strcpy 的主要问题是它没有长度限制。在注意时,这没有问题,但这意味着 strcpy 始终要附带一些保护代码。许多经验不足的编码人员陷入了这个陷阱,因此编码指南付诸实践。

安全处理字符串复制的可能方法是:

  • 检查字符串长度
  • 使用安全的变体,如strlcpy,或在较旧的Microsoft编译器上,strncpy_s。

作为一般的 strcpy 替换习语,假设您对打印格式化函数的轻微开销感到满意,请使用 snprintf:

snprintf(dest, dest_total_buffer_length, "%s", source);

例如

snprintf(newArgv[i], strlen(argv[i]) + 1, "%s", argv[i]);

它安全,简单,您无需考虑+1/-1尺寸调整。