安全使用 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
。
好吧,该代码存在多个问题:
- 如果分配失败,就会发生内存泄漏。
- 改用
strcpy()
instead of reusing the length is sub-optimal. Use std::copy_n()
or memcpy()
。
据推测,没有数据争用,我们无法判断。
无论如何,性能的轻微下降是 "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 大小调整。
我们公司的编码标准禁止使用普通的旧 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
。
好吧,该代码存在多个问题:
- 如果分配失败,就会发生内存泄漏。
- 改用
strcpy()
instead of reusing the length is sub-optimal. Usestd::copy_n()
ormemcpy()
。
据推测,没有数据争用,我们无法判断。
无论如何,性能的轻微下降是 "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 大小调整。