Microsoft To Banish Memcpy()
kyriacos notes that Microsoft will be adding memcpy() to its list of function calls banned under its secure development lifecycle. This reader asks, "I was wondering how advanced C/C++ programmers view this move. Do you find this having a negative impact on the flexibility of the language, and do you think it will restrict the creativity of the programmer?"
Just like removing printf, scanf, and most other copy/string functions. There are safe versions of memcpy that work just fine and are just as easy to use...
Lame story (Trying for flamebait here?)
I have mod points and I am not afraid to use them
This should have been done thirty years ago.
AFAIK memcpy() is only one of the many ways in which you can hang any half-awake coder himself in C (some manage it when awake, but let's say charitable - I'm ignoring the chorus asking "why?").
Well done for thinking about security, boohoo for going straight to the press and trying to milk it instead of bloody DOING something for a change. Trust comes from casual "oh that? Yeah, we thought that was unsafe so we improved it" instead of trumpeting high and wide "look everyone, we bought a new padlock. Look how shiny it is, and how big" whilst still having a wooden backdoor with a simple latch only.
Do, don't talk. Show me. We've 20 years of marketing so pardon me for being cynical.
=Smidge=
Is it just my observation, or is eldavojohn an idiot?
...and pop up a message box asking the user to confirm they want to copy the memory, and if they press OK then they should have to enter a captcha.
Seriously though, how is it supposed to make your code safer if you pass the size you think your destination buffer is? With memcpy, that size is implicitly greater or equal to the copy size and it's the caller's responsibility to make sure this is the case. Putting bounds checking into the copy function is ridiculous if you're responsible for passing the bounds yourself, and it goes against basic good design. I'm surprised they aren't passing the source buffer size too, just to be extra safe. Also, what happened to the __restrict keyword? It's strangely absent from the memcpy_s function declaration.
=Smidge=
Is it just my observation, or is eldavojohn an idiot?
I have often used memcpy instead of strcpy when I have known the length of the strings, and also known the destination to be large enough.
I'm guessing many developers will just #define memcpy to something else and continue as nothing happened.
/ The Arrow
"How lovely you are. So lovely in my straightjacket..." - Nny
If you consider memcpy too dangerous then you should be using something besides C. If you're using C++ and memcpy then you really do need to know what both you and the compiler are doing.
The problem with strcpy() and sprintf() and like functions is that you don't know when calling them the length of the source to be copied into the supplied buffer. But with memcpy() you specify this length.
Frequently, the size of the target is calculated at run time, so bugs in memcpy() tend to be in the area of this calculation, rather than in not checking if the source fits the target.
Any lack of memcpy() would be easy to overcome, just use
memcpy_s (dst, len, src, len)
which is functionally identical to
memcpy (dst, src, len)
>Isn't security the programmer's responsibility?
You must be kidding. The average code monkey has failed miserably at that responsibility, time after time, for decades.
>(FP btw)
Fail.
This is nothing like sprintf. In sprintf there is no way to know how much data will be created ahead of time, so limit on buffer size is useful to make sure there is no buffer overrun.
With memcpy it is *precisely* known how much data will be copied. It is right there, 3rd parameter. If a developer can't do "if (sizetocopy = sizeofdstbuffer)", it is just as unlikely that he will be able to properly state that additional parameter that specifies the destination buffer size.
Of course if Microsoft is so concerned with security, why the heck did it take them years to add snptinf()? All this is is another attempt to make crossplatform development that much harder (much like all those "obsolete" POSIX functions that will barf warnings unless you use a cryptic define).
That said, if this silliness ever becomes a rule, I have an easy solution:
#define memcpy(dst, src, size) memcpy_s((dst), (src), (size), (size))
Problemo solved, now let's go actually write some real code.
Okay, I'm obviously missing something here. How is having an extra parameter for the destination size any safer? I always thought the third parameter to memcpy was the amount of data to copy, and since obviously it should never be set to anything larger than the size of the destination, how will having the destination size explicitly passed in help any?
Or are we just talking about a convenience feature that will make it easier for lazy programmers?
This is not the first time MS has done this. They have plenty of other standard functions that they have deprecated.
Yes, you read that right. Microsoft is deprecating parts of an ISO Standard all by themselves. Not that this should surprise anyone. I would have absolutely no objection to them proposing to WG14 to deprecate those functions; heck, I'd encourage it! But besides going out and deciding to 'deprecate' parts of the standards, the replacement functions actually violate those same standards.
And the warnings are irritating. You can't write a nice cross-platform library without either spewing tons of warnings or having to put in a bunch of #defines to shut the compiler up. And if you do that, your users get irritated if they depend on these warnings because you just turned them off (and of course, if you don't, they'll complain that your library is unsafe).
Screw Microsoft.
instead of
If they've been screwing up and using the wrong size for the number of bytes to copy, what's going to stop them from screwing up and putting the wrong size for the size of the destination buffer? Nothing! Now the coders that have been using something like
for the last parameter for years will have to change their code. Oh well...it's job security for someone.
the good ground has been paved over by suicidal maniacs
If = is ambiguous, then you must have a habit of abusing it. While you can overload = to mean anything you want, I suppose, it would seem like you should try to preserve the general notion of the assignment operator in C and C++, which is that = never modifies the right-hand side of the equal sign, only the left hand side.
"Does it mean duplicate the contents, transfer the contents and clear the original copy, or just swap the contents of the items, which might be quicker."
I would say if you are trying to stay true to the way the operator behaves in the language when you overload it, the last two operations would NOT be overloaded to the equal sign, because they modify the right-hand argument. Give them a meaningful method name instead.
#define memcpy(s1, s2, n) memcpy_s((s1), (n), (s2), (n))
taking the min is probably not what you want to do. If you don't have room in the destination for everything you want to copy, you need to find a new destination. Copying just part of the source memory is going to lead to strange behavior down the road (when you start interpretting the copied memory and it cuts off suddenly). So this just changes checking the sizes before the memcpy call and handling the error there into check the error code from memcpy_s, and handling the error afterwards.
Just write a one-liner that replaces all calls to memcpy with a call to memcpy_s, duplicating the size parameter.
I'm only half-joking. This is exactly how people will (mis)use memcpy_s. If you want safe memory access, you need to ban the entire C language. For those cases where you need C, you'll just have to make sure your programmers know what they're doing.
There's no failure quite as dissatisfying as a complete and total solution to the wrong problem.
How to easily make your code compliant with the new safety requirements:
#define memcpy(dest,src,len) memcpy_s(dest,len,src,len)
Some of these reactions are quite funny.
The goal of asking you to specify the length of the destination buffer is to force you to think about the data you're working with *while* you're writing the code and not afterwards in an unconnected security audit. Furthermore, it provides documentation to other people reading the code who may not have the same mental model of what's going on as you do. And as usual "other people" includes you, six months after you wrote the code.
Uh-huh. Because everyone is not just going to add a line of code to one of the base headers:
#define memcpy(dst, len, src) memcpy_s((dst),(len),(src),(len))
C is not a safe language, and stupid programmers will always find ways to mess it up. There are safer languages where you can't hang yourself as easily, and if you don't understand C, you should use them. Microsoft can't fix this problem.
Warning: Opinions known to be heavily biased.
Firstly, the specification of C anf C++ standard library is governed by the corresponding standard commitee. Microsoft has absolutely no authority to "banish" anything from neither C nor C++. They can deprecate it in their .NET code, C# etc., but it has absolutely no relevance to C and C++ languages. So, why would the author of the original question direct it to "advanced C and C++" programmers is beyond me. In general, C and C++ programmers will never know about this "interesting" development.
Secondly, the tryly unsafe and useless functions in the C standard library are the functions like "gets", which offer absolutely no protection agains buffer overflow, regardless of how careful the develoiper is. Functions like 'memcpy', on the other hand, offer sufficient protection to a qualified developer. There's absolutely no sentiment against these functions in C/C++ community and there is absolutely no possiblity of these functions to get deprecated as long as C language exists.
Well there's a reason Java and C# have GCs to free you from having to worry about calling malloc and free..
Now, all that's going to happen is that programmers are going to write their own memcpy-like routines using a quicky for-loop or something. It'll be just as bug prone, and harder to detect via automated source code analysis.
...but it's being eaten...by some...Linux or something...
Besides:
#pragma warning( disable: 4996 )
Thanks
If you wrote a program that used 8+ gigs of memory that means you're an incompetent code monkey.
I have an hourly job that processes about 8GB of input data files. We found that copying the data to a tmpfs filesystem instead of leaving it on a HDD cut the work time from 20 minutes to about 30 seconds because the job necessarily requires an enormous number of random seek()s. Since mmap()ing a file on tmpfs is roughly identical to read()ing the whole file into RAM, I guess that makes me an incompetent code monkey.
Of course, my boss who got a 40x speedup in exchange for $250 worth of RAM might see things differently from your inexperienced little self. Sometimes the Real World throws pretty big datasets at you.
Dewey, what part of this looks like authorities should be involved?
I guess Microsoft is trying to get people that don't understand C++ to program better in the language. IMHO, this will not solve fundamental problems with people programming C++, just cause them to learn the language slower by not having an experience working through a bastard of a bug. I think the world (and not just MS) needs to realize that writing a piece of complex software is difficult. Bugs like an errant memcpy of a subclass into a baseclass instance are *very* easy bugs to solve if you're looking for them. Memory overwrites are easy to detect if you are looking for them. Bad pointers are easy to detect if you're looking for them.
Such problems will always exist in software. I've found a fair number in my own code. What we *really* need to do is train a better caliber of programmer. OTOH, Microsoft seems hell-bent on trying to make writing software easy to do