Each applet is given two sandboxes, one for the code and one for the
data, as illustrated in Fig. 9-38(a) for the case of 16 sandboxes of 16 MB each.
MOV R1, S1
SHR #24, S1
CMP S1, S2
(a) Memory divided into 16-MB sandboxes. (b) One way of
checking an instruction for validity.
The basic idea behind a sandbox is to guarantee that an applet cannot jump to
code outside its code sandbox or reference data outside its data sandbox. The rea-
son for having two sandboxes is to prevent an applet from modifying its code dur-
ing execution to get around these restrictions.
By preventing all stores into the
code sandbox, we eliminate the danger of self-modifying code.
As long as an
applet is confined this way, it cannot damage the browser or other applets, plant vi-
ruses in memory, or otherwise do any damage to memory.
As soon as an applet is loaded, it is relocated to begin at the start of its sand-
box. Then checks are made to see if code and data references are confined to the
In the discussion below, we will just look at code references
instructions), but the same story holds for data references as
instructions that use direct addressing are easy to check: does the
target address land within the boundaries of the code sandbox?
s are also easy to check.
If the applet has code that tries to leave the code
sandbox, it is rejected and not executed. Similarly, attempts to touch data outside
the data sandbox cause the applet to be rejected.
The hard part is dynamic
instructions. Most machines have an instruction
in which the address to jump to is computed at run time, put in a register, and then
jumped to indirectly, for example by
to jump to the address held in regis-
The validity of such instructions must be checked at run time. This is done
by inserting code directly before the indirect jump to test the target address.
example of such a test is shown in Fig. 9-38(b). Remember that all valid addresses
have the same upper
bits, so this prefix can be stored in a scratch register, say
Such a register cannot be used by the applet itself, which may require rewriting it
to avoid this register.
The code works as follows: First the target address under inspection is copied
to a scratch register,
Then this register is shifted right precisely the correct
number of bits to isolate the common prefix in
Next the isolated prefix is com-
pared to the correct prefix initially loaded into
If they do not match, a trap oc-
curs and the applet is killed. This code sequence requires four instructions and two
Patching the binary program during execution requires some work, but it is
doable. It would be simpler if the applet were presented in source form and then
compiled locally using a trusted compiler that automatically checked the static ad-
dresses and inserted code to verify the dynamic ones during execution. Either way,
there is some run-time overhead associated with the dynamic checks.
Wahbe et al.
(1993) have measured this as about 4%, which is generally acceptable.
A second problem that must be solved is what happens when an applet tries to
make a system call.
The solution here is straightforward. The system-call instruc-
tion is replaced by a call to a special module called a
same pass that the dynamic address checks are inserted (or, if the source code is
available, by linking with a special library that calls the reference monitor instead
of making system calls).
Either way, the reference monitor examines each at-
tempted call and decides if it is safe to perform.
If the call is deemed acceptable,
such as writing a temporary file in a designated scratch directory, the call is allow-
ed to proceed.
If the call is known to be dangerous or the reference monitor cannot
tell, the applet is killed.
If the reference monitor can tell which applet called it, a
single reference monitor somewhere in memory can handle the requests from all
applets. The reference monitor normally learns about the permissions from a con-
The second way to run untrusted applets is to run them interpretively and not
let them get actual control of the hardware. This is the approach used by Web
browsers. Web page applets are commonly written in Java, which is a normal pro-
gramming language, or in a high-level scripting language such as safe-TCL or
Java Virtual Machine
). It is these JVM applets that are put
on the Web page. When they are downloaded, they are inserted into a JVM inter-
preter inside the browser as illustrated in Fig. 9-39.
The advantage of running interpreted code over compiled code is that every in-
struction is examined by the interpreter before being executed. This gives the inter-
preter the opportunity to check if the address is valid. In addition, system calls are