Section 1. 1 describes our threat model. Section 2 develops
some essential concepts for the NaCla system architecture
and programming model. Section 3 gives additional implementation details, organized around major system components. Section 4 provides a quantitative evaluation of the
system using more realistic applications and application
components. In Section 5, we discuss some implications of
this work. Section 6 discusses relevant prior and contemporary systems. Section 7 offers our conclusion.
1. 1. Threat model
Native Client should run untrusted modules from any Web
site with safety comparable to systems such as JavaScript.
When presented to the system, an untrusted NaCl module may contain arbitrary code and data. A consequence
is that the NaCl runtime must be able to confirm that the
module conforms to our validity rules (detailed below).
Modules that do not conform to these rules are rejected by
the system.
Once a conforming NaCl module is accepted for execution, the NaCl runtime must constrain its activity to prevent unintended side effects, such as might be achieved via
unmoderated access to the native operating system’s system call interface. The NaCl module may arbitrarily combine the entire variety of behaviors permitted by the NaCl
execution environment in attempting to compromise the
system. It may execute any reachable instruction block in
the validated text segment. It may exercise the NaCl application binary interface to access runtime services in any
way: passing invalid arguments, etc. It may also send arbitrary data via our intermodule communication interface,
with the communicating peer responsible for validating
input. The NaCl module may allocate memory and spawn
threads up to resource limits. It may attempt to exploit race
conditions in subverting the system.
The next sections detail how our architecture and code
validity rules create a sandbox that effectively contains
NaCl modules.
2. s Ys Tem ARcHi Tec TuRe
A NaCl application is composed of a collection of trusted
and untrusted components. Figure 1 shows the structure
of a hypothetical NaCl-based application for managing
and sharing photos. It consists of two components: a user
interface, implemented in JavaScript and executing in the
Web browser, and an image processing library (imglib.
nexe), implemented as a NaCl module. In this hypothetical
scenario, the user interface and image processing library
are part of the application and therefore untrusted. The
browser component is constrained by the browser execution environment and the image library is constrained
by the NaCl container. Both components are portable
across operating systems and browsers, with native code
portability enabled by Native Client. Prior to running the
photo application, the user has installed Native Client as a
browser plug-in. Note that the NaCl browser plug-in itself
is OS and browser specific. Also note it is trusted, that is, it
figure 1. Hypothetical nacl-based application. untrusted modules
have a gray background.
Browser
User interface
HTML and
JavaScript
SRPC
NPAPI
IMC
imglib.nexe
Service runtime
has full access to the OS system call interface and the user
trusts it to not be abusive.
When the user navigates to the Web site that hosts the
photo application, the browser loads and executes the
application JavaScript components. The JavaScript in
turn invokes the NaCl browser plug-in to load the image
processing library into a NaCl container. Observe that the
native code module is loaded silently—no pop-up window
asks for permission. Native Client is responsible for constraining the behavior of the untrusted module.
Each component runs in its own private address space.
Inter-component communication is based on Native
Client’s reliable datagram service, the IMC (Inter-Module
Communications). For communications between the
browser and a NaCl module, Native Client provides two
options: a Simple Remote Procedure Call (SRPC) facility,
and NPAPI, both implemented on top of the IMC. The IMC
also provides shared memory segments and shared synchronization objects, intended to avoid messaging overhead for high-volume or high-frequency communications.
The NaCl module also has access to a “service runtime”
interface, providing for memory management operations,
thread creation, and other system services. This interface
is analogous to the system call interface of a conventional
operating system.
In this paper we use “NaCl module” to refer to untrusted
native code. Note however that applications can use multiple NaCl modules, and that both trusted and untrusted
components may use the IMC. For example, the user of
the photo application might optionally be able to use a
(hypothetical) trusted NaCl service for local storage of
images, illustrated in Figure 2. Because it has access to
local disk, the storage service must be installed as a native
browser plug-in; it cannot be implemented as a NaCl module. Suppose the photo application has been designed to
optionally use the stable storage service; the user interface
would check for the stable storage plug-in during initialization. If it detected the storage service plug-in, the user interface would establish an IMC communications channel to it,
and pass a descriptor for the channel to the image library,
enabling the image library and the storage service to communicate directly via IMC-based services (SRPC, shared
memory, etc.). In this case the NaCl module will typically be
statically linked against a library that provides a procedural
interface for accessing the storage service, hiding details
of the IMC-level communications such as whether it uses