Gosling Claims Huge Security Hole in .NET
renai42 writes "Java creator James Gosling this week called Microsoft's decision to support C and C++ in the common language runtime in .NET one of the 'biggest and most offensive mistakes that they could have made.' Gosling further commented that by including the two languages into Microsoft's software development platform, the company 'has left open a security hole large enough to drive many, many large trucks through.'" Note that this isn't a particular vulnerability, just a system of typing that makes it easy to introduce vulnerabilities, which last time I checked, all C programmers deal with.
Good thing Linux isn't written in...
Oh. Never mind!
I actually RTFA since it included a sensationalistic phrase like "biggest and most offensive mistakes that they could have made."
.NET platform. I certainly wouldn't call this a huge mistake made by MS.
To me, it sounded like a big advertisement for Java.
It's the developers decision to use unsafe code in the
A hunting rifle can be used to kill people. Does that mean the trigger should only work after inserting a valid and current hunting license?
CowboyNeal is defending Microsoft. Someone take a screengrab, Slashdot's been hacked!
So you mean to tell me that the father of Java won't be slightly bias?
.NET is great (for its target area)
C'mon now. There is no vulnerability. Don't post this sort of crap. Its strictly knee-jerk material meant to bend a few people out of shape and start flames.
J2EE is great (for its target area)
Both are secure, stable and reasonably fast if you are a GOOD programmer. ANYONE who does ANY C or C++ code that will be used in industry needs to ENSURE that they just take a few extra precautions and are aware of secure coding techniques in both languages. Its rather quite simple.
To sum it up: nothing to see here folks.
I don't disagree with Microsofts position. Yes errors are possible, but it's a programming language, and not Microsofts responsibility. With a case like programming it is the programmers responsibility to release code without exploits... c and c++ are fast, they have many advantages other languages don't have (such as Java) if a programmer decides to take advantage of that, with a slight bump in risk, then I say more power to them.
WANNAWIKI Wannawiki WannaWiki WANNAWIKI!
This could have just as easily read "Java Creator Disses Rival Product, Ignores Flaws in His Own."
In Java, everything is an object! Oh...except for the basic types, you need to use object wrappers for those.
the company 'has left open a security hole large enough to drive many, many large trucks through.'"
Like, say, a truck about the size of Sun's Java runtime environment.
The coolest voice ever.
This is what really distinguishes Java from other languages. The Java verifier is a sort of theorum prover that examines the byte-code and can guarantee that it does not violate certain rules such as forging the type of a reference or under/over-flowing the stack. Because this is done at the verify stage it is still possible to compile the bytecode down to machine level instructions after that and run at full speed. This is why Java is both safe and fast.
To support C/C++ semantics (ad-hoc pointers) you'd have to throw all that out the window and I assume that's what he's talking about.
Pat Niemeyer,
Author of Learning Java, O'Reilly & Associates and the BeanShell Java Scripting language.
New languages such as C# and Visual Basic.NET only produce managed code.
Hey, what about the keyword unsafe in C#? Sheesh.
Unsafe code is not subject to security checks of the .NET virtual machine. To execute unsafe code, you have to specifically grant those rights to the executing program. It is not something automatic.
Applications that require safety (for example running plugins downloaded from the net) simply don't allow those assemblies to be loaded.
Where is the problem again?
It's the same with C. We should know by now "you cannot use C to handle untrusted data (ie, data from untrusted machines on the net)". All such data need to be handled in a sandboxed system, a system with safe memory access. This means something like Java or similar things.
A lot of people will make posts that say things like "C doesn't cause the problems, it's incompetent or lazy programmers who cause the problems." Whatever. No excuse. That's like saying "we shouldn't need seat belts or airbags; all we need is to make sure that drivers don't make mistakes." Drivers and programmers do make mistakes and that's why we need safety mechanisms in both cases. C provides none. Programming in C is like driving around in a car from the fifties, with no seat belts, no airbags, no head rests, no ABS.
So any decision to extend the use of C is just foolish. What is the purpose of doing this? If people must use horrible legacy code then just use it, but why drag that into new frameworks like .NET?
It does not compute, for me at least.
No longer should homes be built using nails. All new homes should be built with really strong glue. Even though nails are faster and easier to work with, a carpenter might accidentally smash his thumb with a hammer. Plus, nails contain metal which may warp your home in the event a huge magnet is placed near the house.
--The Elmer's Glue Foundation for Strength and Security
But JNI is not Java... It's an API. For that matter you might consider sockets and network connections to make Java unsafe because they could invoke unsafe applications.
.NET allows you to choose safe vs. unsafe code... but it is a little different from the Java scenario in that this is unsafe code that is run through the VM. It's just an odd choice to make.
It is completely fair to point out that
Pat Niemeyer
Author of Learning Java, O'Reilly & Associates
To me this looks like a similar problem as allowing running native code via ActiveX. Yeah, we have permissions, signing and what ever - how much does it take for a trusted but buggy ActiveX applet to be exploited?
Huge mistake, IMHO. And do not compare this to JNI - I am no Java expert, but AFAIK you simply cannot call JNI functions from something like web applet by design, whereas here it is on the discretion of the app developer.
Gosling is dead wrong. I believe that Microsoft will soon prove they are capable of even bigger and more offensive security mistakes.
Also, the choice to actually use .NET is at least as big of a security error.
I'm an American. I love this country and the freedoms that we used to have.
Yes, CowboyNeal, but do they want to deal with it, and should they deal with it?
For every programmer who reads security bulletins and keeps tabs on the latest string-copying buffer overflow issues and fundamental security principles, there are a hundred who don't know or care.
C is a high-level language that:
Programmers want to be productive -- most want to make things make colourful stuff happen on the screen, not fiddle around with buffer guard code. So the more security can be built into the language and its running environment, the better.
Many languages, such as Python or Ruby, provide security against what I mention in my first bullet, through a virtual machine. They're not impenetrable, and are of course, as dynamic languages, subject to a different class of security holes (eg., string evaluation of code), but they're a step up from the C level.
Other languages, like Java, provide capability-based security models, allowing for sandbox environments with fine-grained control over what a program may or may not do. Java's security system is ambitious, but since most Java apps run on the server these days, it's not frequently used, and except for browser applets, Java code tend to run unchecked.
In a way, Java tries to do what the OS should be doing. Programs run on behalf of its human user, and their destructive power is scary. Why should any given program running on my PC have full access to my documents or personal data? As we're entering an age where we have more and smaller programs, and the difference between "my PC" and "the net" is increasingly blurred. Operating systems need to evolve into being able to distinguish between different capabilities it can grant to programs, or processes -- we need to think about our programs as servants that are doing work for us by proxy.
The same way you wouldn't let a personal servant manage your credit cards, you don't want to let your program do it -- unless, of course, it was a servant (or, following this metaphor, program) hired to deal with credit cards, which introduces the idea of trust. The personal accountant trusts the bank clerk, who trusts the people handling the vault, who trust the people who built the vault, and so on.
In short, any modern computer system needs to support the notions of delegated powers, and trust.
Programmers will certainly never stop having to consider vulnerabilities in code. But painstakingly working around pitfalls inherent in one's language, be it C or indeed .NET -- we need to evolve past that. The users, upon whom we exert so much power, certainly deserve it.
I don't know where you got your understanding of malloc, and especially free, but it's severely out of date. Knuth published about "Boundary Tags" no later than 1973 (citeseer is down, so no link). Saying that a coalesce operation "can be arbirarily slow" is just FUD. A boundary tag makes free() a fast O(1) operation: check the previous block in memory to see if it's free and if so join, a fast O(1) operation; check the next block in memory to see if it's free and if so coalesce; add free block to free-list, done. Yes, it's not zero work like a GC implementation sort-of is, but "arbitrarily slow"? It's basically at least as fast as malloc().
Allocation requests can hit disk, sure, but so can GC allocations even if they're just bumping a pointer: it all depends on the working set size. GC compaction can reduce fragmentation to reduce working set size, but that is only a big win if there's a lot of fragmentation, and most apps using a good malloc() don't exhibit that much. (It is also possible for a GC to rearrange memory so more in-working-set data is on pages together, reducing the working set page count without changing the total memory used. I don't know of any in-use implementations of this, since you need hardware support to know what objects are more-in-use; generally this is only available at the page level, where it's no help. I think maybe an early microde-based Smalltalk implementation might have done this.)
If your malloc has to walk giant free lists to find an open block, then sure, that can be slow. That's why people use trees of free lists based on size and such to make it more O(log N), and O(1) for small allocations. (On large allocations, actually using the memory amortizes the cost.) Read about dlmalloc, for example.
Furthermore, let's not misrepresent GC. Stop-and-collect GCs have obvious extra costs beyond the free-of-charge free (or lack of need for one). Incremental GCs that don't pause are usually slower overall and only preferred for interactive programs. For example, incremental GCs usually require "write barriers" or "read barriers" which require several extra instruction on every fetch from memory or every write of a pointer variable in memory. This can add up across the entire program. Incremental GCs also tend to be conservative, and only end up collecting things that, say, were garbage at the start of the most recent collection round, and generational collectors allow garbage to collect in later generations for some time, so they don't actually necessarily have a smaller working set than a non-leaky malloc()/free() program.
Another big win in non-GC systems is that you can use pointers that don't come off the heap. That way you can avoid allocation and deallocation and GC entirely. (You can actually do some of this in a GC system too if it's a 'conservative' GC that copes with pointers into the middle of blocks. Those pretty much only get used for adding GC to C and C++, though.) Here are some common ways this happens:
Of course, doing all these things requires that you balance your different types of malloc()s with the correct, matching type of free(). In practice, GC proponents overestimate the diffi