Static methods/fields (also known as class methods/fields) are accessible from everywhere in the VM, because they do not need an object reference (which is obvious :). There are several different cases where problems could arise.
A possible approach for a solution
I tried to analyze the usage of static fields in the Java 1.1 API (as described in the API definition), and
came to the conclusion, that only System.in and System.out were problematic. The usage of static methods is not
really a problem, because either a) calling them has no impact on the rest of the system (e.g. Integer.parseInt)
or b) the methods may be implemented so that "system-wide" changes will only affect the "process
context". Please correct me, if I've missed something important. So we can consider problem 2 solved.
For problem 1 there are several possible approaches. Either we ignore this problem and leave security to the application
developer, or the ClassLoader verifies the bytecode at load time to ensure that there are no forbidden calls (criteria
for this are needed), or we take up the suggestion that the ClassLoader creates a new namespace for all static
calls (hmm...would increase memory consumption and make everything a bit more complicated).
All Threads belonging to a program could be placed in a ThreadGroup. JOS security will prevent applications from accessing/modifying their own ThreadGroup. ThreadGroup's functionality needs to be increased to support real limitations upon memory/CPU usage. A ThreadGroup could also serve as "parent object" for the "caller stack security model" I will describe later. Others suggested to introduction of "Application contexts" or "Process contexts", but these are basically just synonyms for my extended ThreadGroups. We can agree on the name later.
CPU time accounting
For this model to work, Threads will always need to be created in the appropriate ThreadGroup. E.g. an AWT Repaint
Thread, even if started by the system, needs to be put in the applications' ThreadGroup which is painted, so that
the painting time is accounted to the application, not the system. This should be flawless, as long as while creating
JOS, we keep in mind to put everything into the appropriate ThreadGroup. Our SecurityManager will only allow the
creation of Threads somewhere in that applications' ThreadGroup hierarchy. (small note to people not familiar with
the Java API: ThreadGroups may also contain other ThreadGroups as well as single Threads).
Memory accounting
It's difficult to track which object was created in an object-oriented system by which other object and why.
Therefore I suggest doing a compromise and also use the ThreadGroups to do memory accounting. The memory space
consumed by objects creating during a ThreadGroups execution time are accounted to that ThreadGroup. That's still
not 100% fair in case of shared code, but it's a beginning.
In an object-oriented system, with reusability in mind, objects will have to call other objects of which they do not know 100% if they are to be trusted. So we will need to scale access rights security down to the object level. I find the "caller stack security" approach, which is in use in the LP Mud world for years now, very usable. It basically works that way, that if a restricted action is tried to be executed, the whole stack of calling objects is traced back to the object with the least amount of security rights which are then used for executing this action. We will need a "parent" object for this model, so I suggest that a program's ThreadGroup should be used as the parent object. The ThreadGroup could have some sort of User object attached to it, which represents a "real user", and knows about that users basic access rights. Sometimes, an object which is part of JOS itself will need to have better rights than the calling objects. In this case, the JOS system may do a so called "unguarded" call, which basically deletes all entries in the current caller stack and therefore allows to restart with the system's access rights. The usage of "unguarded" calls is limited to a trusted part of the JOS core system.
Why is this really useful?
On the first look, the security achieved by this model can be achieved with a less costly model. But utilizing
this model from the very beginning puts our system on rather "safe feet" and allows adding rather nifty
security features later on.
Imagine this:
A composed document incorporating JavaBeans code for some really nice rendering of something is provided from User
A with very few access rights to User B with almost all access rights. User A could have modified the JavaBeans
code to be some sort of "Trojan Horse" to get something similar to "root" access to the machine
User B controls. But because the security is object-based, the incorporated JavaBeans objects will have more restrictive
access rights than User B, and so the caller stack security will prevent User A from obtaining "root"
access. Maybe this example was not that good, because similar stuff could be achieved by letting the JavaBeans
running in some sort of sandbox, but my intuition tells me, that having object-level security would be wise. An
argument for object-level security and against the sandbox approach would be, that you would have to setup
a new sandbox for basically everything. I need your opinions on that.
Of course there's still the open question on how to make this process transparent and really usable to end users.
JavaSoft's JDK 1.2 Security Specification seems to be almost at the same approach, so this draft should adapt a bit.
But, do we have to do more than one event-handling thread (for every process/ user with a different security-domain)? This would mean, every callback thread (like event-handler and with API 1.2 also printer) must reside in every security domain.
Btw, who is the author of this draft?
PhilNeumann 15.7.1998