为什么strncpy不安全?

sti*_*mms 65 c c++ string strncpy

我想找出为什么strncpy被认为是不安全的.有没有人有关于此的任何文档或使用它的漏洞利用示例?

Tim*_*Tim 40

看看这个网站 ; 这是一个相当详细的解释.基本上,strncpy()不需要NUL终止,因此容易受到各种攻击.

  • +1,但值得注意的是,当您忘记手动添加空终止符时,strncpy只是不安全.如果你不记得,请考虑一个包装函数,它在调用strncpy后总是将最终字符设置为'\ 0'. (13认同)
  • "NULL终止"不正确.ASCII字符`\ 0`通常写成"NUL"以避免与`NULL`指针混淆. (5认同)
  • @Billy ONeal,http://opengroup.org/onlinepubs/007908775/xsh/strncpy.html,http://www.opengroup.org/onlinepubs/009695399/functions/strncpy.html和C1x草案不同意你的意见.除非ANSI C另有说明,否则零填充不是非标准行为.然后,微软根本不支持C; 他们所拥有的只是一个C++编译器. (4认同)
  • @RBerteig,请注意MS strncpy_s和公司不是1:1 strncpy替换,因为它们没有填充缓冲区.它们是更好的strcpy虽然IMHO strl*功能更通用,更快.@ojrac,它仍然太容易被滥用,因为有一件事你必须记住*和*复制(bufsize-1)而不是(bufsize)或让你的"rm -Rf/a"变成"rm - Rf /". (2认同)

Dig*_*oss 12

最初的问题显然是strcpy(3)不是一个内存安全的操作,因此攻击者可以提供比缓冲区更长的字符串,这将覆盖堆栈上的代码,如果仔细安排,可以执行来自攻击者的任意代码.

但是strncpy(3)还有一个问题,就是它在目的地的每种情况下都不提供空终止.(想象一下源字符串比目标缓冲区更长.)当结果被复制到第三个缓冲区时,未来的操作可能期望在相同大小的缓冲区之间符合C nul终止的字符串并且下游出现故障.

使用strncpy(3)比strcpy(3)好,但strlcpy(3)之类的东西更好.

  • `strncpy` 并不比 `strcpy` 好。`strlcpy` 在可用的地方很有用,在不可用的地方很容易重写。 (2认同)

sup*_*cat 7

要安全地使用strncpy,必须(1)手动将空字符粘贴到结果缓冲区上,(2)知道缓冲区事先以null结尾,并将(length-1)传递给strncpy,或者(3)知道永远不会使用任何不将其长度限制为缓冲区长度的方法复制缓冲区.

重要的是要注意strncpy将填充缓冲区中的所有内容超过复制的字符串,而其他长度限制的strcpy变体则不会.在某些情况下,这可能会导致性能下降,但在其他情况下则具有安全优势.例如,如果使用strlcpy将"supercalifragilisticexpalidocious"复制到缓冲区然后复制"it",则缓冲区将保持"it ^ ercalifragilisticexpalidocious ^"(使用"^"表示零字节).如果缓冲区被复制到固定大小的格式,则额外数据可能会随之标记.


AnT*_*AnT 5

该问题基于“加载”前提,这使得问题本身无效。

这里的底线strncpy是不被认为是不安全的,也从未被认为是不安全的。可以附加到该函数的唯一“不安全”声明是 C 内存模型和 C 语言本身的一般不安全性的广泛声明。(但这显然是一个完全不同的话题)。

在 C 语言领域内,对某种固有的“不安全”的错误信念strncpy源自广泛存在的strncpy用于“安全字符串复制”的可疑模式,即此函数不执行且从未打算执行的操作。这种用法确实很容易出错。但是即使你在“高度容易出错”和“不安全”之间加上一个等号,它仍然是一个使用问题(即缺乏教育问题)而不是strncpy问题。

基本上,可以说唯一的问题strncpy是不幸的命名,这让新手程序员认为他们了解这个函数的作用,而不是实际阅读规范。查看函数名称,一个不称职的程序员假定它strncpy是 的“安全版本” strcpy,而实际上这两个函数完全无关。

例如,可以对除法运算符提出完全相同的要求。正如你们大多数人所知,关于 C 语言最常见的问题之一是“我认为这1/2会评估为,0.5但我得到了0。为什么?” 然而,我们不会仅仅因为语言初学者倾向于误解其行为而声称除法运算符是不安全的。

再举一个例子,我们不会把伪随机数生成器函数称为“不安全”,因为无能的程序员经常对他们的输出不是真正随机的事实感到不快。

这正是它的strncpy功能。就像初学者程序员需要时间了解伪随机数生成器的实际作用一样,他们也需要时间来了解strncpy实际的作用。需要花时间了解这strncpy是一个转换函数,旨在将零终止字符串转换为固定宽度的字符串。需要时间来了解这strncpy与“安全字符串复制”完全无关,并且不能有意义地用于该目的。

诚然,语言学生通常需要更长的时间来学习目的,而strncpy不是使用除法运算符来解决问题。但是,这是针对strncpy.

PS 在接受的答案中链接的 CERT 文件正是致力于:证明典型的无能滥用strncpy功能的不安全性作为strcpy. 它绝不是要声称strncpy自己在某种程度上是不安全的。

  • 当人们说“`strncpy` 不安全”时,他们的意思是“它没有[成功的坑](http://blogs.msdn.com/b/brada/archive/2003/10/02/50420 .aspx)”。这是真的。 (2认同)