[3130] in java-interest
A Critique of the Java / HotJava Class Loading Mechanism
daemon@ATHENA.MIT.EDU (Antony Courtney)
Wed Nov 1 06:29:37 1995
To: java-interest@java.sun.com
From: Antony Courtney <antony@apocalypse.org>
Date: Wed, 01 Nov 1995 02:51:53 +0100
[ My sincerest appologies if this topic has already been addressed in this
forum. I didn't find any references to the issue on the java.sun.com
web site through either the top-level search mechanism or through
searching the mailing list archives. Unfortunately, there don't seem to be
any archives of comp.lang.java yet...]
A Critique of the Java / HotJava Class Loading Mechanism
Antony Courtney
<antony@apocalypse.org>
A Java class obtained from across the network (for example, an Applet which
is dynamically loaded into the HotJava browser) may reference other classes
which it wishes to use in its execution. In the binary Java class file
format, such "dependent classes" are represented by the name of the
dependent class (possibly qualified by the name of the package in which
the class appears).
When the Java class loader obtains and loads an Applet into a user's
browser, it must resolve the names of any dependent classes. It is my
belief that the current approach to class name resolution (which searches the
local filesystem _first_) is fundamentally flawed, and will lead to
substantial security, naming and versioning problems. I outline the problem
below, and offer some thoughts on a solution at the end of the article.
The Current Approach:
For "security" reasons, the Java class loader resolves all names of dependent
classes by first searching for a class with the given qualified class name
on the local filesystem, in directories given in the user's $CLASSPATH
environment variable. If a class with the given qualified class name
happens to exist on the user's local filesystem (or, more precisely, in the
user's $CLASSPATH), the class loader will resolve the dependent class name
by dynamically loading the class from the local filesystem. If a class
with the given qualified class name can not be found in the user's $CLASSPATH,
then the class loader will fetch the code for the class from the network
site from which the original class was obtained.
Problems:
There are three fundamental problems with the current approach to resolving
dependent class names.
First, there is the obvious security issue. HotJava users must ensure that
there is no code accessible through their $CLASSPATH which gives unchecked
access to local system resources, by, for example, providing a native method
which does not check who has invoked the method. All a malicious applet
needs to do in order to gain access to such unsafe code is guess the code's
qualified class name and the name and signature of the given method. [Note 1]
Second, even if there weren't a security issue, the current approach to
class loading introduces the potential for accidental name clashes
between the user's site and the site from which the Applet was obtained.
The only way that accidental name clashes will not be an issue under
the current scheme is if the package namespace is treated as a global
namespace spanning the entire Internet for the remainder of time. There is
some indication in the documentation that the package namespace was intended
to work this way:
...By convention, package names consist of period-seperated words,
with the first name representing the organization that developed
the package.
[The Java Language Specification, Rel 1.0 alpha3, pg. 21]
...while this is, perhaps, a nice idea, it is little more than "wishful
thinking" without mechanisms for allocating parts of the top-level package
namespace and managing the namespace on a global scale.
Finally, the current approach introduces a substantial versioning issue.
If I have one version of a library class like Acme.Collection.Bag on my system,
and an applet which I retrieve from across the network happens to have been
compiled with Acme.Collection.Bag, there is no reason whatsoever to believe
that the version used to compile the applet at the remote site and the version
on my system are compatible simply because they have the same name. This will
lead to unpredictable library incompatibilities at runtime for downloaded
applets, a disastrous result for an otherwise "statically safe" language.
[Note 3]
Some thoughts on addressing the problem:
In any system which allows for transmission of code across sites, a
distinction should be drawn between three different kinds of dependent
packages/classes (based on Gifford's terminology):
- Primitives: Primitives are the basic set of packages which
are assumed to exist at every execution site. Essentially, the
set of primitives is the set of packages which are provided as
part of the Java VM runtime. The set of primitives should be
Etched In Stone (i.e. written in some standard document somewhere),
and should have clear, universal, unambiguous semantics.
For notational convenience, it is reasonable for identifiers
referring to primitives to be dynamically rebound to their
implementation at the execution site, since primitives will have a
single, standardized interpretation everywhere.
- Libraries: In general, any dependent packages which an Applet
refers to should be treated as libraries. The names of library
classes should NOT be considered as globally scoped names, as
they currently are. Instead, dependent class names should be
considered as context-dependent names, where the context or
scope of the names is the network site from which the Applet
was obtained [note 3].
- Services: Services are local resources (provided as native methods
in Java) which an execution site wishes to make available to an
incoming Applet. For example, some sites might have 3-D rendering
hardware which they wish to make available to Applets. Such
specialized resources obviously don't belong in the standardized
set of primitives, since not every execution site can provide the
resource. However, since the service is partially implemented with
native methods, the code for services can't be obtained from across
the network, as was suggested for libraries.
Services are the most troublesome for the Java / HotJava model. It's not
at all clear to me that there is a reasonable model for making execution-site
services available to incoming Applets within the context of HotJava. [Note 4]
Notes:
[1] It could be argued that users are foolish if they have untrusted code in
their $CLASSPATH, and should only ever run hotjava with a minimal class path
consisting of system code and code they know to be secure. I consider this
an unreasonable argument; programmers should be encouraged to play with and
experiment with Java, and they must set their $CLASSPATH in order to do
that. The problem here is really that the mechanism by which programmers
specify "here are the classes which I need access to during my tinkering" is
the same mechanism which is used to specify "here are the classes which I wish
to make available for network access by Applets in HotJava". These are two
seperate issues, and should therefore be solved by two seperate, independent
mechanisms.
[2] At the very least, a (major, minor) version number mechanism, as used in
shared libraries, would be useful here.
[3] Actually, the "network site" alone isn't really sufficient, since it
doesn't capture the environment used by the programmer to resolve the
dependent class when the Applet was originally compiled. However, using
the directory in which the Applet appears as "additional context" (which is
what is currently done when fetching dependent classes from across the
network) is nearly sufficient.
[4] This is not to suggest that there aren't models which allow for
execution-site services to be provided in some clean, semantically sound way
to incoming code. For example Luca Cardelli's language Obliq allows for
execution-site services to be provided as formal parameters to incoming
agents. However, it's not clear how such a language/runtime facility could
be provided in the context of the Java/HotJava class loading model.
Have Fun,
-antony
--
Antony Courtney <antony@apocalypse.org>
Berkeley, CA
-
This message was sent to the java-interest mailing list
Info: send 'help' to java-interest-request@java.sun.com