由于其可能存在缓冲区溢出,因此禁止在我们公司的编码标准中使用普通旧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的这种用法。感谢您的投入和专业知识。
答案 0 :(得分:3)
可能安全地使用strcpy
- 这只是相当辛苦的工作(这就是为什么你的编码标准禁止它)。
但是,您发布的代码不是漏洞。没有办法用它来覆盖内存位;我不打算重写它。 (如果您做决定重写它,请改用std::string
。
答案 1 :(得分:2)
嗯,该代码存在多个问题:
strcpy()
而不是重复使用长度是次优的。请改用std::copy_n()
或memcpy()
。据推测,没有数据竞赛,我们无法分辨。
无论如何,在那里使用strcpy()
时,性能的轻微下降是唯一“错误”。至少如果你坚持自己手动管理字符串。
答案 2 :(得分:0)
总是有可能偏离编码标准,但是请很好地记录为什么决定这样做。
strcpy的主要问题是它没有长度限制。注意时,这没问题,但这意味着strcpy始终要附带一些保护代码。许多经验不足的编码人员陷入了这种陷阱,因此编码准则得以实施。
安全处理字符串复制的可能方法是:
答案 3 :(得分:0)
作为一般的strcpy替换用语,假设您对打印格式化功能的开销不大,可以使用snprintf:
snprintf(dest, dest_total_buffer_length, "%s", source);
例如
snprintf(newArgv[i], strlen(argv[i]) + 1, "%s", argv[i]);
这是安全,简单的,您无需考虑+ 1 / -1大小调整。