安全使用支架
Safe Use of strcpy
在我们公司的编码标准中使用普通的旧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尺寸调整。
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 通过网络、跨平台传递std::变体是否安全
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 从值小于256的uint16到uint8的Endian安全转换
- 在c++队列中使用pop和visit实现线程安全
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 全局变量 多读取器 一个写入器多线程安全?
- 安全到标准:移动会员?
- AcquireCredentialsHandleA() 返回 PFX 文件的0x8009030e(安全包中没有可用的凭据
- 共享队列的线程安全
- boost::文件系统::recursive_directory_iterator多线程安全
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- C++动态安全 2D 交错阵列