back to article Unsafe at any speed: Memcpy() banished in Redmond

Memcpy() and brethren, your days are numbered. At least in development shops that aspire to secure coding. Microsoft plans to formally banish the popular programming function that's been responsible for an untold number of security vulnerabilities over the years, not just in Windows but in countless other applications based on …

COMMENTS

This topic is closed for new posts.

Page:

  1. Kevin McMurtrie Silver badge
    Gates Horns

    Can't fix C hacking

    If the code was written properly, there'd already be bounds checking on the memcpy() count parameter. The real problem is that C can't associate sizes with pointers by itself. There's nothing to stop coders from using memcpy_s() with the wrong destination size, be it accidentally or intentionally. It will still crash the same way it did before.

  2. Jach
    Linux

    Problem with the coders, not the language

    Banning parts of a language because they could be dangerous or used unsafely is frankly ridiculous. It's a reason Java doesn't have real operator overloading and multiple inheritance. It's a weak argument people use to bash PHP (because it's easy to pick up and lots of idiots who shouldn't be programming in the first place use it).

  3. jake Silver badge

    Whatever.

    C is a low level language, one step up from assembler. Some of us like C because of that. All this article tells me is that Microsoft (and others, not picking on MS specifically) employs a bunch of low-cost kids with no coding street-smarts to do the "dumb heavy work" making up the bulk of the code ... which in turn explains the crap code that pervades today's world of home computing.

    It ain't t'language, lad, tis t'lad using t'language. (Or the t'Lady, with respect to Miss Bee.)

  4. This post has been deleted by its author

  5. jf

    SDL turns out to be a list of banned APIs and a lot of useless rhetoric

    Repeat after me, Banning APIs does not fix the underlying problem, Banning APIs does not fix the underlying problem, Banning APIs does not fix the underlying problem.

    As someone who has had the chance to read a lot of proprietary code the problem is largely more or less what Kevin said-- theres nothing to stop you from using the wrong destination size. Only *one* team I've seen use the API correctly, everyone else does-- well exactly what ATL does in the following screen shot: http://www.innocence-lost.net/atl-generated.jpg.

  6. Kevin Whitefoot

    Why is buffer overflow a problem?

    Surely the operating system and the hardware can allocate space in such a way that data buffers are not executable and that the code of a program is not writeable. So why is this still a problem? Isn't the ability to mark memory blocks with flags controlling these things supposed to be a feature of proper operating systems and processors? I have vague memories of reading many years ago about the memory management features of mainframe computers that mention things like this. See also http://developer.amd.com/documentation/articles/pages/3312005143.aspx for instance.

  7. Glen Turner

    Cheap rhetoric

    Last time I checked Linus wrote a kernel, not a C library or a compiler.

  8. Mike Pellatt
    Coat

    Nitpicks

    memcpy() et al aren't "commands" , they're "functions"

    Neither are they part of the "C" language - they are part of the "C" run-time support library, and these function calls aren't defined by the "C" language

  9. Ben
    Unhappy

    They should go one better...

    ...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.

  10. Tom

    wrong thing to ban

    #include win*

    or its equivalent in any language until MS unequivocally states it will not try to own any of your code at a later date.

  11. F Seiler

    new size parameter ..err, what?

    The memcpy i used so far has always had three parameters - destination, source AND number of bytes to copy.

    How will adding *another* size indicator help avoid buffer overruns ? If the programmer was wrong in specifying a proper and safe bytes-to-copy parameter, are the chances really any larger to get it right in a second guess ;)

    *note: memcpy is distince to the basic strcpy et co in this. Vanilla strcpy does *not* take a paramet specifying how much to copy, in the hope there will be a '\0' in the source before the destination buffer overflows. strncpy cures this.

  12. Tam Lin

    In actual usage, however ...

    int foo(char *inbuff)

    {

    char buff[12];

    char ams[] = "Ai'nt microsoft smrat?";

    /* Specifying the source size twice makes us mostest secure */

    memcpy_s(buff, sizeof(ams), ams, sizeof(ams));

    or

    /* This error logic you've seen before. */

    if (memcpy_s(buff + 32, sizeof(buff), ams, sizeof(ams))) printf("Disk full");

    finally;

    /* Caller allocated inbuff based on available RAM; We *KNOW* it's big enough, but we don't know its exact size. This fix allows us to kill warnings.

    NOTE: already tried memcpy_s(inbuff, sizeof(inbuff), ams, sizeof(ams)), it didn't work for some reason, probably another compiler bug */

    memcpy_s(inbuff, 999999, ams, sizeof(ams));

    }

    Kevin is right - of course it will "work" in certain cases. In those cases it has probably been implemented thousands of times already (likely as a macro). But replacing the original memcpy() gives a misplaced and dangerous sense of security where none actually exists.

    In order to understand the strcpy/strlcpy strcat/strlcat benefit, you first have to understand why and how it works, then you have to follow the rules. But buffers don't have rules, and slapping on another size parameter for security is like slapping a non-matching fake chrome exhaust pipe on your ricer to make it go faster and sound better. So, yeah, Linus and DrPepper probably will pick it up.

  13. Torben Mogensen

    It's a start...

    But I have to agree with Kevin that the core of the problem is using C, which checks nothing at runtime at not enough at compile time.

    An alternative could be Cyclone (http://cyclone.thelanguage.org/), which shares a lot with C but has advanced features don't have and, more importantly, avoids many types of safety holes and bugs caused by C's lack of checking.

    C# is also better than C in terms of safety and features. Microsoft is already using C# for a lot of things, but it is tied strongly to the .NET platform, so it can't be used for generic Windows programs or operating system modules. And for .NET, I would choose F# over C# any day.

  14. Maksim
    Flame

    This is insane

    What's up with this trend of 'making life easier and safer'? If somebody wants to use safe alternatives - fine. But why do we need to _force_ people out of fast low-level stuff?

    It's like 'yeah, you know, 99% of the programmers are idiots, really, who can't be trusted with dangerous stuff'. Only in ten years time there won't be anybody who can program your framoworks, libraries and OSes at all with that approach. Things are bad enough as it is, nine out of ten candidates whom I interview already do not know how computer works.

    Arrrgh!

  15. Ru

    You can't stop a determined idiot

    I note that openbsd did similar things by mandating use of their strlcpy and strlcat functions in the kernel instead of the usual strcpy and strcat, but still leave the old versions of the function available to ease application porting.

    It helps that they have significant amounts of buffer overflow and stack smashing protection enabled by default in their version of gcc, significantly reducing the risks of an overflow.

  16. raving angry loony

    A.F.T.

    I'd just like to say one thing.

    About. Fucking. Time.

    You'd think by now they would have written an appropriate bullet-proof wrapper for the function. I'm frankly shocked they haven't already done this, and the fact that they haven't explains so much about the lack of quality of their products.

  17. Anonymous Coward
    Thumb Down

    "It's a question worth asking"

    No it isn't a question worth asking. It's entirely possible to use memcpy safely, just as it's entirely possible to use memcpy_s (etc) wrongly.

    Does the author or the people making these suggestions have any experience of Bill's current family of _s "improvements"? They're rubbish.

    Why should slightly changing the name and the calling sequence turn carp programmers and carp designs into safe programmers and safe designs?

    Only a poor craftsman blames his tools, and programming is a craft not a science.

    What a daft concept, what a daft article.

  18. This post has been deleted by its author

  19. Andraž Levstik

    Hmmm what does Linus have to do with this?

    He has the kernel... not the C library(glibc). And this sounds like part of the C library not the kernel...

    Or do you mean not using it in the kernel?

  20. Anonymous Coward
    Anonymous Coward

    @ Kevin

    Read the article mate (also why the ms hate?)

    Its to do with security, nothing to do with crashes, basically saying its a lot harder to cause security issues with the new function so use that instead.

  21. Anonymous Coward
    Thumb Down

    Wrong approach

    You cant rely on the compiler or new functions to make your code secure. The only way to make code secure is to really understand what you are doing. Replacing memcpy with memcpy_s is silly and only leads to a false sense of security.

  22. Alan Jenkins

    Is this a joke?

    Yeah, the FA is pretty clear it doesn't make the operation any safer - it's more about forcing the programmer to consider the destination buffer size.

    Also, it's a nice way of saying "to achieve this certification, you must audit all your existing memcpy calls", in a verifiable way. Again, it's easily bypassed by

    sed -i *.c s/memcpy\((.*), (.*), (.*)\)/memcpy_s(\1, \3, \2, \3)/

    but if you're really that short-sighted, there's nothing that could help you :-).

    They seem to be missing a trick though. You should also be looking to try and replace memcpy() with structure assignment. Most C programmers don't even realise you can do that.

    Incidentally, C99 does have support for array _parameters_ with an associated size. I think the syntax is "char a[*]".

  23. Neil B

    Ultimate Solution

    # pragma deprecated (The C Language)

  24. Paul Clark
    Stop

    memcpy() is already bounded

    I don't get this at all... The problem with strcpy() which causes so many overflow vulnerabilities is that the amount copied depends on the unpredictable C-string length of 'src', but memcpy() has an explicit length. Allowing that length to be greater than the size of 'dest' is sheer stupidity, not just laziness, and memcpy_s() won't protect you from that.

    But who in Microsoft other than kernel/driver folk (who ought to know better, and who will resent the redundant comparison) is working in pure C anyway?

  25. jeffrey
    Boffin

    Well

    If people use memcpy properly in the first place it wouldn't be a problem

  26. Anonymous Coward
    Gates Horns

    This is evidently another MS error.

    System time on their publicity machine must have been reset to April 1st.

    The comment by Kevin McMurtie is quite correct, you'll still be able to break things in the same way as before by passing dodgy parameters to memcpy_s()

    They could declare a structure which began with a pointer and which then held the length of the data in bytes. Passing the structure (overridden natch) to any function would work and they could keep a count of the size of the data the pointer was looking at using the other variable. That might help...

    A more sensible step for MS to take might be simply to hire programmers who knew how to use pointers. Oh, and if their developer turn-around wasn't so high, they'd have developers who were more intimiate with the code which would mean less bugs (of any type) would slip through.

    ...it goes without saying (so I'll say it anyway) that if their OS was more than a patch fix on a bug fix on a pile of half-arsed cludges they'd get on better anyway. Isn't it about time they got rid of the biggest flaw in their code - the design (or lack of). I'm talking about things like the registry... it's a joke.

  27. Neil Barnes Silver badge
    Thumb Down

    Extend, embrace, extinguish...

    I assume that MS have at least *heard* of K&R? Perhaps they'll be banishing the assembler next on the grounds that you can do anything...

    Hopefully, #define _CRT_SECURE_NO_DEPRECATE will continue to work?

  28. M. Poolman

    title

    memcpy(dst, src, sizeof(*dst))

    might help. Better to use abstract data types with dedicated copy functions. If done properly problems like this will be manifest at compile time, not run time.

    JM2CW

  29. Andrew Moore

    Sheesh

    Who does unchecked memcpys?

    Oh yeah, Microsoft programmers...

  30. alain williams Silver badge

    How will an extra parameter help ?

    The 3rd parameter is the number of bytes that you want to copy, so having another size ... what does it add ?

  31. lennie
    Gates Halo

    they're thinking ahead

    @kevin: well at least they're trying something. its better than doing nothing don't you think?

  32. Dave

    Size?

    Last time I looked, memcpy has a length parameter, unlike strcpy. Admittedly it's obscured by the size_t so there's a bit of brain work required to convert to bytes for real buffer size, but it's there. I assume the new function has an explicit check (i.e. slower) to accomplish the same thing at runtime but can still be broken by a programming error in specifying buffer size.

  33. Critical

    What?

    "The command is already supported in Microsoft's Visual C++, but according to Ullrich, native support doesn't yet seem to be available in the GCC compiler."

    What's it got to do with the compiler? memcpy and friends are in glibc.

    If you don't want people to call stuff insecurely, you need to train them to go about development in a considered manner. Just passing the destination size is not good enough to prevent buffer overflows, as it still relies on the programmer passing the right size.

    If people aren't willing or able to think about stuff at that level, then they're better off using a higher-level language that would provide more safety anyway.

  34. Mark Wills
    Stop

    Hmmm.....

    "Its drawback comes when the source to be copied contains more bytes than its destination, creating overflows that present attackers with opportunities to ...."

    Hmmm,,, I think that's the symptom, rather than the cause.

    There's nothing wrong with memcpy(). It reads a word from a source, and writes it to a destination, decrements a counter, and continues if the counter !=0

    In other words, it does what it is supposed to do. The problem is that programmer did not bounds check before the memcpy was executed.

    A simple if block around the memcpy is all that's needed.

    Mark

  35. Anonymous Coward
    Thumb Down

    memcpy ain't the only way of writing to memory

    If you want to trash some memory, C provides endless ways of doing so. Anyone who thinks banning memcpy() will solve their security problems is fooling themselves.

  36. Anonymous Coward
    Anonymous Coward

    What I don't see can't harm me

    And what do they imagine is happening inside the code that they're too detached from the detail to know about?

    Bulk memory shifting!, and you'd better be doing it with memcpy that uses the correct processor instructions because doing it in a loop is slow and crappy and incompetent and no more secure.

    This is what AMD sued Intel for making their memcpy slow, and why processors have instructions built in to do it:

    http://www.amd.com/us-en/assets/content_type/DownloadableAssets/AMD-Intel_Full_Complaint.pdf

    Code is like sausage, if your sausage is crap it's better to not know what's in it, and kid yourself it's grade A meat. Redmond produce a lot of this kind of sausage.

    On the other hand the best sausage comes from the people who know what the pig that went into it had for breakfast.

  37. Jonathan

    Stupid question...

    I know that Steve refers to Steve Jobs of Apple and Linus refers to Linus Torvalds of Linux. Who does Larry refer to?

  38. Anonymous Coward
    Anonymous Coward

    Re: Can't fix C hacking

    I guess you didn't actually read the blog (or, maybe you did and are trying to look clever!)

    From the blog:

    "Of course, you can easily make a call to memcpy_s() insecure by getting the buffer sizes wrong. The following code is no better than memcpy():

    memcpy_s(dst,len, src,len);

    You’ve been warned!"

    ...

  39. John Smith Gold badge
    Thumb Up

    "notoriously dangerous C commands"

    Perhaps that should read "Notoriously dangerous stdio function library calls."

    IIRC there are safer more restricted versions of memcpy which have safety built in. They are also part of the stdio library.

    But maybe using them would demand too much thinking time when a release date is looming.

    I'd love to see some stats on this in live code, like Windows for example. And how many of those could actually be banished by a replacement macro IE where the unlimited nature of this function is not actually necessary.

    Thumbs up as better late than never.

  40. Andrew
    Boffin

    You know what will happen...

    What, my code doesn't complie? Hmm....

    #define memcpy(dst, src, sz) memcpy_s(dst, sz, src, sz)

    Problem solved.

  41. Anonymous Coward
    Gates Horns

    This is insane

    Anyone clueful will already be checking the amount you're copying (the "count" parameter to memcpy()) fits in the destination buffer before making the call. So there is no advantage to these new functions.

    Similarly for many of the other functions which they've already "deprecated".

    This is just another Microsoft attempt to fragment the C and C++ languages, so people writing for Windows write in Microsoft-only "safe C" rather than real portable C. This makes it harder for people to write cross-platform applications, or to port their apps from Windows to Linux/Mac. And they get to spin it as "Microsoft caring about security!" too.

  42. Anonymous Coward
    Thumb Down

    Obviously...

    ..we wouldn't want people learning to program properly would we.

  43. Andrew
    Boffin

    Security Theatre

    This seems fairly pointless. The reason strcpy is dangerous is that the number of bytes which it attempts to copy, is not specified by the calling function at all - rather it is determined by the contents of the copied memory. Whereas memcpy always copies exactly the number of bytes that the calling function anticipates. I'm not sure there are many cases in which this will crash where memcpy_s would have helped?

  44. Eddie Edwards
    Unhappy

    fopen_s

    I get memcpy_s but wtf use is fopen_s? That function doesn't write to the string buffer.

    Bored of that VC warning about this stuff. Esp. with clients that *insist* that warnings were always *actually* meant to be errors. Yay for breaking all legacy C code!

  45. Anonymous Coward
    Stop

    @kevin

    I'd have to agree, the destination argument is irrelevant.

    The proposed M$ fix is not really that helpful as it both makes the code non-portable (completely by accident I'm sure) and doesn't make it any safer as the above poster explains.

    A much better way is to arrange that your calls are truncated at the limit of the

    destination buffer using the sizeof operator, hence allowing the compiler to "associate sizes with pointers".

    It's portable, pure ANSI and works a treat.

    void

    my_func(FOO *dest, BAR *src)

    {

    memcpy(dest,src,sizeof(dest));

    }

    TTFN

  46. Joe Montana
    Flame

    WTF?

    the memcpy function already has a parameter to specify how many bytes to copy:

    void *

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

    Destination, Source, Length...

    If you add a 4th parameter, people will just put the length parameter twice, so if the specified length is wrong then it's wrong.

  47. David Hicks
    Thumb Down

    Leave my C alone!

    C is a beautiful, wonderful language that sorts the men from the boys and no mistaking.

    Sure, there are other ways to get things done quicker, but when you absolutely, positively have to squeeze every last ounce of performance out of something, well, there's no other way to go (except assembly and maybe C++).

    Yes, you can shoot yourself in the foot, or the head, with ease. But that's what makes the language so flexible. Take away my ability to treat everything as a piece of memory filled that I can stomp all over as I like and you take away some of my power to make things go fast.

  48. Anonymous Coward
    Thumb Down

    Notjing to do with C

    I agree with that. memcpy can be called from within even VB. Its an adjunct.

    Anyhow, its stupid to ban these things. More annoyance and intrusive "warnings" from MS who regard us as if we're all slightly backward children who can't be trusted with sharp things.

  49. This post has been deleted by its author

  50. Jason Bloomberg Silver badge
    Flame

    Next step, ban pointers

    There comes a point, if you are having to curtail programmers from doing something potentially damaging, where you have to consider that you are perhaps using the wrong programming language, or the wrong programmers, or both.

    That said, this isn't a bug or problem with C itself but in the libarary. Even then it's not really a bug or problem, only when it's used improperly does the issue arise.

    C allows plenty of damage to be done and it amazes me that it has gained such widespread acceptance. It is used in many circumstances where programmers would be better off using something else. Industry only has itself to blame for using the wrong tools for the job.

Page:

This topic is closed for new posts.

Other stories you might like