Follow Slashdot stories on Twitter

 



Forgot your password?
typodupeerror
×
Security Microsoft Java Programming Sun Microsystems

Gosling Claims Huge Security Hole in .NET 687

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.
This discussion has been archived. No new comments can be posted.

Gosling Claims Huge Security Hole in .NET

Comments Filter:
  • JNI (Score:3, Informative)

    by codepunk ( 167897 ) on Friday February 04, 2005 @08:53PM (#11578863)
    I guess he forgot all about JNI. Now don't get me wrong I like java and would not even think about messing with .NOT but quit telling lies, java has the same exact hole.
  • by jerometremblay ( 513886 ) on Friday February 04, 2005 @08:58PM (#11578911) Homepage
    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?
  • by patniemeyer ( 444913 ) * <pat@pat.net> on Friday February 04, 2005 @09:10PM (#11579015) Homepage
    Yes, actually, it does. Have you checked it recently? The only overhead that natively compiled Java code would have over comparable C++ is that it always does array bounds checking. Other than that you just have to ask yourself, what kind of optimization can a static compiler (C/C++) do that a dynamic, profiling runtime compiler (Java) can't do?

    Garbage collection in Java has been faster than free/malloc in C for years. This is in large part due to the fact that the runtime can recognize very short lived objects and put them on a special part of the heap.

    It's not necessary to use unsafe languages to get performance any more.

    Pat Niemeyer
  • by Anonymous Coward on Friday February 04, 2005 @09:13PM (#11579056)
    .NET has the same kind of mechanism. All IL is checked and verified. An assembly that contains embedded native x86 code cannot be verified and will only execute in an environment with full trust permitted. It is exactly the same as JNI.
  • Re:Why oh why (Score:3, Informative)

    by omicronish ( 750174 ) on Friday February 04, 2005 @09:15PM (#11579072)

    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?

    Managed C++ is basically a compatibility language. It exists to provide developers an easy way to interface legacy C/C++ code with .NET code. By providing MC++ Microsoft is actually providing a way for developers to slowly migrate to more modern languages (sorta like JNI with Java; imagine if you couldn't make system calls at all). Without it considerably more effort would be needed to port and allow existing code to interface with new systems.

  • Re:JNI (Score:5, Informative)

    by patniemeyer ( 444913 ) * <pat@pat.net> on Friday February 04, 2005 @09:16PM (#11579078) Homepage
    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.

    It is completely fair to point out that .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.

    Pat Niemeyer
    Author of Learning Java, O'Reilly & Associates
  • by borgheron ( 172546 ) on Friday February 04, 2005 @09:26PM (#11579160) Homepage Journal
    Just curious... What's wrong with that?

    It speaks to the purity of the language. Being able to deal with *everything* as an object is a distinct advantage since it allows you to, potentially, extend basic types into more complex ones and it also prevents you from having to "box" primitives in objects and "unbox" them on the way out.

    BTW, JDK1.5 (aka Java 5) has a new feature called "autoboxing" which does the above boxing for you. This doesn't really count as those types being objects, it's more of a kludge than anything else.

    This difference means that C#, from an OO standpoint, is a more pure language as opposed to Java which is a "hybrid" OO language.

    GJC
  • by bnenning ( 58349 ) on Friday February 04, 2005 @09:29PM (#11579182)
    Just curious... What's wrong with that?

    It's ugly and non-orthoganal. Look at the Arrays [sun.com] class for example; there are dozens of duplicated methods that are identical except that they take bytes, chars, shorts, ints, etc. as arguments. I'd much rather have everything be a true object; any performance issues can be handled by the compiler, runtime, or Moore's law. Autoboxing helps, but better to fix it for real than with syntactic sugar.
  • Re:Phew! (Score:4, Informative)

    by DrLZRDMN ( 728996 ) on Friday February 04, 2005 @09:32PM (#11579198)
    Id like to see a kernel written in either language.
  • Re:Phew! (Score:1, Informative)

    by Anonymous Coward on Friday February 04, 2005 @09:34PM (#11579212)
    Not possible. By definition a virtual machine must run as a process.
  • by ppenrod ( 121367 ) on Friday February 04, 2005 @09:40PM (#11579249)
    "C and C++ allow for buffer overflows. They allow for improper or intentional coding to cause software to try to violate memory space of other functions or programs. They allow for memory allocation without necessarily providing any cleanup later. In the hands of bad, sloppy, lazy, or malicious programmers these traits have always proven to be a problem time and again on many different platforms."

    C is not for everyone.
    For starters, it's a small language by design.
    It was used to write OS code from the beginning.
    It assumes you know what you are doing and allows you to break the rules to get it done.

    If you want safety go back to Pascal...
  • by hobuddy ( 253368 ) on Friday February 04, 2005 @09:48PM (#11579304)

    You're quite right that Java's speed is excellent these days (for non-GUI code, at least). I've spent a lot of time recently working with a large system that was first implemented in Java (by highly skilled developers) and then ported to C++ (by greenhorns). The C++ port is only 50-100% faster, which isn't worth the price in developer time that's been wasted on memory leaks and other forms of memory corruption that were never a factor in Java. Besides that, supporting multiple platforms with the C++ version is the #definition of pain.

    However, the C++ version uses only about 1/4 or 1/5 as much memory as the Java version, and starts up far more quickly. If a *desktop* application needs to be deployed on older machines, or if the application is so memory-intensive it taxes the limits of today's server hardware, Java still falls flat.

  • Re:Advertisement? (Score:3, Informative)

    by cookd ( 72933 ) <douglascook&juno,com> on Friday February 04, 2005 @10:34PM (#11579606) Journal
    Ummm ... are you saying if a developer chooses to write unsafe code on .NET it is the fault of the developer that he can do so? By it's very name it implies that remote computers are going to connect to it, so one would hope it's not built to be too riddled with security holes or potential to be 'dangerous'.

    The developer can choose to do whatever he/she wants. The nice thing about .NET is that the end user can then choose whether or not to allow that developer's code to run on his/her machine, and can obtain additional information that aids him/her in making that decision.

    The .NET VM will verify the bytecode to determine whether the developer has done anything "unsafe" (such as perform pointer arithmetic or call native Windows code). If so, the VM will check the user's security settings to determine whether unsafe code is allowed to run in this context.
  • C++ isn't so unsafe (Score:1, Informative)

    by Anonymous Coward on Friday February 04, 2005 @10:36PM (#11579626)
    For those of you who haven't looked at C++ in 10 years or so (apparently all of you), things have changed. Modern C++ is completely different from C, and for that matter completely different from C a few years ago. Not much unchecked pointer code to deal with. In fact, NONE, except when you have to interface with a C library, and then that stuff is confined to a single well-tested abstraction layer over the C library.

    Why is it that open source type people stay away from C++? The few open source C++ projects I have looked at look like they were written about 10 years ago.

    If you're one of those who think C++ is just a big complicated mess, do yourself a favor and take a look at it now. I thought that not too long ago too but then I actually took the time to learn it well and it has completely changed the way I code (even in other languages!). Yes, it is big, and it is complicated, and it is most DEFINITELY not perfect. But it directly has facilities to support some very modern and powerful programming paradigms.
  • Re:Advertisement? (Score:3, Informative)

    by cookd ( 72933 ) <douglascook&juno,com> on Friday February 04, 2005 @10:37PM (#11579629) Journal
    His point is essentially that .NET does not protect the user against untrusted code, while Java does. If you run .NET code, you have to trust the developer, because the system won't protect you against a malicious or careless developer. If you run Java code in a sandbox, you're safe, because the system will watch what's going on and can be sure of the safety of its information.

    If that is the point, he's dead wrong.

    Just like you can run Java code in or out of the sandbox, you can run .NET code in or out of the sandbox. If the developer does pointer arithmetic or anything else that cannot be verified as "safe", the code will require additional permissions to run. Just like calling the file system APIs requires additional permissions in Java. It just means that if you want to write in C and target .NET, you can, but your users will have to grant your code additional permissions before it will run.
  • Re:Phew! (Score:3, Informative)

    by bluGill ( 862 ) on Saturday February 05, 2005 @12:47AM (#11580312)

    I'd like to point out that in this day and age most C programmers have heard about the problems and make some effort to prevent them. While programmers in "safe" languages (VB) generally have not heard of these problems, so while they are harder to create, those programmers are also less likely to recognize them. In fact problems in C are generally minor mistakes that are easy (though tedious) to fix, while in the other languages the same problem tends to be major design level issues that are hard to correct.

  • Re:Advertisement? (Score:3, Informative)

    by devinoni ( 13244 ) on Saturday February 05, 2005 @12:49AM (#11580321)
    Other than generics, and static imports, all the new language features of Java 1.5 aka 5.0 were available in C# 1.0. There was even a slashdot story about it. http://it.slashdot.org/article.pl?sid=04/10/11/145 4220&tid=108&tid=8/ [slashdot.org]
  • by rabtech ( 223758 ) on Saturday February 05, 2005 @01:32AM (#11580501) Homepage
    Like we really need more Rhetoric from Sun... but I'll deal with his concerns anyway.

    In order to use "unsafe" code from managed C++ (or unsafe blocks in C#) you must have "FullTrust" security rights, otherwise the code fails to run.

    You could shoot yourself in the foot but the runtime is perfectly capable of detecting and coping with corruption of the managed heap (generally by closing down the offending AppDomain.) Of course you can write a COM component in C++ and call it from dotnet, which is (in effect) the same exact thing! (I dare you to try and stop me from trashing Java or dotnet once I'm loaded in process via JNI or COM...)

    CAS (Code Access Security) means that no other code can call your "unsafe" methods without FullTrust either, so there is no danger from code running off the web of doing this.

    JNI is the same thing, Sun just gets to hide behind the lie since the risks aren't known by or integrated with the platform. At least with unsafe code the runtime is fully aware of that pointer voodoo magic you are trying to pull and can deal with it appropriately.

    In other words Game Developer X can hand-tune the rendering algorithm inside the "unsafe" code areas, but develop the rest of the platform in fully managed code, making the development process much easier to write, test, and debug.

    (As an aside, thanks to the antitrust ruling Microsoft is not allowed to comment on a great many things, including competitors. I don't know if this falls under that heading, but in many cases Microsoft's employees can't just come out and call bullshit when they see it for legal reasons.)

    In conclusion: Sun should shut the hell up.
  • Re:Advertisement? (Score:4, Informative)

    by Bodrius ( 191265 ) on Saturday February 05, 2005 @01:55AM (#11580600) Homepage
    What are you talking about? Inner classes are fully supported in C#...

    Unless you're talking about anonymous inner classes (a different animal, typically with a different purpose altogether when it comes to design motivation).

    This seems to have been a matter of designer taste on the part of Hejlsberg. 2.0 should bring anonymous methods, which aims to solve the same type of problems anonymous classes did, in a neater way.

  • Re:Advertisement? (Score:3, Informative)

    by malfunct ( 120790 ) on Saturday February 05, 2005 @02:02AM (#11580628) Homepage
    Nope, at least not if it can't verify its safety and request permissions correctly. There is a chain of trust that needs to be developed before the .NET framework will allow the assembly to load. One thing that you should do if you don't want unsafe code to execute is remove that permission from your program (can be done with an attribute in your source code) and then these unsafe modules just won't load.

    Not saying this can't be defeated but there are tools in the languages to protect yourself.
  • Re:Advertisement? (Score:1, Informative)

    by Anonymous Coward on Saturday February 05, 2005 @03:48AM (#11580979)
    And type safe delegates, type safe reference value parameters, custom defined metadata, user defined enumerations, explicit interface implementation to avoid syntactic and semantic method clashes, various language abstractions (properties, operator overloading).

    Just talking about V1.0 of C# here - I'm aware that Sun has copied many of those features in Java 1.5. For V2.0 there's a real implementation of generics rather than a kludge on type of the JVM... blah blah blah...
  • by Anonymous Coward on Saturday February 05, 2005 @04:19AM (#11581064)
    You can choose not to allow the unsafe code blocks with security settings. He just hasn't done enough homework to know what he's talking about.

    On top of this, allowing unsafe blocks of C/C++ is a good thing when people are porting to a managed language and need integration. It's pretty amazing that you can set a flag and run your old code in the new environment and call it from C#!

    My impression of him has dropped significantly. Apparently experienced .Net programmers know a heck of a lot more than he does.
  • Re:Advertisement? (Score:3, Informative)

    by malfunct ( 120790 ) on Saturday February 05, 2005 @04:49AM (#11581154) Homepage
    What I am saying, if you read it, is that you can tell the .Net framework that your application does not accept unsafe modules. If that is the case the C/C++ module that does unsafe actions (which are obvious to the frameworks security checks which are extensive and expensive) it will not be loaded. There is no danger of accidentially running unsafe code in an application that doesn't accept unsafe code. If you are worried about security it would be in your interest to not give your application this permission, especially if you are dynamically loading libraries through relfection.

    It would pay for you to read:

    http://msdn.microsoft.com/library/default.asp?url= /library/en-us/dnnetsec/html/seccodeguide.asp [microsoft.com]
  • by nothings ( 597917 ) on Saturday February 05, 2005 @04:59AM (#11581182) Homepage
    Malloc and free are simple algorithms, and whoever told you otherwise was wrong.

    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 [oswego.edu], 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:

    • statically allocated arrays
    • small arrays and strcts on the stack
    • structs that are components of other structs, or arrays at the end of structs
    • use of special allocators:
      • slab allocators (it's even possible to embed this entirely inside the default allocator for all small allocations)
      • pool allocators (allocate a large block of memory, suballocate from it, deallocate all at once)
      • "stack" allocators (allocate a large block of memory, suballocate from one end, only allow freeing from the same end, so allocation is a adding to a pointer and deallocation is reseting that pointer)

    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

  • Re:Advertisement? (Score:3, Informative)

    by Jordy ( 440 ) * <jordan.snocap@com> on Saturday February 05, 2005 @08:44AM (#11581810) Homepage
    C++/C is not. Bugs can have disastrous effect.

    Sigh. There are plenty of garbage collectors and boundscheckers for C/C++. Heck, there are several bounds checker extensions/patches for GCC that introduce bounds checking to both stack and heap. Boehm is a fine garbage collector if you like that sort of thing. They go back at least 10 years.

    Combined with a non-executable stack and heap, randomized address space layout and signed return addresses (StackGuard XORs with a random value and verifies before returning), it becomes extremely difficult to exploit.

    And of course with C++, you don't actually have to use pointers or arrays. There are enough nice safe standard containers.. well I won't go into that.

    That said, not all security exploits are buffer overflow related. There were plenty of security exploits before buffer overflows became popular and there are still plenty today. They can exist in Java just as easily as anywhere else. You pass an unescaped buffer from a user to a db call, no amount of VM is going to help you avoid someone taking advantage of it.
  • Re:Advertisement? (Score:3, Informative)

    by DrXym ( 126579 ) on Saturday February 05, 2005 @11:14AM (#11582443)
    The "integrating more cleanly" bit is worth more exploration. Java does allow native calls via JNI but it's always been bloody fiddly to get it to work. It does work, but it's fiddly requiring you define an interface, run a tool to generate stubs and implement those stubs handling exceptions & objects via a large set of JNI helper methods. Thus the average Java programmer doesn't even *think* about writing native code unless they absolutely, positively have to. So virtually every third party lib is pure Java, and has no dependencies on native executables or platform specific features. There are exceptions of course (e.g. SWT) which hit the underlying OS but in general this is true.

    Now onto .NET. C++ is fairly easy to pull into a project - write some garbage collection safe wrappers around your "legacy" code and now it runs in .NET. And via PInvoke you can call native methods easily too. And then there's COM interop which pulls in ActiveX controls. That's all good and well, but it also means that lots of projects are not "pure" - they're polluted with Win32 crap and generally not portable.

    That's probably what gets to Gosling - that .NET is touted as a portable development platform but it isn't. Projects are infested with unpure, unsafe and platform-specific code. Microsoft can preach portability but they know that very few people will be disciplined enough to bother with it. Thus people are tied to Win32 even when they're using a allegedly portable runtime. Even the likes of Mono only gets around this by pulling in winelib.

Software production is assumed to be a line function, but it is run like a staff function. -- Paul Licker

Working...