How’s this for a stupid piece of security news? Microsoft has banned memcpy from its “Security Development Lifecycle”, which presumably means Visual C++ will issue warnings now whenever you try to use it.
Microsoft have done this many times – “deprecating” pieces of the C standard library. Functions already banned are gets, sprintf, scanf, strcpy and strcat. But people are quite up-in-arms about memcpy because it’s a perfectly safe function if you use it properly — it copies exactly the number of bytes you tell it to. I want to make something clear which I haven’t seen quite right yet in this discussion.
The following functions are bad: gets, scanf(“%s”) and sprintf (among others). All modern C manuals warn you about using them, and Microsoft is right to deprecate them. gets, scanf and sprintf have unavoidable overflow issues, because they write to a pre-allocated string, and you have no way of knowing how many bytes will be written. They’re evil. Never use them, ever.
The following functions are okay, but require more caution than usual, I’d say: strcpy, strcat and sscanf(“%s”) (among others). It’s possible to use these safely, but you need to make sure the destination is large enough before you write, which usually means using strlen to allocate an appropriate size. There’s really nothing wrong with these functions, and I’ve always been annoyed that Microsoft took it upon themselves to “deprecate” them.
Now memcpy sits above both of these categories, with the likes of fgets and strncpy. Rather than going till the length of a (potentially unknown) string, it takes a length as input, and copies exactly that many bytes. It couldn’t be more straightforward. Do not copy more bytes than your source buffer, or your destination buffer. If you get that wrong, then you’ve made a serious programming error. Making errors on such a scale in C leads to unsafe programs. That’s just how it is. If you don’t like that, use a different language.
memcpy is not the problem. C is the problem. There’s nothing less safe about memcpy than anything else in the C language – even if you remove the entire library. If you can’t use memcpy correctly, then you can’t use C correctly. The replacement? memcpy_s! The s is for secure! This function takes separate arguments for the size of the source and the destination. It’s still unsafe, of course, it’s just that the new function is going to try and help you out in some cases. “It looks like you’re trying to cause a buffer overrun. Would you like help?” In my opinion, this memcpy_s offers nothing more than a false sense of security.
Oh, and of course the conspiracy theorist in me can’t help but point out that memcpy_s is a Microsoft function. It isn’t part of the C standard. Code which uses it will only work with Visual C++ (of course, you can define it yourself in another compiler, but that’s not ideal). So what’ve we got? A whole bunch of new functions with _s on the end of their names, which are no more secure than the functions we started with, but Visual C++ will now warn you if you write standard C code, and other compilers won’t work if you write Microsoft C code. Of course I think we can trust Microsoft not to write their own implementation of a standard, add their own extensions, then kill off the competition. That would just be ungentlemanlike.
Another blogger pointed out the official example of memmove_s, which has at least two problems I can spot (the most serious one is trying to write into a string literal, which as far as I know will segfault in most C implementations including Microsoft’s).