8 ms·
Microsoft's list of banned C functions
- m12k 6y agoIn case you're wondering, yes, sscanf is on there.
- klodolph 6y agoNot really relevant to the recent sscanf problems, because Microsoft would use sscanf_s instead. The sscanf_s function is basically just a security-enhanced version of sscanf that otherwise behaves the same. I think it’s an Annex K version but I don't know Annex K very well.
- klodolph 6y agoNote that Microsoft’s approach to taming the C language is a bit different from Git’s approach (https://github.com/git/git/blob/master/banned.h https://github.com/git/git/blob/master/banned.h). Microsoft’s approach involves replacing the relevant functions with their Annex K variants, which is why the list is so long! For example, you see memcpy() on Microsoft’s list. That doesn't mean that Microsoft simply “banned memcpy”, it means that Microsoft wants their developers to use an alternative function called memcpy_s(). The _s suffix means “secure”. These functions are defined in Annex K of the C standard, which is an optional part of the C standard. If you look at memcpy_s(), it may seem a bit weird: errno_t memcpy_s( void *restrict dest, rsize_t destsz, const void *restrict src, rsize_t count ); Note that this is more than plain bounds checking, and I believe it’s also intended to be used with static analysis tools to ensure that it’s being called correctly—and the API is designed to make static analysis tools easier to write! As far as I can tell, Microsoft is really the only major user of Annex K. There may be a couple other users, but Microsoft is the big one. Microsoft reportedly pushed for the inclusion of Annex K into the C standard, implemented it in their own C toolchain, and wrote a bunch of tooling to work with the Annex K functions inside their massive legacy C codebase. You see, sometimes you have to do things a bit different if you have tons of legacy code and aren’t willing to spend the (prohibitively expensive) effort to rewrite it all with newer, safer techniques (use your imagination—like C++ or Rust). The _s Annex K functions are designed to replace the unsafe variants in a somewhat predictable, mechanical fashion so you can send a bunch of programmers into your legacy code base to fix security holes. And it does work. Git is a much newer C code base, is much smaller than Microsoft’s C code, not as old, and doesn’t run in the kernel. In Git, you’d be expected to manipulate strings with strbuf (https://github.com/git/git/blob/master/strbuf.h https://github.com/git/git/blob/master/strbuf.h) which is generally much safer and easier to use than the C stdlib. It’s just so much easier to make decisions like this in a new codebase like Git’s.
- ngcc_hk 6y agoEmbrace extend ... extinguish of the insecure one. Is security an excuse or is t the industry consensus or just Microsoft direction ? Old thinking I guess. But just ... What others do in this sphere.
- JW_00000 6y agoThe "extension" here (the _s functions) is standardized; while in the EEE strategy the extensions cannot be standardized: the whole point of the "extension" phase in EEE is to prevent interoperability.
- moonchild 6y agoExcept that the microsoft versions of the functions are incompatible with the standardized versions. (I don't think that that was done in bad faith, however; only that wg14 decided to change the definitions from the microsoft-proposed ones, and microsoft didn't feel willing to break compatibility.)
- Cyph0n 6y agoCisco uses the _s variants heavily in IOS-XR. I wasn’t aware that this family of functions was part of a specific addition to the C standard.
- lelanthran 6y ago> Microsoft’s approach involves replacing the relevant functions with their Annex K variants, which is why the list is so long! No, Microsoft's approach involves replacing the relevant functions with functions that are semantically different (and incompatible to) the Annex K functions. [EDIT: In case anyone is wondering, the Annex K functions that Microsoft provides will compile error-free on a conforming implementation (function signatures are the same), but because they are incompatible with what each parameter means sometimes they will crash].
- skohan 6y ago
- protoman3000 6y agoHow can you ban memcpy effectively if it’s just a simple for loop everybody can implement in less than 20 seconds?
- sneak 6y agoPresumably anyone sneaking in a memcpy in the backdoor would also be thwarted on code review.
- tom_mellior 6y agoOn code review and/or by a linting tool. Microsoft seems to be using lots of static analysis, and recognizing a memcpy loop is pretty simple.
- yholio 6y agoWell, of course you can't stop out of bounds array access in C. But at least you can cover the major array operations, such as string and memory copy.
- millstone 6y agoThis is a fair point. memcpy will just be replaced by manual loops or std::copy_n or whatever. Don't know if that's better or worse.
- the_mitsuhiko 6y agoNo it will be replaced by memcpy_s which is just generally a more sane version.
- deesep 6y agoShe Tried it's
- deesep 6y agoLol. I have no idea how the above comment got posted. I just noticed I had lost karma points and wondered why. I check my comment history and find this strange comment. I remember reading comments on this post and then doing something else. either I have gremlins in my phone or I must have unknowingly posted this reply. Not intentional and I can't edit or delete it as it was posted a while ago. Please ignore it :-)
- zz_throwaway_zz 6y agoNow C functions are getting banned? This censorship has gotten out of control.
- junippor 6y agoCan someone explain to me what's wrong with memcpy?
- scoutt 6y agoI think the most destructive thing is that you can overflow the destination buffer. With memcpy_s you have to specify the destination buffer size so you can (supposedly) prevent it.
- junippor 6y agoOk fine. As far as footguns go, that's not the most subtle one.
- fanf2 6y agoIt can do the wrong thing if the source and destination overlap. Use memmove() instead.
- longcommonname 6y agoIn addition to the others answers, memcpy of size zero is undefined in certain cases. This and the other two bugs can be particularly nasty when doing something such as an arena allocator or any other means of user memory pools. After an incredibly long slog on some particularly nasty corruption issues years ago I was only able to identify the problem by using ld preload and patching memcpy with some simple value and boundary checks for these three problems. Each of them was a source of the corruption.
- rurban 6y agoMany things. Besides the already explained buffer overflow, overlap and zero size UB, compiler also frequently chose to ignore it. The secure variant will fill the dest buffer regardless if the compiler thinks this is a useless side effect. Similar to the memset_s security problems nobody cares to fix.
- TazeTSchnitzel 6y agoI am happy to see snprintf isn't on the list. It's the best C99 string function, both safe and useful.
- EdSchouten 6y agoIt took ages for Microsoft to add it, though. They only implemented it as part of Visual Studio 2015.
- hnick 6y agosnprintf still has the typical format string vulnerabilities doesn't it? Information leaks, buffer overflows, etc.
- TazeTSchnitzel 6y agoYou can do silly things with the format string, but it will never overflow the output buffer if you invoke snprintf properly, nor will it ever not be null terminated, and snprintf can even tell you how large a buffer you need.
- hnick 6y agoOh yea, I was just thinking there are still limits to what 'safe' means though. My memory on the exact exploits was hazy so I had to look it up but I know it includes sending user defined data to the format string, which is not advised, but people do silly things all the time when coding which is why snprintf exists to start with. People can't be trusted to bounds check. In my mind a safer version for daily use wouldn't support the more problematic format options but maybe other people use them far more widely than me.
- TazeTSchnitzel 6y agoRight, yeah, I should say snprintf() is safer than sprintf(), but it still has the unsafe features of printf().
- 6y ago
- gorgoiler 6y agoCompletely off topic, but how is “(c) Microsoft All rights reserved” compatible with the rest of this code’s license?
- progre 6y agoCopyright ownership is generally separate from any license
- klodolph 6y ago“All rights reserved” is a confusing (and perhaps meaningless) phrase that could be taken to mean “no license”.
- SAI_Peregrinus 6y agoIt reserves all rights possible under copyright law. It then immediately grants some exceptions, in the form of a license. Failure to comply with the terms of the license brings the user into breach of contract, and it reverts to "all rights reserved". I don't think the "all rights reserved" part is necessary, since copyright in the US is automatic, but it doesn't change anything.
- klodolph 6y ago> It reserves all rights possible under copyright law. Could you provide some source that corroborates this? Because my understanding is that this has no effect. It merely states something that is already true. That’s what I was hinting at with “possibly meaningless”.
- SAI_Peregrinus 6y agoIt's a holdover from the time before the Berne convention where you needed to explicitly state what rights you were reserving when copyrighting a work. The US entered the Berne convention in 1988. Before that the Universal Copyright Convention (1952) was in force, which required a copyright notice and registration at the copyright office. Under the Berne convention (and the later WTO TRIPS agreement) neither of these things are required, so the entire "Copyright (c) Microsoft Corporation. All rights reserved." line is redundant. As you note, it merely states something that is already true. But it's become traditional to include something like that, often including the date, sometimes using the © symbol, etc.
- deleted 6y ago[deleted]