LWN.net Logo

Developing GNOME Applications with Java (Linux Journal)

Linux Journal looks at the process of creating a GUI design in XML, writes Java code, and then plugs the whole thing in to the GNOME desktop. "With three existing Java GUI toolkits, one might ask why another alternative is necessary. GNOME's Java bindings are unique because they are tied directly to GNOME. An application written with GNOME's Java offerings looks and behaves exactly as if it had been written using GNOME's C libraries. It integrates seamlessly into the GNOME desktop and provides the same capabilities as any other GNOME application. The reason for this is GNOME's Java bindings use the Java Native Interface to delegate work directly to GNOME's C libraries."
(Log in to post comments)

Developing GNOME Applications with Java (Linux Journal)

Posted May 27, 2005 22:04 UTC (Fri) by bluefoxicy (guest, #25366) [Link]

Java still bothers me. A bug in the JRE code could quickly make for an exploit, which would be unguaranteed.

I have a major focus on proactive security measures. Mainly I prefer several techniques developed and implemented by various parties, some of whom I've studied with.

  1. Stack smash protection

    Prevents stack-based buffer overflows from corrupting local variables or the return address or return stack frame

  2. NX (Non-eXecutable) markings

    Allows memory without PROT_EXEC to refuse to execute, preventing code in places like the heap or stack from running unless allowed to explicitly

  3. Memory policy

    Assigns mandatory access control policy to memory, preventing programs from making dangerous transitions; particularly, PaX impliments a policy in which programs need permission to create or transition a write-execute resource or to transition non-executable resources to executable

  4. Address space layout randomization

    Randomly arranges the address space so that runtime assigned control values reflect a different environment at every program run; typically position independent executables locate this information using a value stored in a register, requiring code to be injected and run from some random unknown position to locate the random unknown position, et al

With typical JIT compilers, these compiler and operating system (kernel) protections come into question. Typically (3) is impossible due to the design of any JIT (Java, Mono); this places (2) into question because the JIT is left with no obligation to responsibly manage its own security. (1) is alright as long as the underlying language is bounds checked, except in the face of bugs in the JIT that miss bounds cehcking. (4) depends on the generation of PIC and the acceptance of mmap()-assigned addresses.

Of course, if the JIT moves to using temporary files in /tmp and file-backed mmap() (with a mild performance hit mitigatable by a little optimization, i.e. generating a method and nearest related all at once), some tricks with mkdtemp() and mkstemp() and some mmap()ing could easily place the JIT within the bounds of (3), immediately restoring (2). (1) stays in question, as well as (4); but because the address of the mapping is unknown until the file is mmap()ed in, it's likely PIC would be used and (4) would be restored.

It's notable that a JIT can restore (2) and (4); but that (1) would be a separate implementation from the underlying compiler used to build the JIT and thus would be twice the overhead with regard to code review. Only by using temporary files can (3) be restored, which implies (2); this method is easiest if (4) is honored.

Developing GNOME Applications with Java (Linux Journal)

Posted May 27, 2005 23:10 UTC (Fri) by dw (subscriber, #12017) [Link]

I'm sorry, but how is your rant applicable to this article? You are talking about the (few potential) vulnerabilities in some specific JRE implementation and constrasting it with a limited range of hardware/OS level bug prevention mechanisms.

Within the context of this article, in comparison to working in raw C, the increased security/productivity offered by Java far outweighs the fact that existing JREs cannot make use of some existing low level stack/memory protection mechanisms that don't even guarantee security anyway.

Developing GNOME Applications with Java (Linux Journal)

Posted May 28, 2005 0:44 UTC (Sat) by bluefoxicy (guest, #25366) [Link]

(3) together with (2) guarantees that no code can be directly injected into memory (hence java/mono not working); (1) and (4) are probablistic and solvable by luck, typically compounded, producing a multiple of both probabilities that being 2^32 * 2^16 == 2^48, which is pretty much proven to be considered a guarantee (according to an article about address space layout randomization and brute forcing it in 216 seconds in a 32 bit address space; it's "infeasable" to break it in a 48 bit address space). (1) alone bolsters the rest in many cases; (4) guards against the technique used to defeat (2) and (3). The result is reciprocative; each part protects against the attacks needed to defeat the others. Defeat is only possible by breaking (1) and (4), which is highly unprobabilistic.

Inherent security in Java is about as good as inherent security in an operating system. I can't develop a complete JRE/JIT on my own, and nobody is going to be crazy enough to back me on a high-security JIT even if it can provably avoid any performance detriment. I've informed the Mono and Kaffe projects of potential changes. Kaffe looked, made a little noise, no results; Mono just argued that it'd be slow and that no algorithms would ever mitigate that. My solution was to generate all methods called by a method when calling it, and keep track; this would work in theory because at most every other call would generate something, recursion would be fast, and typical access patterns would probably not cause a bunch of functions to exist with perfectly unique calls. Of course it and the two-level-deep model were blanketted with "That Won't Work Because We Said So And We Know More Than You" argument.

As for relavence, I was pointing out that having everything written in Java or C# isn't automatically a Good Thing(TM). The typical results with these types of articles is a double-edged religious battle between "OMFG JAVA IS SLOW AND TEH SUX" and "OMFG JAVA IS THE BEST THING EVAR ITZ SO EZ!"

I was raising the valid concerns of running Java in a secure environment; most typical JIT designs for Java or Mono or anything else won't fit in with a really good security model. These security models are almost but not quite perfectly suitable for even use on a typical home desktop (they kill Java, Mono, and anything using nVidia's closed source GLX; nVidia's GLX would be easy to fix if we had the source, but the other two need serious redesign). Having half your apps get quick and dirty kills by your security system makes these designs infeasible. The only potential saving grace would possibly be gcj.

Developing GNOME Applications with Java (Linux Journal)

Posted May 28, 2005 3:10 UTC (Sat) by mepr (guest, #4819) [Link]

"it's 'infeasable' to break it in a 48 bit address space"

I don't know when I'll seeing a GNOME desktop with 48 bits (256TB) of addressable memory. I'm not sure when I can expect to see such a system with 40 bits of memory (1TB), particularly not a consumer desk top.

Developing GNOME Applications with Java (Linux Journal)

Posted May 28, 2005 7:47 UTC (Sat) by farnz (subscriber, #17727) [Link]

All AMD64 systems have at least a 48-bit virtual address space, if not larger; just because it's not usually backed by RAM doesn't mean an exploit can make assumptions about the layout of virtual memory.

Developing GNOME Applications with Java (Linux Journal)

Posted May 28, 2005 19:33 UTC (Sat) by mepr (guest, #4819) [Link]

A naive exploit would be dumb and assume. Most people have memory sticks of uniform size starting in slot zero and working upward, restricting the likely memory locations, and most k8 motherboards are still highly limited in the amount of _actual_ address space implemented. I still dont see how the large memory space matters until it is implemented in hardware and commonly used.
For example, even the dual core, 4cpu Sun Fire V40z that I'm personally slavering over at this second, maxes at 32GB

Developing GNOME Applications with Java (Linux Journal)

Posted May 29, 2005 7:37 UTC (Sun) by peterh (subscriber, #4225) [Link]

You appear to be confusing virtual address space with physical address space.

It is irrelevant how much memory a computer has, or its location in the physical memory map. Address space randomization techniques work by randomizing the base virtual addresses of a program's segments, making it difficult for an attacker to guess the correct location of the program's code and data segments in the virtual address space. This can be done freely on just about any CPU with an MMU (although CPUs with a larger virtual address space naturally have more possible locations that can be used, irrespective of the size of physical memory).

Note that it is completely irrelevant (beyond a point) how much physical memory is installed and its configuration. These details are only known to the CPU and kernel, not to userspace programs. In fact, one of the main jobs of the kernel is to abstract these details from userspace. I don't know of any technical obstacle to using address space randomization on, say, an 80386 with 4Mb of RAM -- you still have 4Gb of virtual address space to play with on a 32 bit machine (actually 2Gb for userspace, but that's another story).

Take a look at a basic operating systems textbook (eg. Tanenbaum 'Modern Operating Systems') if you want more details.

Developing GNOME Applications with Java (Linux Journal)

Posted May 28, 2005 22:13 UTC (Sat) by ibukanov (subscriber, #3942) [Link]

You mistaken Java as a language with its JVM-with-JIT implementation used in Sun's JDK and other products. The article, on other hand, talks about developing Gnome application in Java with GCJ, which typically compiles Java applications directly to native executables.

So with GCJ you can apply all protections you described above and have solid protection offered by the language itself like automatic memory management. That along prevents heap corruption which can be exploited even if one uses all of the described prevention measures.

Developing GNOME Applications with Java (Linux Journal)

Posted May 29, 2005 16:50 UTC (Sun) by phiggins (subscriber, #5605) [Link]

You're really starting to sound like Colin Percival raising the red flag on hyperthreading. Maybe the fact that you can't convince VM designers to fix their problems is a sign that the problem isn't worth fixing. Take a look at BugTraq and search by narrowing to Sun as the vendor, then pick the J2SE JRE as the product. I see four vulnerabilities, and the only one that actual looks scary if the bytecode verifier, but that's not a stack overflow. I used to be worried about buffer overflows in the VM being exploitable from Java code, but I was concerned about that well over 5 years ago and such an exploit has never appeared. So what are you surprised that the VM writers aren't jumping through all the hoops you are proposing to prevent it from ever happening?

The much bigger problem with JIT is the huge amount of non-shared memory that gets taken up by JIT compiled versions of the (huge!) standard libraries. I'd much rather see someone go for a shared mmap()able temp file for the purpose of reducing memory usage!

Developing GNOME Applications with Java (Linux Journal)

Posted May 29, 2005 17:15 UTC (Sun) by cajal (guest, #4167) [Link]

In fact, Sun's Java 5.0 VM has started to share libraries between different instances of the JRE. See this article for more information.

Developing GNOME Applications with Java (Linux Journal)

Posted May 31, 2005 20:24 UTC (Tue) by massimiliano (subscriber, #3048) [Link]

In fact, Sun's Java 5.0 VM has started to share libraries between different instances of the JRE.

Mono does this if you compile AOT (and so does .NET if you use ngen).

Developing GNOME Applications with Java (Linux Journal)

Posted May 31, 2005 23:56 UTC (Tue) by mjw (subscriber, #16740) [Link]

The much bigger problem with JIT is the huge amount of non-shared memory that gets taken up by JIT compiled versions of the (huge!) standard libraries. I'd much rather see someone go for a shared mmap()able temp file for the purpose of reducing memory usage!
Use GCJ. The libgcj (GNU Classpath) core libraries are just compiled as a shared library so all gcj compiled (native) applications just share the core class library. That is what is so nice about the radical traditional approach that gcj takes.

Visual J++ Anyone?

Posted Jun 8, 2005 18:39 UTC (Wed) by hazelsct (subscriber, #3659) [Link]

How different are the GNOME Java bindings from Microsoft's Windows Foundation Classes? Granted the motivation is less sinister, but the result is the same: they kill platform independence, defeating one of the major purposes of Java.

Copyright © 2005, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds