Tuesday, July 21, 2009

Immutability, Javari, and @ReadOnly: JSR 308

Behind the curve, as always, I'm only just realizing that Java is in the process of introducing an Official Way to assemble one of the important puzzle pieces for making systems with cooperating untrusted code: namely, immutability.

Enforced immutability makes it easy for you to share a data structure with a piece of code that should be allowed to read, but not write, the structure. There are a number of situations where this is useful. The Javari paper, for example, cites the way Class.getSigners was implemented in early versions of Java:


class Class {
private Object[] signers;
Object[] getSigners() {
return signers;
}
}


Because raw Java does not provide for read-only array elements, and because the method returns the array actually used to implement Java security, this is a security hole: all you need to do to make a class appear to have a different set of signers is alter elements in the returned array.

The conventional Java programming technique to avoid this problem is to make and return a copy of the array, but that adds verbosity to the code, is prone to errors (what if you forget to make a copy in just one place?), and is not efficient (if you invoke the method a lot, you make a lot of array copies).

Javari makes it easy to do something like this:


class Class {
private Object[] signers;
readonly Object[] getSigners() {
return signers;
}
}


which has the effect of prohibiting modification of the returned array elements, so that even untrusted code can invoke the method without ill effects.

JSR 308, coming up in Java 7, allows annotations on types. This extends Java annotations so that they can be used in place of the readonly keyword above, so that Javari can be turned into standard (JSR-308-extended) Java.

And now we come to the end of my expertise on the subject, because I've only just glanced at the main java page's blurb about JSR 308 and barely begun to read the Javari paper.

But I've got a question: is the Javari checker only a compiletime thing, and not a loadtime thing? Compiletime checking is great, of course; the earlier you can catch a potential error, in general, the better. But a compiletime-only mechanism is likely insufficient if you're interested in enforcing rules on untrusted code, because:

  • You may well not have access to the source for the untrusted code you'd like to run, and
  • Even if you have the source code, it may not be compilable with the Java compiler. With the recent proliferation of high-quality JVM-compatible languages, another language may express an algorithm better than Java itself, and you'd want to give people the freedom to submit untrusted code written in the language of their choice.
It may be that there's some straightforward way to put the pieces of the JSR 308 kit into a class loader and do loadtime verification of Javari's immutability rules, but I haven't yet spotted anything that says this is the case. Guess I've got my summer reading assignment.

No comments:

Post a Comment