memcpy()在Mac OS X中是否不安全?

时间:2012-04-16 12:25:57

标签: macos security memcpy

我知道有很多关于memcpy()在Windows / Microsoft世界中是不安全的讨论,但这是否也适用于Mac OS X代码(Cocoa)?如果是这样,Cocoa应该使用什么功能以获得最大安全性? memcpy_s()似乎没有出现在平台上。

感谢。

更新:我意识到关于memcpy()甚至在Windows中都是一个灰色区域(请参阅Memcpy() in secure programming?),但我试图发现这个相同的讨论是否适用于Mac OS X.事实上Mac OS X没有包含“安全”版本的memcpy()似乎意味着Apple认为事情并不那么糟糕。

4 个答案:

答案 0 :(得分:3)

当内存区域重叠时,您应该使用memmove而不是memcpy

如果你进行防御性编程并且知道他们实际上在做什么,那么他们本身就不安全。

答案 1 :(得分:2)

这是一个相当新的AFAIK,并不完美,但是GCC提供了一个名为__memcpy_chk的包装器,它会在可能的情况下检查目的地的大小,看看here。它的用法(来自同一资源):

 #undef memcpy
 #define bos0(dest) __builtin_object_size (dest, 0)
 #define memcpy(dest, src, n) \
   __builtin___memcpy_chk (dest, src, n, bos0 (dest))

 char *volatile p;
 char buf[10];
 /* It is unknown what object p points to, so this is optimized
    into plain memcpy - no checking is possible.  */
 memcpy (p, "abcde", n);
 /* Destination is known and length too.  It is known at compile
    time there will be no overflow.  */
 memcpy (&buf[5], "abcde", 5);
 /* Destination is known, but the length is not known at compile time.
    This will result in __memcpy_chk call that can check for overflow
    at runtime.  */
 memcpy (&buf[5], "abcde", n);
 /* Destination is known and it is known at compile time there will
    be overflow.  There will be a warning and __memcpy_chk call that
    will abort the program at runtime.  */
 memcpy (&buf[6], "abcde", 5);

答案 2 :(得分:2)

缓冲区溢出(这是memcpy,strcpy等的安全问题)与操作系统无关;基本上它们是C语言固有的问题,因为它没有提供自动边界检查。

尽职尽责,memcpy是安全的;例如,如果您自己验证参数,或者在编译时已知大小。但是每个人都会犯错误。

MS的禁止memcpy和使用自己的memcpy_s的方法是通过强制程序员到处进行额外的安全检查来减少错误。如果你愿意,你可以编写自己的memcpy_s;这不难做到,只需实施its MSDN page中描述的行为。

  ......似乎暗示苹果觉得事情并不那么糟糕。

结果是,微软觉得事情很糟糕。但是,公司对问题的看法并不会影响所述问题的存在,即不验证您对memcpy的输入是造成一类漏洞的原因。

答案 3 :(得分:1)

微软的memcpy_s()并没有给我留下深刻印象,因为仍然需要调用者来提供目标缓冲区大小。由于memcpy()可能出错的主要问题(除了源缓冲区和目标缓冲区重叠之外)是由于不知道目标缓冲区实际有多大而引起的,因此调用者不会将错误的大小放入目的地在?

我认为有一类错误会有所帮助,例如:

  char anArray[10]
  char* foo = anArray;
  memcpy_s(foo, sizeof foo, somewhereElse, 10);
  // or
  memcpy_s(foo, sizeof *foo, somewhereElse, 10);

然而,这两个都表明了对C指针的基本误解,并且可能不是代码的唯一问题。

如果目的地太小,你会怎么做?你继续使用截断的数据吗?你是否发出了一条错误消息“警报:程序员是个白痴”?不,在开始复制之前,最好知道目标缓冲区足够大。

此外,问题中的链接会讨论memcpy_s()具有空指针检查。再说一遍,你打算做什么?让程序崩溃是你可以做的所有事情,因为如果你期望不为null的指针为null,你就不能相信程序运行环境的任何部分。在现代PC操作系统上,只要memcpy()尝试取消引用空指针,程序就会崩溃。