views:

623

answers:

7

As some of you may know, Microsoft banned memcpy() from their Security Development Lifecycle, replacing it with memcpy_s().

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

/* simplified signature */
errno_t memcpy_s(void *dst, size_t dstsize, const void *src, size_t n);

So if your code used to be:

if (in_len > dst_len) {
    /* error */
}
memcpy(dst, src, in_len);

it becomes:

if (memcpy_s(dst, dst_len, src, src_len)) {
    /* error */
}

Or, with truncation,

memcpy(dst, src, min(in_len, dst_len));

vs

(void)memcpy_s(dst, dst_len, src, src_len);

The question: how does an extra length parameter make code any more secure? To use memcpy(), I should already have all four parameters known and pass appropriate length as a third argument. What's stopping me from making the same mistake of miscalculating destination buffer size and passing the wrong valus of dst_size? I can't see why it's any different from memcpy() and why it's being deprecated. Is there any common use case that I can't see? What am I missing here?

+4  A: 

You're not missing anything, I think this snippet from the article you linked to pretty much covers it:

If nothing else, memcpy_s makes you think about the size of the target buffer.

ninesided
+6  A: 

Nothing stops you from getting the parameters wrong in the "secure" version either. Microsoft seems to think that you'll always use something like:

errno_t e = memcpy_s (&dstbuff, sizeof(dstbuff), &srcbuff, sizeof(srcbuff));

and check the error.

But this only helps people who don't know what they're doing with the language. In my opinion, that group of people either shouldn't be using the language or they should learn how it works properly.

This sort of crutch doesn't do them any favors in the long run since their code won't be portable.

Now it may be that Microsoft did some analysis and found that there were a lot of problems caused by people misusing memcpy() and they thought this would fix it. But, if that were the case, I suspect a better solution would be to educate the developers rather than forcing them to use non-standard features which will be unavailable in standard compilers.

paxdiablo
"This sort of crutch doesn't do them any favours in the long run..." totally agree, Pax.
ninesided
First part right, second part wrong - it's not a crutch, and it's actually intended more for those that think they are experts in "how the language works", and are always looking for shortcuts. The new "secure" version, as @ninesided said, makes you think about what YOU are doing, and (hopefully) stop trying to work around the language.
AviD
But I should emphasize, what you say about the general pattern relying on use of sizeof(buf) is excellent point, and should be encouraged (unless, of course, you're not doing the copy from the beginning of the buffer...)
AviD
It doesn't matter whether you're dealing with heap or stack, or even whether you're copying from the beginning of the buffer. You /need/ to know how much space remains, and if you do memcpy is safe.
Matthew Flaschen
@AviD, I already know what I'm doing and people who don't have no right using C :-) - it's the chainsaw of programming languages and people who use chainsaws without experience and care WILL cut their limbs off.
paxdiablo
Encouraging programmers to write non-portable code is very helpful... to Microsoft.
Jeremy Friesner
+3  A: 

You're absolutely correct. If you are keeping track of both buffers' lengths, memcpy is safe to use. If you're not, memcpy_s won't save you.

Matthew Flaschen
+1  A: 

According to Microsoft, this will make it a bit easier to write code quality checks for - you can check to be sure that the programmer does not pass the same value to both size parameters (which many people would probably still do out of laziness). The other thing (not actually really related to code security) is that you can clean up your code a bit using this method, because there are less checks to do in your code - the memcpy_s function will check for you that there is enough space in the destination buffer, eliminating one of your checks.

Most important of all, memcpy_s returns an error code indicating whether the whole copy succeeded, but with memcpy there is no way to be sure of this. This is what Microsoft feels makes memcpy_s safer than memcpy.

a_m0d
I think relying on memcpy_s to do ordinary logic checks is poor practice, and I believe even those who advocate for the function would agree.
Matthew Flaschen
I agree - that line of reasoning is not mine but Microsoft's - I've updated my comment to make that a bit clearer. The second part is my opinion, but I don't think that code clarity is such a great reason for banning this function.
a_m0d
+6  A: 

Duplication of information is always bad design - it just gives you more chances to get something wrong. Microsoft have an appaling record when it comes to API design, and have been saved in the past only by the excellence of their documentation. The comforting thing is that they cannot remove the original memcpy() function - it is part of ANSI C.

anon
+1 I agree. I think that the main security problem MS and other low-level "hardcore" programmers should deal is buffer overruns. Anything else can (should) be checked by strong typed languages (C#, Java, Ada, etc...).
ATorras
"they cannot remove the original memcpy() function" - what they can do, though, is make it spit out warnings. And if they want, they can make those warnings difficult or impossible to ignore.
Steve Jessop
A: 

I actually dispare sometimes, there really arn't many of us real programmers left in the world any more who see the machine for what it is and love shifting bits around. A bit off topic I know, but I like to know exactly what's going on and definatly don't want any lame ass garbage collector going around the the background desperatly trying to sort out sloppy programmers messy heaps. I mean, how hard is it to match calls to free() with calls to malloc()/strdup(), how hard is it to make sure you have allocated enough buffer space in order to know you can call memcpy() saefly? Answer: Not very, but 99.9% of programmers really don't care what they are doing because they're just in it for the money, not the passion of writing a beutifully elligant piece of code.

End Rant.

A: 

C like assembly is for people that know what they are doing, I remember to read something like that direcly from K&R

Arabcoder