Microsoft declared standard memory manipulation functions, such as memcpy, not secure and deprecated. The motivation behind this is that modern developers are not smart or careful enough to ensure that the destination buffer has sufficient room, which results in buffer overruns:
http://blogs.msdn.com/sdl/archive/2008/10/22/good-hygiene-and-banned-apis.aspx
Banning functions from the memcpy family is like banning knives in the kitchen or nail guns on a construction site and replacing them with plastic knives and hammers.
Let's put this analogy to the test. This small test program copies a 128 byte buffer 50M times to the destination buffer and prints elapsed time, in milliseconds, at the end.
#define MYSIZE 128
char *src, *dst;
DWORD stime = GetTickCount();
src = new char[MYSIZE];
dst = new char[MYSIZE];
memset(src, 'A', MYSIZE);
stime = GetTickCount();
for(int i = 0; i < 50000000ul; i++)
memcpy(dst, src, MYSIZE);
printf("elapsed: %d\n", GetTickCount()-stime);
On my 1.8MHz machine, this code takes about 3.5 seconds to complete. Replacing memcpy with memcpy_s increases run time to 5.5 seconds.
Let's look under the covers what is going on. Instead of generating a call to memcpy, the compiler produces code similar to what's shown below, which copies 32 4-byte words from the source pointed to by the esi register to the destination pointed to by edi.
memcpy(dst, src, MYSIZE); mov ecx,20h ; set up the counter mov esi,ebx ; source mov edi,ebp ; destination rep movs dword ptr es:[edi],dword ptr [esi] ; copy 4-byte words
When memcpy_s is being called, an actual call instruction is generated:
memcpy_s(dst, MYSIZE, src, MYSIZE); push 80h ; source size push esi ; source push 80h ; destination size push ebx ; destination call ebp ; call memcpy_s add esp,10h ; clean up the stack
, which is, combined with other checks in memcpy_s, explains longer run time. It is also worth mentioning that this optimization will be used when the amount of copied data is up to 4096 bytes.
Note also that the return value has also been changed from the pointer to the destination buffer to a useless errno value, which is appropriately commented in the memcpy_s source. This makes it impossible to use memcpy_s as a drop-in replacement for memcpy.
Conclusion
Functions like memcpy are written in assembly, and by very talented people. Don't take my word for it and take a look at the source. You don't have to understand the assembly language - there are plenty comments in the code showing how much the developer cared about how well this function will perform.
Stunts like banning memcpy are not designed to improve security - a developer who can't ensure that the destination buffer is large enough can and will overrun the buffer by passing the wrong destination size to memcpy_s. The true goal of this announcement is to give the public impression that Microsoft is doing something to make their products more secure.
I am amazed to think that Microsoft will spend a ton of money on walking millions lines of their code, replacing "deprecated" functions with code that will be just as vulnerable and will take longer to run. It's also very likely that they will end up introducing new bugs into otherwise stable code because new functions are not drop-in replacements.
The slowdown is not due to the memset.
Yes I was. Thank you for pointing this out.