سؤال

I read about the heartbleed exploit and that is was mistake with memcpy.

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

A proper call to memcpy can look like this

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

But why the third parameter, when would that be different from the size of the src? I've seen other examples where it's the dest size that is used, when should that be done?

هل كانت مفيدة؟

المحلول

If you take a look a the the memcpy Man page, the third argument is the number of bytes that is copied from src to dst. So it doesn't matter if you use the size of src or size of dst. But you must ensure that the source and destination buffer sizes are at least equal or greater than the number of bytes copied. Otherwise, buffer overflow will occur.

نصائح أخرى

The third parameter of memcpy(dst,src,len) gives the number of bytes to copy.

If that number of bytes is bigger than the memory pointed to by either parameter, you are hosed. That's a technical term describing things like the Heartbleed bug, as well as quite a few other bugs I've had the delightful experience :-( of fixing.

If your software development mindset is oriented toward memory objects, the code pattern in your question is valid. For example, if you develop around the idea that you use memcpy() to make exact copies of entire objects, I suppose you would never use any third parameter besides sizeof(src).

But memcpy() is useful for many other sorts of operations, such as management of partial buffers, gathering disjointed streams of data into consecutive memory locations, and similar things.

It's also subject to misuse, and ordinarily has no checks against that. For example, there are probably tens of thousands of code snippets in the wild, many of them in embedded systems, that look something like this.

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!*/

In this case, the src and dest arrays are the same size so it does not matter which one you do sizeof on.

In general, if you use the dest size, then you guarantee that your writing does not cause a buffer overflow, which is typically (but not always) a more serious problem than reading past the end of src.

However, reading past the end of src can also be serious, as the Heartbeat case shows. To be robust, it's best to check both src and dest sizes and confirm that they are both what you expect them to be, before proceeding.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top