3

我读到了 heartbleed 漏洞,这是 memcpy 的错误。

void * memcpy( void * dest, const void *src, size_t len );

对 memcpy 的正确调用可能如下所示

int a[4711] [4711];
 int b[4711] [4711];
/* initialize a */
(void) memcpy( &b [0] [0], &a [0] [0], sizeof( a ) );

但是为什么第三个参数,什么时候会和 src 的大小不同呢?我看过其他示例,其中使用的是 dest 大小,应该什么时候完成?

4

3 回答 3

4

如果你看一下memcpy 手册页,第三个参数是从 src 复制到 dst 的字节数。所以使用 src 的大小或 dst 的大小都没有关系。但是您必须确保源缓冲区和目标缓冲区的大小至少等于或大于复制的字节数。否则会发生缓冲区溢出。

于 2014-04-12T15:34:28.593 回答
2

在这种情况下,srcdest数组的大小相同,因此无论您使用哪个数组都无关紧要sizeof

一般来说,如果您使用dest大小,那么您可以保证您的写入不会导致缓冲区溢出,这通常(但不总是)比读取结束后更严重的问题src

然而,阅读结束src也可能很严重,正如 Heartbeat 案例所示。为了保持稳健,最好在继续之前检查两者srcdest尺寸并确认它们都是您期望的。

于 2014-04-12T15:28:10.707 回答
2

的第三个参数memcpy(dst,src,len)给出要复制的字节数。

如果该字节数大于任一参数指向的内存,则您将被水洗。这是一个技术术语,用于描述诸如 Heartbleed 错误,以及我有过愉快经历的许多其他错误 :-( 修复。

如果您的软件开发思维方式面向内存对象,那么您问题中的代码模式是有效的。例如,如果您围绕memcpy()用于制作整个对象的精确副本的想法进行开发,我想您永远不会使用除sizeof(src).

但是memcpy()对于许多其他类型的操作很有用,例如部分缓冲区的管理、将不连贯的数据流收集到连续的内存位置以及类似的事情。

它也容易被滥用,并且通常不会对此进行检查。例如,在野外可能有数以万计的代码片段,其中许多在嵌入式系统中,看起来像这样。

char [10] out;
char [] in = "Yo ho ho and a bottle of rum!";
...
memcpy (out, in, 1+ strlen(in));  /*don't do this or you're hosed!*/
于 2014-04-12T15:35:22.173 回答