Port sandbox, sandbox faq, and startup design docs to markdown.
This is mostly a straight port; minimal editing was applied to the converted text to make some styles consistent. The original locations of these docs were: https://www.chromium.org/developers/design-documents/sandbox https://www.chromium.org/developers/design-documents/sandbox/Sandbox-FAQ https://www.chromium.org/developers/design-documents/startup BUG= Review-Url: https://codereview.chromium.org/2827383002 Cr-Commit-Position: refs/heads/master@{#466105}
This commit is contained in:

committed by
Commit bot

parent
a4c052f363
commit
b4730a0c27
@@ -9,5 +9,11 @@ Documents here have been imported
|
|||||||
from [the Project site](https://www.chromium.org/developers/design-documents).
|
from [the Project site](https://www.chromium.org/developers/design-documents).
|
||||||
As of this writing, the vast majority of docs have not been imported yet.
|
As of this writing, the vast majority of docs have not been imported yet.
|
||||||
|
|
||||||
|
* [Sandboxing](sandbox.md) - The Sandboxing architecture, and Windows
|
||||||
|
implementation of sandboxing.
|
||||||
|
* [Sandboxing FAQ](sandbox_faq.md) - Frequently asked questions about Chromium
|
||||||
|
sandboxing.
|
||||||
|
* [Startup](startup.md) - How browser processes starts up, on different
|
||||||
|
platforms.
|
||||||
* [Threading](threading.md) - Preferred ways to use threading, and library
|
* [Threading](threading.md) - Preferred ways to use threading, and library
|
||||||
support for concurrency.
|
support for concurrency.
|
||||||
|
491
docs/design/sandbox.md
Normal file
491
docs/design/sandbox.md
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
# Sandbox
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Security is one of the most important goals for Chromium. The key to security is
|
||||||
|
understanding: we can only truly secure a system if we fully understand its
|
||||||
|
behaviors with respect to the combination of all possible inputs in all possible
|
||||||
|
states. For a codebase as large and diverse as Chromium, reasoning about the
|
||||||
|
combined behavior of all its parts is nearly impossible. The sandbox objective
|
||||||
|
is to provide hard guarantees about what ultimately a piece of code can or
|
||||||
|
cannot do no matter what its inputs are.
|
||||||
|
|
||||||
|
Sandbox leverages the OS-provided security to allow code execution that cannot
|
||||||
|
make persistent changes to the computer or access information that is
|
||||||
|
confidential. The architecture and exact assurances that the sandbox provides
|
||||||
|
are dependent on the operating system. This document covers the Windows
|
||||||
|
implementation as well as the general design. The Linux implementation is
|
||||||
|
described [here](../linux_sandboxing.md), the OSX implementation
|
||||||
|
[here](http://dev.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design).
|
||||||
|
|
||||||
|
If you don't feel like reading this whole document you can read the
|
||||||
|
[Sandbox FAQ](sandbox_faq.md) instead. A
|
||||||
|
description of what the sandbox does and doesn't protect against may also be
|
||||||
|
found in the FAQ.
|
||||||
|
|
||||||
|
## Design principles
|
||||||
|
|
||||||
|
* **Do not re-invent the wheel:** It is tempting to extend the OS kernel with a
|
||||||
|
better security model. Don't. Let the operating system apply its security to
|
||||||
|
the objects it controls. On the other hand, it is OK to create
|
||||||
|
application-level objects (abstractions) that have a custom security model.
|
||||||
|
* **Principle of least privilege:** This should be applied both to the sandboxed
|
||||||
|
code and to the code that controls the sandbox. In other words, the sandbox
|
||||||
|
should work even if the user cannot elevate to super-user.
|
||||||
|
* **Assume sandboxed code is malicious code:** For threat-modeling purposes, we
|
||||||
|
consider the sandbox compromised (that is, running malicious code) once the
|
||||||
|
execution path reaches past a few early calls in the `main()` function. In
|
||||||
|
practice, it could happen as soon as the first external input is accepted, or
|
||||||
|
right before the main loop is entered.
|
||||||
|
* **Be nimble:** Non-malicious code does not try to access resources it cannot
|
||||||
|
obtain. In this case the sandbox should impose near-zero performance
|
||||||
|
impact. It's ok to have performance penalties for exceptional cases when a
|
||||||
|
sensitive resource needs to be touched once in a controlled manner. This is
|
||||||
|
usually the case if the OS security is used properly.
|
||||||
|
* **Emulation is not security:** Emulation and virtual machine solutions do not
|
||||||
|
by themselves provide security. The sandbox should not rely on code emulation,
|
||||||
|
code translation, or patching to provide security.
|
||||||
|
|
||||||
|
## Sandbox windows architecture
|
||||||
|
|
||||||
|
The Windows sandbox is a user-mode only sandbox. There are no special kernel
|
||||||
|
mode drivers, and the user does not need to be an administrator in order for the
|
||||||
|
sandbox to operate correctly. The sandbox is designed for both 32-bit and 64-bit
|
||||||
|
processes and has been tested on all Windows OS flavors between Windows 7 and
|
||||||
|
Windows 10, both 32-bit and 64-bit.
|
||||||
|
|
||||||
|
Sandbox operates at process-level granularity. Anything that needs to be
|
||||||
|
sandboxed needs to live on a separate process. The minimal sandbox configuration
|
||||||
|
has two processes: one that is a privileged controller known as the _broker_,
|
||||||
|
and one or more sandboxed processes known as the _target_. Throughout the
|
||||||
|
documentation and the code these two terms are used with that precise
|
||||||
|
connotation. The sandbox is provided as a static library that must be linked to
|
||||||
|
both the broker and the target executables.
|
||||||
|
|
||||||
|
### The broker process
|
||||||
|
|
||||||
|
In Chromium, the broker is always the browser process. The broker, is in broad
|
||||||
|
terms, a privileged controller/supervisor of the activities of the sandboxed
|
||||||
|
processes. The responsibilities of the broker process are:
|
||||||
|
|
||||||
|
1. Specify the policy for each target process
|
||||||
|
1. Spawn the target processes
|
||||||
|
1. Host the sandbox policy engine service
|
||||||
|
1. Host the sandbox interception manager
|
||||||
|
1. Host the sandbox IPC service (to the target processes)
|
||||||
|
1. Perform the policy-allowed actions on behalf of the target process
|
||||||
|
|
||||||
|
The broker should always outlive all the target processes that it spawned. The
|
||||||
|
sandbox IPC is a low-level mechanism (different from Chromium's IPC) that is
|
||||||
|
used to transparently forward certain windows API calls from the target to the
|
||||||
|
broker: these calls are evaluated against the policy. The policy-allowed calls
|
||||||
|
are then executed by the broker and the results returned to the target process
|
||||||
|
via the same IPC. The job of the interceptions manager is to patch the windows
|
||||||
|
API calls that should be forwarded via IPC to the broker.
|
||||||
|
|
||||||
|
### The target process
|
||||||
|
|
||||||
|
In Chromium, the renderers are always target processes, unless the
|
||||||
|
`--no-sandbox` command line has been specified for the browser process. The
|
||||||
|
target process hosts all the code that is going to run inside the sandbox, plus
|
||||||
|
the sandbox infrastructure client side:
|
||||||
|
|
||||||
|
1. All code to be sandboxed
|
||||||
|
1. The sandbox IPC client
|
||||||
|
1. The sandbox policy engine client
|
||||||
|
1. The sandbox interceptions
|
||||||
|
|
||||||
|
Items 2,3 and 4 are part of the sandbox library that is linked with the code to
|
||||||
|
be sandboxed.
|
||||||
|
|
||||||
|
The interceptions (also known as hooks) are how Windows API calls are forwarded
|
||||||
|
via the sandbox IPC to the broker. It is up to the broker to re-issue the API
|
||||||
|
calls and return the results or simply fail the calls. The interception + IPC
|
||||||
|
mechanism does not provide security; it is designed to provide compatibility
|
||||||
|
when code inside the sandbox cannot be modified to cope with sandbox
|
||||||
|
restrictions. To save unnecessary IPCs, policy is also evaluated in the target
|
||||||
|
process before making an IPC call, although this is not used as a security
|
||||||
|
guarantee but merely a speed optimization.
|
||||||
|
|
||||||
|
It is the expectation that in the future most plugins will run inside a target
|
||||||
|
process.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Sandbox restrictions
|
||||||
|
|
||||||
|
At its core, the sandbox relies on the protection provided by four Windows
|
||||||
|
mechanisms:
|
||||||
|
|
||||||
|
* A restricted token
|
||||||
|
* The Windows _job_ object
|
||||||
|
* The Windows _desktop_ object
|
||||||
|
* Windows Vista and above: The integrity levels
|
||||||
|
|
||||||
|
These mechanisms are highly effective at protecting the OS, its configuration,
|
||||||
|
and the user's data provided that:
|
||||||
|
|
||||||
|
* All the securable resources have a better than null security descriptor. In
|
||||||
|
other words, there are no critical resources with misconfigured security.
|
||||||
|
* The computer is not already compromised by malware.
|
||||||
|
* Third party software does not weaken the security of the system.
|
||||||
|
|
||||||
|
** Note that extra mitigations above and beyond this base/core will be described
|
||||||
|
in the "Process Mitigations" section below.
|
||||||
|
|
||||||
|
### The token
|
||||||
|
|
||||||
|
One issue that other similar sandbox projects face is how restricted can the
|
||||||
|
token and job be while still having a properly functioning process. For the
|
||||||
|
Chromium sandbox, the most restrictive token for Windows XP takes the following
|
||||||
|
form:
|
||||||
|
|
||||||
|
#### Regular Groups
|
||||||
|
* Logon SID : mandatory
|
||||||
|
* All other SIDs : deny only, mandatory
|
||||||
|
#### Restricted Groups
|
||||||
|
* S-1-0-0 : mandatory
|
||||||
|
#### Privileges
|
||||||
|
* None
|
||||||
|
|
||||||
|
With the caveats described above, it is near impossible to find an existing
|
||||||
|
resource that the OS will grant access with such a token. As long as the disk
|
||||||
|
root directories have non-null security, even files with null security cannot be
|
||||||
|
accessed. In Vista, the most restrictive token is the same but it also includes
|
||||||
|
the low integrity level label. The Chromium renderer normally runs with this
|
||||||
|
token, which means that almost all resources that the renderer process uses have
|
||||||
|
been acquired by the Browser and their handles duplicated into the renderer
|
||||||
|
process.
|
||||||
|
|
||||||
|
Note that the token is not derived from anonymous or from the guest token; it is
|
||||||
|
derived from the user's token and thus associated to the user logon. As a
|
||||||
|
result, any auditing that the system or the domain has in place can still be
|
||||||
|
used.
|
||||||
|
|
||||||
|
By design, the sandbox token cannot protect the following non-securable
|
||||||
|
resources:
|
||||||
|
|
||||||
|
* Mounted FAT or FAT32 volumes: The security descriptor on them is effectively
|
||||||
|
null. Malware running in the target can read and write to these volumes as
|
||||||
|
long it can guess or deduce their paths.
|
||||||
|
* TCP/IP: The security of TCP/IP sockets in Windows 2000 and Windows XP (but not
|
||||||
|
in Vista) is effectively null. It might be possible for malicious code in the
|
||||||
|
target to send and receive network packets to any host.
|
||||||
|
|
||||||
|
More information about the Windows token object can be
|
||||||
|
found
|
||||||
|
[here](http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsAToken.htm)
|
||||||
|
|
||||||
|
### The Job object
|
||||||
|
|
||||||
|
The target process also runs under a Job object. Using this Windows mechanism,
|
||||||
|
some interesting global restrictions that do not have a traditional object or
|
||||||
|
security descriptor associated with them are enforced:
|
||||||
|
|
||||||
|
* Forbid per-use system-wide changes using `SystemParametersInfo()`, which can
|
||||||
|
be used to swap the mouse buttons or set the screen saver timeout
|
||||||
|
* Forbid the creation or switch of Desktops
|
||||||
|
* Forbid changes to the per-user display configuration such as resolution and
|
||||||
|
primary display
|
||||||
|
* No read or write to the clipboard
|
||||||
|
* Forbid Windows message broadcasts
|
||||||
|
* Forbid setting global Windows hooks (using `SetWindowsHookEx()`)
|
||||||
|
* Forbid access to the global atoms table
|
||||||
|
* Forbid access to USER handles created outside the Job object
|
||||||
|
* One active process limit (disallows creating child processes)
|
||||||
|
|
||||||
|
Chromium renderers normally run with all these restrictions active. Each
|
||||||
|
renderers run in its own Job object. Using the Job object, the sandbox can (but
|
||||||
|
currently does not) prevent:
|
||||||
|
|
||||||
|
* Excessive use of CPU cycles
|
||||||
|
* Excessive use of memory
|
||||||
|
* Excessive use of IO
|
||||||
|
|
||||||
|
More information about Windows Job Objects can be
|
||||||
|
found [here](http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx)
|
||||||
|
|
||||||
|
### The alternate desktop
|
||||||
|
|
||||||
|
The token and the job object define a security boundary: that is, all processes
|
||||||
|
with the same token and in the same job object are effectively in the same
|
||||||
|
security context. However, one not-well-understood fact is that applications
|
||||||
|
that have windows on the same desktop are also effectively in the same security
|
||||||
|
context because the sending and receiving of window messages is not subject to
|
||||||
|
any security checks. Sending messages across desktops is not allowed. This is
|
||||||
|
the source of the infamous "shatter" attacks, which is why services should not
|
||||||
|
host windows on the interactive desktop. A Windows desktop is a regular kernel
|
||||||
|
object that can be created and assigned a security descriptor.
|
||||||
|
|
||||||
|
In a standard Windows installation, at least two desktops are attached to the
|
||||||
|
interactive window station; the regular (default) desktop, and the logon
|
||||||
|
desktop. The sandbox creates a third desktop that is associated to all target
|
||||||
|
processes. This desktop is never visible or interactive and effectively isolates
|
||||||
|
the sandboxed processes from snooping the user's interaction and from sending
|
||||||
|
messages to windows operating at more privileged contexts.
|
||||||
|
|
||||||
|
The only disadvantage of an alternate desktop is that it uses approximately 4MB
|
||||||
|
of RAM from a separate pool, possibly more on Vista.
|
||||||
|
|
||||||
|
More information about Window Stations
|
||||||
|
|
||||||
|
### The integrity levels
|
||||||
|
|
||||||
|
Integrity levels are available on Windows Vista and later versions. They don't
|
||||||
|
define a security boundary in the strict sense, but they do provide a form of
|
||||||
|
mandatory access control (MAC) and act as the basis of Microsoft's Internet
|
||||||
|
Explorer sandbox.
|
||||||
|
|
||||||
|
Integrity levels are implemented as a special set of SID and ACL entries
|
||||||
|
representing five levels of increasing privilege: untrusted, low, medium, high,
|
||||||
|
system. Access to an object may be restricted if the object is at a higher
|
||||||
|
integrity level than the requesting token. Integrity levels also implement User
|
||||||
|
Interface Privilege Isolation, which applies the rules of integrity levels to
|
||||||
|
window messages exchanged between different processes on the same desktop.
|
||||||
|
|
||||||
|
By default, a token can read an object of a higher integrity level, but not
|
||||||
|
write to it. Most desktop applications run at medium integrity (MI), while less
|
||||||
|
trusted processes like Internet Explorer's protected mode and our own sandbox
|
||||||
|
run at low integrity (LI). A low integrity mode token can access only the
|
||||||
|
following shared resources:
|
||||||
|
|
||||||
|
* Read access to most files
|
||||||
|
* Write access to `%USER PROFILE%\AppData\LocalLow`
|
||||||
|
* Read access to most of the registry
|
||||||
|
* Write access to `HKEY_CURRENT_USER\Software\AppDataLow`
|
||||||
|
* Clipboard (copy and paste for certain formats)
|
||||||
|
* Remote procedure call (RPC)
|
||||||
|
* TCP/IP Sockets
|
||||||
|
* Window messages exposed via `ChangeWindowMessageFilter`
|
||||||
|
* Shared memory exposed via LI (low integrity) labels
|
||||||
|
* COM interfaces with LI (low integrity) launch activation rights
|
||||||
|
* Named pipes exposed via LI (low integrity) labels
|
||||||
|
|
||||||
|
You'll notice that the previously described attributes of the token, job object,
|
||||||
|
and alternate desktop are more restrictive, and would in fact block access to
|
||||||
|
everything allowed in the above list. So, the integrity level is a bit redundant
|
||||||
|
with the other measures, but it can be seen as an additional degree of
|
||||||
|
defense-in-depth, and its use has no visible impact on performance or resource
|
||||||
|
usage.
|
||||||
|
|
||||||
|
More information on integrity levels can be
|
||||||
|
found [here](http://msdn.microsoft.com/en-us/library/bb625963.aspx).
|
||||||
|
|
||||||
|
### Process mitigation policies
|
||||||
|
|
||||||
|
Most process mitigation policies can be applied to the target process by means
|
||||||
|
of SetProcessMitigationPolicy. The sandbox uses this API to set various
|
||||||
|
policies on the target process for enforcing security characteristics.
|
||||||
|
|
||||||
|
#### Relocate Images:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* Address-load randomization (ASLR) on all images in process (and must be
|
||||||
|
supported by all images).
|
||||||
|
|
||||||
|
#### Heap Terminate:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* Terminates the process on Windows heap corruption.
|
||||||
|
|
||||||
|
#### Bottom-up ASLR:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* Sets random lower bound as minimum user address for the process.
|
||||||
|
|
||||||
|
#### High-entropy ASLR:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* Increases randomness range for bottom-up ASLR to 1TB.
|
||||||
|
|
||||||
|
#### Strict Handle Checks:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* Immediately raises an exception on a bad handle reference.
|
||||||
|
|
||||||
|
#### Win32k.sys lockdown:
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* `ProcessSystemCallDisablePolicy`, which allows selective disabling of system
|
||||||
|
calls available from the target process.
|
||||||
|
* Renderer processes now have this set to `DisallowWin32kSystemCalls` which
|
||||||
|
means that calls from user mode that are serviced by `win32k.sys` are no
|
||||||
|
longer permitted. This significantly reduces the kernel attack surface
|
||||||
|
available from a renderer. See
|
||||||
|
[here](https://docs.google.com/document/d/1gJDlk-9xkh6_8M_awrczWCaUuyr0Zd2TKjNBCiPO_G4)
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
#### App Container (low box token):
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* In Windows this is implemented at the kernel level by a Low Box token which is
|
||||||
|
a stripped version of a normal token with limited privilege (normally just
|
||||||
|
`SeChangeNotifyPrivilege` and `SeIncreaseWorkingSetPrivilege`), running at Low
|
||||||
|
integrity level and an array of "Capabilities" which can be mapped to
|
||||||
|
allow/deny what the process is allowed to do (see
|
||||||
|
[MSDN](https://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx)
|
||||||
|
for a high level description). The capability most interesting from a sandbox
|
||||||
|
perspective is denying is access to the network, as it turns out network
|
||||||
|
checks are enforced if the token is a Low Box token and the `INTERNET_CLIENT`
|
||||||
|
Capability is not present.
|
||||||
|
* The sandbox therefore takes the existing restricted token and adds the Low Box
|
||||||
|
attributes, without granting any Capabilities, so as to gain the additional
|
||||||
|
protection of no network access from the sandboxed process.
|
||||||
|
|
||||||
|
#### Disable Extension Points (legacy hooking):
|
||||||
|
|
||||||
|
* >= Win8
|
||||||
|
* `ProcessExtensionPointDisablePolicy`
|
||||||
|
* The following injection vectors are blocked:
|
||||||
|
* AppInit DLLs Winsock Layered Service Providers (LSPs)
|
||||||
|
* Global Window Hooks (not thread-targeted hooks)
|
||||||
|
* Legacy Input Method Editors (IMEs)
|
||||||
|
|
||||||
|
#### Control Flow Guard (CFG):
|
||||||
|
|
||||||
|
* >= Win8.1 Update 3 (KB3000850)
|
||||||
|
* Enabled in all chrome.exe processes. Not compiled into all chrome binaries.
|
||||||
|
* Takes advantage of CFG security in Microsoft system DLLs in our processes.
|
||||||
|
* Compiler/Linker opt-in, not a run-time policy opt-in. See
|
||||||
|
[MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/mt637065(v=vs.85).aspx).
|
||||||
|
|
||||||
|
#### Disable Font Loading:
|
||||||
|
|
||||||
|
* >= Win10
|
||||||
|
* `ProcessFontDisablePolicy`
|
||||||
|
|
||||||
|
#### Disable Image Load from Remote Devices:
|
||||||
|
|
||||||
|
* >= Win10 TH2
|
||||||
|
* `ProcessImageLoadPolicy`
|
||||||
|
* E.g. UNC path to network resource.
|
||||||
|
|
||||||
|
#### Disable Image Load of "mandatory low" (low integrity level):
|
||||||
|
|
||||||
|
* >= Win10 TH2
|
||||||
|
* `ProcessImageLoadPolicy`
|
||||||
|
* E.g. temporary internet files.
|
||||||
|
|
||||||
|
#### Extra Disable Child Process Creation:
|
||||||
|
|
||||||
|
* >= Win10 TH2
|
||||||
|
* If the Job level <= `JOB_LIMITED_USER`, set
|
||||||
|
`PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY` to
|
||||||
|
`PROCESS_CREATION_CHILD_PROCESS_RESTRICTED` via `UpdateProcThreadAttribute()`.
|
||||||
|
* This is an extra layer of defense, given that Job levels can be broken out of.
|
||||||
|
See also:
|
||||||
|
[ticket](https://bugs.chromium.org/p/project-zero/issues/detail?id=213&redir=1),
|
||||||
|
[Project Zero blog](http://googleprojectzero.blogspot.co.uk/2015/05/in-console-able.html).
|
||||||
|
|
||||||
|
### Other caveats
|
||||||
|
|
||||||
|
The operating system might have bugs. Of interest are bugs in the Windows API
|
||||||
|
that allow the bypass of the regular security checks. If such a bug exists,
|
||||||
|
malware will be able to bypass the sandbox restrictions and broker policy and
|
||||||
|
possibly compromise the computer. Under Windows, there is no practical way to
|
||||||
|
prevent code in the sandbox from calling a system service.
|
||||||
|
|
||||||
|
In addition, third party software, particularly anti-malware solutions, can
|
||||||
|
create new attack vectors. The most troublesome are applications that inject
|
||||||
|
dlls in order to enable some (usually unwanted) capability. These dlls will also
|
||||||
|
get injected in the sandbox process. In the best case they will malfunction, and
|
||||||
|
in the worst case can create backdoors to other processes or to the file system
|
||||||
|
itself, enabling specially crafted malware to escape the sandbox.
|
||||||
|
|
||||||
|
## Sandbox policy
|
||||||
|
|
||||||
|
The actual restrictions applied to a target process are configured by a
|
||||||
|
policy. The policy is just a programmatic interface that the broker calls to
|
||||||
|
define the restrictions and allowances. Four functions control the restrictions,
|
||||||
|
roughly corresponding to the four Windows mechanisms:
|
||||||
|
|
||||||
|
* `TargetPolicy::SetTokenLevel()`
|
||||||
|
* `TargetPolicy::SetJobLevel()`
|
||||||
|
* `TargetPolicy::SetIntegrityLevel()`
|
||||||
|
* `TargetPolicy::SetDesktop()`
|
||||||
|
|
||||||
|
The first three calls take an integer level parameter that goes from very strict
|
||||||
|
to very loose; for example, the token level has 7 levels and the job level has 5
|
||||||
|
levels. Chromium renderers are typically run with the most strict level in all
|
||||||
|
four mechanisms. Finally, the last (desktop) policy is binary and can only be
|
||||||
|
used to indicate if a target is run on an alternate desktop or not.
|
||||||
|
|
||||||
|
The restrictions are by design coarse in that they affect all securable
|
||||||
|
resources that the target can touch, but sometimes a more finely-grained
|
||||||
|
resolution is needed. The policy interface allows the broker to specify
|
||||||
|
exceptions. An exception is a way to take a specific Windows API call issued in
|
||||||
|
the target and proxy it over to the broker. The broker can inspect the
|
||||||
|
parameters and re-issue the call as is, re-issue the call with different
|
||||||
|
parameters, or simply deny the call. To specify exceptions there is a single
|
||||||
|
call: `AddRule`. The following kinds of rules for different Windows subsystems
|
||||||
|
are supported at this time:
|
||||||
|
|
||||||
|
* Files
|
||||||
|
* Named pipes
|
||||||
|
* Process creation
|
||||||
|
* Registry
|
||||||
|
* Synchronization objects
|
||||||
|
|
||||||
|
The exact form of the rules for each subsystem varies, but in general rules are
|
||||||
|
triggered based on a string pattern. For example, a possible file rule is:
|
||||||
|
|
||||||
|
AddRule(SUBSYS_FILES, FILES_ALLOW_READONLY, L"c:\\temp\\app_log\\d*.dmp")
|
||||||
|
|
||||||
|
This rule specifies that access will be granted if a target wants to open a
|
||||||
|
file, for read-only access as long as the file matches the pattern expression;
|
||||||
|
for example `c:\temp\app_log\domino.dmp` is a file that satisfies the
|
||||||
|
pattern. Consult the header files for an up-to-date list of supported objects
|
||||||
|
and supported actions.
|
||||||
|
|
||||||
|
Rules can only be added before each target process is spawned, and cannot be
|
||||||
|
modified while a target is running, but different targets can have different
|
||||||
|
rules.
|
||||||
|
|
||||||
|
## Target bootstrapping
|
||||||
|
|
||||||
|
Targets do not start executing with the restrictions specified by policy. They
|
||||||
|
start executing with a token that is very close to the token the regular user
|
||||||
|
processes have. The reason is that during process bootstrapping the OS loader
|
||||||
|
accesses a lot of resources, most of them are actually undocumented and can
|
||||||
|
change at any time. Also, most applications use the standard CRT provided with
|
||||||
|
the standard development tools; after the process is bootstrapped the CRT needs
|
||||||
|
to initialize as well and there again the internals of the CRT initialization
|
||||||
|
are undocumented.
|
||||||
|
|
||||||
|
Therefore, during the bootstrapping phase the process actually uses two tokens:
|
||||||
|
the lockdown token which is the process token as is and the initial token which
|
||||||
|
is set as the impersonation token of the initial thread. In fact the actual
|
||||||
|
`SetTokenLevel` definition is:
|
||||||
|
|
||||||
|
SetTokenLevel(TokenLevel initial, TokenLevel lockdown)
|
||||||
|
|
||||||
|
After all the critical initialization is done, execution continues at `main()`
|
||||||
|
or `WinMain()`, here the two tokens are still active, but only the initial
|
||||||
|
thread can use the more powerful initial token. It is the target's
|
||||||
|
responsibility to discard the initial token when ready. This is done with a
|
||||||
|
single call:
|
||||||
|
|
||||||
|
LowerToken()
|
||||||
|
|
||||||
|
After this call is issued by the target the only token available is the lockdown
|
||||||
|
token and the full sandbox restrictions go into effect. The effects of this call
|
||||||
|
cannot be undone. Note that the initial token is a impersonation token only
|
||||||
|
valid for the main thread, other threads created in the target process use only
|
||||||
|
the lockdown token and therefore should not attempt to obtain any system
|
||||||
|
resources subject to a security check.
|
||||||
|
|
||||||
|
The fact that the target starts with a privileged token simplifies the explicit
|
||||||
|
policy since anything privileged that needs to be done once, at process startup
|
||||||
|
can be done before the `LowerToken()` call and does not require to have rules in
|
||||||
|
the policy.
|
||||||
|
|
||||||
|
**Important**
|
||||||
|
|
||||||
|
Make sure any sensitive OS handles obtained with the initial token are closed
|
||||||
|
before calling LowerToken(). Any leaked handle can be abused by malware to
|
||||||
|
escape the sandbox.
|
||||||
|
|
||||||
|
|
||||||
|
|
125
docs/design/sandbox_faq.md
Normal file
125
docs/design/sandbox_faq.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
# Sandbox FAQ
|
||||||
|
|
||||||
|
[TOC]
|
||||||
|
|
||||||
|
### What is the sandbox?
|
||||||
|
|
||||||
|
The sandbox is a C++ library that allows the creation of sandboxed processes —
|
||||||
|
processes that execute within a very restrictive environment. The only resources
|
||||||
|
sandboxed processes can freely use are CPU cycles and memory. For example,
|
||||||
|
sandboxes processes cannot write to disk or display their own windows. What
|
||||||
|
exactly they can do is controlled by an explicit policy. Chromium renderers are
|
||||||
|
sandboxed processes.
|
||||||
|
|
||||||
|
### What does and doesn't it protect against?
|
||||||
|
|
||||||
|
The sandbox limits the severity of bugs in code running inside the sandbox. Such
|
||||||
|
bugs cannot install persistent malware in the user's account (because writing to
|
||||||
|
the filesystem is banned). Such bugs also cannot read and steal arbitrary files
|
||||||
|
from the user's machine.
|
||||||
|
|
||||||
|
(In Chromium, the renderer processes are sandboxed and have this
|
||||||
|
protection. After the NPAPI removal, all remaining plugins are also
|
||||||
|
sandboxed. Also note that Chromium renderer processes are isolated from the
|
||||||
|
system, but not yet from the web. Therefore, domain-based data isolation is not
|
||||||
|
yet provided.).
|
||||||
|
|
||||||
|
The sandbox cannot provide any protection against bugs in system components such
|
||||||
|
as the kernel it is running on.
|
||||||
|
|
||||||
|
### Is the sandbox like what you get with the Java VM?
|
||||||
|
|
||||||
|
Yeah, kind of... except that to take advantage of the Java sandbox, you must
|
||||||
|
rewrite your code to use Java. With our sandbox you can add sandboxing to your
|
||||||
|
existing C/C++ applications. Because the code is not executed inside a virtual
|
||||||
|
machine, you get native speed and direct access to the Windows API.
|
||||||
|
|
||||||
|
### Do I need to install a driver or kernel module? Does the user need to be Administrator?
|
||||||
|
|
||||||
|
No and no. The sandbox is a pure user-mode library, and any user can run
|
||||||
|
sandboxed processes.
|
||||||
|
|
||||||
|
### How can you do this for C++ code if there is no virtual machine?
|
||||||
|
|
||||||
|
We leverage the Windows security model. In Windows, code cannot perform any form
|
||||||
|
of I/O (be it disk, keyboard, or screen) without making a system call. In most
|
||||||
|
system calls, Windows performs some sort of security check. The sandbox sets
|
||||||
|
things up so that these security checks fail for the kinds of actions that you
|
||||||
|
don’t want the sandboxed process to perform. In Chromium, the sandbox is such
|
||||||
|
that all access checks should fail.
|
||||||
|
|
||||||
|
### So how can a sandboxed process such as a renderer accomplish anything?
|
||||||
|
|
||||||
|
Certain communication channels are explicitly open for the sandboxed processes;
|
||||||
|
the processes can write and read from these channels. A more privileged process
|
||||||
|
can use these channels to do certain actions on behalf of the sandboxed
|
||||||
|
process. In Chromium, the privileged process is usually the browser process.
|
||||||
|
|
||||||
|
### Doesn't Vista have similar functionality?
|
||||||
|
|
||||||
|
Yes. It's called integrity levels (ILs). The sandbox detects Vista and uses
|
||||||
|
integrity levels, as well. The main difference is that the sandbox also works
|
||||||
|
well under Windows XP. The only application that we are aware of that uses ILs
|
||||||
|
is Internet Explorer 7. In other words, leveraging the new Vista security
|
||||||
|
features is one of the things that the sandbox library does for you.
|
||||||
|
|
||||||
|
### This is very neat. Can I use the sandbox in my own programs?
|
||||||
|
|
||||||
|
Yes. The sandbox does not have any hard dependencies on the Chromium browser and
|
||||||
|
was designed to be used with other Internet-facing applications. The main hurdle
|
||||||
|
is that you have to split your application into at least two interacting
|
||||||
|
processes. One of the processes is privileged and does I/O and interacts with
|
||||||
|
the user; the other is not privileged at all and does untrusted data processing.
|
||||||
|
|
||||||
|
### Isn't that a lot of work?
|
||||||
|
|
||||||
|
Possibly. But it's worth the trouble, especially if your application processes
|
||||||
|
arbitrary untrusted data. Any buffer overflow or format decoding flaw that your
|
||||||
|
code might have won't automatically result in malicious code compromising the
|
||||||
|
whole computer. The sandbox is not a security silver bullet, but it is a strong
|
||||||
|
last defense against nasty exploits.
|
||||||
|
|
||||||
|
### Should I be aware of any gotchas?
|
||||||
|
|
||||||
|
Well, the main thing to keep in mind is that you should only sandbox code that
|
||||||
|
you fully control or that you fully understand. Sandboxing third-party code can
|
||||||
|
be very difficult. For example, you might not be aware of third-party code's
|
||||||
|
need to create temporary files or display warning dialogs; these operations will
|
||||||
|
not succeed unless you explicitly allow them. Furthermore, third-party
|
||||||
|
components could get updated on the end-user machine with new behaviors that you
|
||||||
|
did not anticipate.
|
||||||
|
|
||||||
|
### How about COM, Winsock, or DirectX — can I use them?
|
||||||
|
|
||||||
|
For the most part, no. We recommend against using them before lock-down. Once a
|
||||||
|
sandboxed process is locked down, use of Winsock, COM, or DirectX will either
|
||||||
|
malfunction or outright fail.
|
||||||
|
|
||||||
|
### What do you mean by before _lock-down_? Is the sandboxed process not locked down from the start?
|
||||||
|
|
||||||
|
No, the sandboxed process does not start fully secured. The sandbox takes effect
|
||||||
|
once the process makes a call to the sandbox method `LowerToken()`. This allows
|
||||||
|
for a period during process startup when the sandboxed process can freely get
|
||||||
|
hold of critical resources, load libraries, or read configuration files. The
|
||||||
|
process should call `LowerToken()` as soon as feasible and certainly before it
|
||||||
|
starts interacting with untrusted data.
|
||||||
|
|
||||||
|
**Note:** Any OS handle that is left open after calling `LowerToken()` can be
|
||||||
|
abused by malware if your process gets infected. That's why we discourage
|
||||||
|
calling COM or other heavyweight APIs; they leave some open handles around for
|
||||||
|
efficiency in later calls.
|
||||||
|
|
||||||
|
### So what APIs can you call?
|
||||||
|
|
||||||
|
There is no master list of safe APIs. In general, structure your code such that
|
||||||
|
the sandboxed code reads and writes from pipes or shared memory and just does
|
||||||
|
operations over this data. In the case of Chromium, the entire WebKit code runs
|
||||||
|
this way, and the output is mostly a rendered bitmap of the web pages. You can
|
||||||
|
use Chromium as inspiration for your own memory- or pipe-based IPC.
|
||||||
|
|
||||||
|
### But can't malware just infect the process at the other end of the pipe or shared memory?
|
||||||
|
|
||||||
|
Yes, it might, if there's a bug there. The key point is that it's easier to
|
||||||
|
write and analyze a correct IPC mechanism than, say, a web browser
|
||||||
|
engine. Strive to make the IPC code as simple as possible, and have it reviewed
|
||||||
|
by others.
|
BIN
docs/design/sandbox_top_diagram.png
Normal file
BIN
docs/design/sandbox_top_diagram.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 22 KiB |
45
docs/design/startup.md
Normal file
45
docs/design/startup.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Startup
|
||||||
|
|
||||||
|
Chrome is (mostly) shipped as a single executable that knows how to run as all
|
||||||
|
the interesting sorts of processes we use.
|
||||||
|
|
||||||
|
Here's an overview of how that works.
|
||||||
|
|
||||||
|
1. First there's the platform-specific entry point: `wWinMain()` on Windows,
|
||||||
|
`main()` on Linux. This lives in `chrome/app/chrome_exe_main_*`. On Mac and
|
||||||
|
Windows, that function loads modules as described later, while on Linux it
|
||||||
|
does very little, and all of them call into:
|
||||||
|
2. `ChromeMain()`, which is the place where cross-platform code that needs to
|
||||||
|
run in all Chrome processes lives. It lives in `chrome/app/chrome_main*`.
|
||||||
|
For example, here is where we call initializers for modules like logging and
|
||||||
|
ICU. We then examine the internal `--process-type` switch and dispatch to:
|
||||||
|
3. A process-type-specific main function such as `BrowserMain()` (for the outer
|
||||||
|
browser process) or `RendererMain()` (for a tab-specific renderer process).
|
||||||
|
|
||||||
|
## Platform-specific entry points
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
On Windows we build the bulk of Chrome as a DLL. (XXX: why?) `wWinMain()`
|
||||||
|
loads `chrome.dll`, does some other random stuff (XXX: why?) and calls
|
||||||
|
`ChromeMain()` in the DLL.
|
||||||
|
|
||||||
|
### Mac
|
||||||
|
|
||||||
|
Mac is also packaged as a framework and an executable, but they're linked
|
||||||
|
together: `main()` calls `ChromeMain()` directly. There is also a second entry
|
||||||
|
point, in
|
||||||
|
[`chrome_main_app_mode_mac.mm`](https://cs.chromium.org/chromium/src/chrome/app_shim/chrome_main_app_mode_mac.mm),
|
||||||
|
for app mode shortcuts: "On Mac, one can't make shortcuts with command-line
|
||||||
|
arguments. Instead, we produce small app bundles which locate the Chromium
|
||||||
|
framework and load it, passing the appropriate
|
||||||
|
data." This executable also calls `ChromeMain()`.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
On Linux due to the sandbox we launch subprocesses by repeatedly forking from a
|
||||||
|
helper process. This means that new subprocesses don't enter through main()
|
||||||
|
again, but instead resume from clones in the middle of startup. The initial
|
||||||
|
launch of the helper process still executes the normal startup path, so any
|
||||||
|
initialization that happens in `ChromeMain()` will have been run for all
|
||||||
|
subprocesses but they will all share the same initialization.
|
Reference in New Issue
Block a user