Microsoft Open-Sources 'Checked C,' A Safer C Version (softpedia.com)
An anonymous reader writes from a report via Softpedia: Microsoft has open-sourced Checked C, an extension to the C programming language that brings new features to address a series of security-related issues. As its name hints, Checked C will add checking to C, and more specifically pointer bounds checking. The company hopes to curb the high-number of security bugs such as buffer overruns, out-of-bounds memory accesses, and incorrect type casts, all which would be easier to catch in Checked C. Despite tangible benefits to security, the problem of porting code to Checked C still exists, just like it did when C# or Rust came out, both C alternatives.
So they're calling it Checked C, or CC?
Checked, indeed.
If strcpy_s is their idea of a safer C I don't want to find out what a whole language like that is.
This won't gain traction until it's compatible with the C99 and C11 standards.
What a joke. If Microsoft was serious about this they should have done it...oh I don't know, maybe 25 years ago. You know, back when people were still writing applications in C, maybe?
Morons.
Seriously, watching things compile, i see the CC complain about that all the damned time.
As far as I can tell, developers consider the conservation of their precious time much more important than properly checking their variable types, or assuring type casts are content appropriate.
Given this simple fact, a language that would DARE to enforce sanity on such a target demographic is sure to be short lived.
I mean, the GALL! Forcing poor developers to write better quality code and avoid bad practices! Shame on you Microsoft!
I seem to recall long long ago someone else made a C compiler that did this.
Non sequitur: Your facts are uncoordinated.
That swiss cheese needs to be plugged ASAP.
My ism, it's full of beliefs.
Long long time ago (~2000?) I used GCC's bounds checking feature.
If I recall correctly, I had to compile my own GCC because it was the only way to enable it.
There have been many such alternatives around for a number of years. These include gcc and valgrind. And any decent C-library that supplies an "array" type and a "string" and a malloc wrapper can achieve the same ends without compromise.
That's it, I've had enough. I'm going back to Turbo Pascal.
Now Linux Torvalds will be able to do a serious linux kernel LOL
They allow for both by introducing a "bounded pointer" type in addition to the old style pointer. If you want to, you can still create a buffer overflow using a char *. Or, you can choose to a char 256* and access to it won't overflow 256, it'll generate an error.
Years ago, someone (perhaps Philippe Khan of Turbo Pascal) said 'C is a disease and the Americans are spreading it.'
Maybe he was referring to these security issues.
whatever is compatible with asm dude.
:
I'm confused - is Microsoft reinventing C++ or reinventing Java? I can't tell which decade from the last millennium they're trying to drag us back to. (Maybe as far back as when they were considered a reputable software company?)
"Microsoft has open-sourced Checked C, an extension to the C programming language that brings new features to address a series of security-related issues"
Bounds checking for C and C++ Nov 2004
Those that do not understand Rust are doomed to reinvent it. Badly.
The CPU just needs to set aside an area of memory exclusively for return addresses, and make that protected. No more security issues, buffer overruns, execution of arbitrary code. The real problem is that return addresses are mingled with other data. This should be solved at the hardware level, and AFAICS, it could be done totally transparently to code, even binaries.
Just asking.
Please fix Visual Studio C99 & C11 compliance first before extending the language.
The funny little known fact is: C99 already has a bounded pointer type: A pointer to a variable-length array.
void foo(int N, char (*ptr)[N]) // undefined behaviour
{
(*ptr)[N + 3] = 10;
}
Using the undefined-behaviour sanitizer, you can also have the compiler add automatic checks.
These are runtime checks and therefore expensive. C is intended to be a language for writing low level code that should not be encumbered with the expense of additional runtime checks. Use a different language if you need training wheels.
That declares that ptr is a pointer to a character, and reserves memory at that address for 256 characters. It does NOT prevent one from accessing ptr[312] . (Though a compiler MIGHT catch it if 312 were a literal.) By the C standard, the behavior when attempting to access ptr[312] is undefined, put it would normaly access whatever happens to be at a memory address 66 characters past the end of the ptr array.
The Microsoft extension adds a type with run-time bounds checking, so trying to access ptr[312] will always give an array-out-of-bounds erroe.
That's the right direction. Apple already has a pretty good version of it. (See below.)
Bounds checking C like this now is weak and very, very late:
https://gcc.gnu.org/ml/gcc/199...
https://www.lrde.epita.fr/~aki...
http://blog.qt.io/blog/2013/04...
http://valgrind.org/docs/manua...
https://en.wikipedia.org/wiki/...
But the grand champion memory debugger is the Mac OS X standard malloc libraries. You can simply set environment variables and instantly get better debugging than most methods on all other platforms. I presume this is because Objective C/C++ is such a pain to debug that they just built in features to always be available, even for production apps.
http://www.cocoawithlove.com/2...
Those libraries are clever because when debugging array bounds corruption and used/free, all mallocs get their own mmapped memory block surrounded by unmapped memory. Plus writing patterns into free / allocated memory to detect writing to freed memory, etc. This is great because it triggers a system signal that debuggers can catch deterministically.
I found and used those techniques on my last big project a couple years ago. The Windows desktop app and imaging C++ libraries were full of errors, memory corruption, struct and 32bit/64bit problems, etc. I had to do a lot of debugging and rewriting to port to Mac OS X, then a lot to solve corruption and threading issues. And found out, the hard way, what a mess the "standard" pthreads API / libraries were. Just spurred me on to switch to C++11 to have standard threads. This Mac OS X built-in debugging along with gdb made it a snap to find all of those kinds of errors, even for code meant for Android, Linux, and Windows.
Stephen D. Williams
automatically
They adress diffrent problem domains.
You're looking at the future of C. Probably the future of the Linux and BSD kernels as well.
Either this, or something similar to it will almost certainly be mandated at some point in the future for any sort of shared infrastructure programming. I expect projects where security is critical to opt in voluntarily as the benefits of being able to prove that certain fairly common classes of security bugs can not occur is especially valuable.
When you can build a stack of software from the kernel up that does not include ANY unsafe C code, you can start to actually rely on your code not being repeatedly subverted every few weeks with new previously undetected vulnerabilities.
What's wrong with the standard pthreads API?
"First they came for the slanderers and i said nothing."
So checked C is simila to Pascal?
May I direct your attention to this?
The CPU just needs to set aside an area of memory exclusively for return addresses, and make that protected. No more security issues, buffer overruns, execution of arbitrary code. The real problem is that return addresses are mingled with other data. This should be solved at the hardware level, and AFAICS, it could be done totally transparently to code, even binaries.
That solves some cases but by no means all of them.
Buffer overrun is a method that can be used to exploit the stack based return address. A separate return stack prevents buffer overrun to trash the return address but the buffer overrun will still happen.
Most operating systems that has file access capability or interrupts will have callback hooks and function pointers. Those are supposed to be written and overwriting those can also lead to arbitrary code execution.
It is also not a requirement to have the support in CPU. If I recall correctly ICCAVR used to have separate return and variable stacks.
Pretty much any CPU already supports this. On Z80 the IX or IY register would be ideal for a separate variable stack, you probably need to use one of them as a frame pointer anyway. On 68K you can pick any address register. On ARM I think any register would do.
The loss of an extra register to stack might lead to slightly slower code but there is almost always a performance tradeoff for security.
The method makes the code slightly harder to exploit. It doesn't protect against everything but no simple solution does.
Of course the better option is coding discipline and checking all inputs but that takes the fun out of programming.
C# isn't anywhere near a C alternative. No-one sensible is going to write an OS or low-level driver in C#.
There are many (?) compilers that place boundary spaces above and below arrays, so that access to ptr[256] or ptr[-1] will trigger a (manageable) runtime error, so it will catch runaway loops. But it won't catch things like your example. And C is for speed and this adds a check or two for every array access, so even if enabled in debug mode, it's usually removed in release mode.
Non-Linux Penguins ?
Actually, it declares that ptr is a pointer to an array. So to get at the data you would actually have to do (*ptr)[20] or ptr[0][20]. Provided you have assigned something meaningful to the pointer first. The only memory reserved by the declaration is enough to hold a pointer.
My interest in writing in C is knowing the machine code that is likely to be produced by the compiler. How does this apply to "Nim"?
Change is certain; progress is not obligatory.
It is absolutely astonishing that it has taken _this_long_ for someone to make these basic fixes to C.
Yes, and (*ptr)[20] is the correct syntax in that case since it is a pointer and not an array.
Ideally ptr[0][20] should generate a warning but probably won't.
Like C programmers cannot write bounds checkers. These are mostly hackish indeed, but at least standards compliant.
actually (ptr + 20) and *(ptr + 20) can be used .. and is what is most likely translated to by the compiler. Just as printf("%c", "this is a string"[8]); will output the letter 'a'
*("this is a string" + 8) will also produce the letter 'a' as "this is a string" is used as the base address.
What happens when that area runs out of space?
Move it to main memory?
The shitty Bell Labs stuff is widely used. Because people are educated in all textbooks to use the crap.
It is a MAJOR security issue. Like C and Unix and Windows and MacOS in general. One big shitpile which is less secure than the Algol 68 mainframes from Unisys, ICL and MCST.
But yeah, in a better C world we would use a string object (I actually do in one project), which has automatically growing capabilities.
MSFT is doing the right thing here, even if Hillary wants insecure computers.
So the microsoft extension is std::array?
It will send all your C source code to India where it can be checked for anything remotely innovative or copyright/patentable, at which point it will be sent back to you so you can await the pending lawsuit for copyright/patent infringement from Microsoft if you ever end up making money with your code.
I wonder if some kind of AI (Watson or similar) is going to deprecate a lot of these programming languages, extensions, and tools. Imagine if your AI could analyze your millions of lines of code in a few minutes, then aggressively optimize it and patch all of the bugs and vulnerabilities, while still giving the same intended output 100% of the time. I wonder what programming would look like at that point.
I imagine at that point everybody would be using a programming language like Go or Python that emphasizes readability and understandability, since all of the manual stuff you used to have to do with C or C++ or asm won't be necessary anymore.
How can you trust a software from a company that wants access to all your data (to improve your experience, they say) and won't let you turn it off.
Another indication that M$ recognizes that .NET and C# have failed.
You can simply set environment variables and instantly get better debugging than most methods on all other platforms.
... except ... its the same as on FreeBSD ... and every other applications that uses that malloc allocator instead of a crappy one. (Its not OS specific, its just the default allocator in OSX, iOS and FreeBSD, presumably others but I don't really follow the others.
Queue the idiots screaming that Apple stole it from FreeBSD now ... (original code was written to make the FBSD allocator not suck ass years ago)
And found out, the hard way, what a mess the "standard" pthreads API / libraries were.
Sigh, you just told us you're a shitty developer. Best of yet, you don't realize that what you switched to ... still uses pthreads under the hood on every platform that matters except windows.
pthreads requires you to know WTF you are doing and are extremely efficient, but I'm guessing you prefer something that does all the work for you and wastes a fuckton of CPU time because 'math is hard' Barbee.
Persistent Volume manager for Kubernetes - https://github.com/dwimsey/openshift-pvmanager
It produces C code, so you can know the machine code that is likely to be produced by the C compiler. If you know what machine code your C code will become, which I find quite hard, due to modern optimizations. That shifts the problem to knowing what C code your nim code will be turned into. It would take some learning and experience, and one would have to weigh this against the advantages nim offers, of which the checking described here ist only one.
So, your "interest" in writing in "C" is knowing the "machine code" that is likely to be produced by the "compiler". I see :o).
Old news for OpenBSD developers.
but the win should go to the parent for trolling via clever juxtapositioning of competing and incompatible technologies and/or implementations thereof.
(It already seems to have borne fruit!)
It produces C code, so you can know the machine code that is likely to be produced by the C compiler. If you know what machine code your C code will become, which I find quite hard, due to modern optimizations. That shifts the problem to knowing what C code your nim code will be turned into. It would take some learning and experience, and one would have to weigh this against the advantages nim offers, of which the checking described here ist only one. /. noob hell for this.
P.S.: sry for re-posting this while logged in, my anon reply was invisible even when selecting all posts to be displayed. Hope I don't go to
Like those at the CPSC, would gladly take the tools away from any construction site, as they are "unsafe".
After the unsafe tools are recalled, and the workers are issued big foam hammers, dull plastic saws, and wheelbarrows with training wheels, how can any real work be done?
(Captcha: foible)
Umm, no. *(ptr + 20) is different from those above. That would translate to *(char**) (((void*) ptr) + sizeof(char*) * 20). Whilst ptr[0][20] and (*ptr)[20] translate to *(char*) (((void*) (*ptr)) + sizeof(char) * 20).
And (ptr + 20) is even worse since it's completely missing dereferences.
Your printf example is correct though, but not relevant to the current case.
Yeah, but I'm not going to write 100 different variations in nim to get it to produce the C code I want to get it translated to machine code.
I'm writing low level C code, which doesn't have much room for optimization honestly and I like to do my own micro optimizations (and trust me, a compiler can't optimize some things the same way a human can, take a look at path walking in the Linux kernel for an epic example).
Sadly, things like bounds checking and malloc handling aren't always the most efficient and sacrifice performance; which isn't always in the interest of the project one works on.
Change is certain; progress is not obligatory.
Well, let's be honest, assembler does not have the nice fancy IDEs you can get with C (even if you're not using their fancy compilers), the language isn't so simple that you have to write out entire loop code. It is low level enough that I can write micro-optimizations and understand more or less what the compiler is going to produce.
So yes, my preference for using C is for this particular scenario typically.
Change is certain; progress is not obligatory.
Telemetry calls embedded via the compiler? Check!
Queue the idiots screaming that Apple stole it from FreeBSD now
Is it "stole" as much as "used under license"? Darwin is FreeBSD's userland on a Mach-derived kernel.
That and if you need to port your code to other architectures, such as x86 vs. x86-64 vs. ARM vs. MIPS, you can recompile C with only a minor loss in runtime speed due to loss of effectiveness of micro-optimizations.
No-one sensible is going to write an OS or low-level driver in C#.
Singularity was written in a variant of C#, using the .NET CLR's safety model.
"Singularity authors aren't sensible"? No true Scotsman.
And, so, how is this different from lint?
For that matter, none of all the C I used to write ever had buffer overflows, or memory out of bounds, etc. Of course, I wasn't right out of school when I wrote it, nor was I lazy... so, for example, I almost *never* used while/wend - overwhelmingly, it was for/next, with *LIMITS*. After some early C programming bugs that I fixed, I started, more and more, using strncpy.. And I *checked* the return from malloc.
mark "remember, half of the programmers out there are the bottom half"
This does not reserve memory. This declares ptr to be a pointer to an array of length 256. This is exactly what a bounded pointer is. And yes, compilers can sometimes detect out-of-bounds accesses at compile time (not only for literals) and because out-of-bounds accesses are undefined behavior, there are free to add run-time bounds checking when the pointer is de-referenced. And this is exactly what the undefined-behavior sanitizer for clang and gcc does if you use it. I know, because I fixed this for gcc because it wasn't working.
void foo(int n, char (*buf)[n]) ./a.out
{
(*buf)[n] = 1;
}
int main(int c, char* argv[])
{
char buf[10];
foo(10, &buf);
}
$ clang-3.5 -fsanitize=undefined -O3 c.c
$
c.c:4:2: runtime error: index 10 out of bounds for type 'char [n]'
Any time you brandish the word safer in the same breath as Microsoft you are lying.
In the example I gave, the size is encoded in the type. This makes it simple and cheap for the compiler to add bounds checking (which can also often be optimized away if it can prove that the access is not out-of-bounds).
This was posted here recently.
http://i.imgur.com/rnnPzYX.jpg
Now today our browsers connect to imgur.com on port 443. Are you saying they are a new certificate authority?
Or is this Spydot?
That's very interesting, thank you. Sometime I might use -fsanitize=undefined. Since most software is network-bound or IO-bound, I suppose the cost would be minimal?
> I know, because I fixed this for gcc because it wasn't working.
It's always good to hear from someone who definitely knows.
First they came for our null pointer references, then they came for our heap overflows... Jesus, is nothing sacred?
Soon upstanding citizens won't be able to divide a LEGALLY owned number by zero...
Ahh.. I never noticed the ptr[0][20] !!!
Your mindset is the McDonalds Approach To Computer Science. Quick and dirty. I do not really blame you, it is the rotten management and the race-to-bottom treadmill we are operating in.
Plus of course Hillary and he NSA minions want the capability to subvert everything.
But I guess this will change, because otherwise computers will lose their utility.
We have loads of crapware and millions of developers. Now, go it slowly and thoroughly. Then the cyber war domain can die its needed death.
C is worse than assembler in case I want to efficiently check for integer over- and underflow. CPUs can do it, but there is no way to use this functionality in a portable way.
C has clearly been created by USG in order to make computers "reconnoiterable" - worldwide, anytime.
Let's prop up your creation, so that you can hack all systems, worldwide, anytime.
Make people think C is a progression on Algol68, when the opposite is true.
Your lying will catch up with you and I guess the Mohammedics will take you over soon, because they are even better at lying than you are.
Do you really believe these 1% sponsored Dreck Messages ?
IBM currently dies a slow death because they mistrust Human Intelligence.
Here is an ounce of truth for you: Each Ant has a more powerful neural net than all real world "AIs". Just check the numbers.
Marvin Minsky was a 1% science whore who had fun to scare people.
And grow some balls, stop believing the nonsense of the marketing vultures and other propagandists.
It cannot be that a TLA wanted to make ciphers insecure. They would never do that, would they ?
Seriously, that is the most useless example why we should use non initialized memory. Assuming that "by magic" there will appear entropy from uninitialized memory is super amateurish.
Proper crypto can be nicely done in Pascal, Ada or Oberon. Actually, it can be done so well that the 1% would start calling for a return of their C based backdoors.
> Plus of course Hillary and he NSA minions want the capability to subvert everything.
The funny thing about being a partisan tool is it blinds you to the real issues, and turns politics into a base team sport.
And the real thigh-slapper is that you think a Republican candidate (even one other than Trump) wouldn't fuck your privacy 6 ways from Sunday.