安全使用 strcpy

Safe Use of strcpy

我们公司的编码标准禁止使用普通的旧 strcpy,因为它可能会导致缓冲区溢出。我正在寻找我们在代码中 link 反对的一些第 3 方库的源代码。库源代码像这样使用 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 为缓冲区分配正确数量的 space,然后复制到该缓冲区使用 argv[] 作为源,应该始终以 null 终止。

老实说,我很好奇是否有人 运行 带有调试器的这段代码可以利用它,或者是否有人试图破解我们的二进制文件(使用我们 [=19= 的库源) ] against in its compiled version) 可以用来利用 strcpy 的这种使用。感谢您的投入和专业知识。

可能 安全地使用 strcpy - 这只是相当艰苦的工作(这就是为什么您的编码标准禁止这样做的原因)。

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

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

据推测,没有数据争用,我们无法判断。

无论如何,性能的轻微下降是 "wrong" 在那里使用 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 大小调整。