forked from bazelbuild/bazel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
-- MOS_MIGRATED_REVID=102838733
- Loading branch information
Showing
1 changed file
with
84 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
--- | ||
layout: posts | ||
title: About Sandboxing | ||
--- | ||
|
||
We've only added sandboxing to Bazel two weeks ago, and we've already seen a | ||
flurry of fixes to almost all of the rules to conform with the additional | ||
restrictions imposed by it. | ||
|
||
## What is sandboxing? | ||
Sandboxing is the technique of restricting the access rights of a process. In | ||
the context of Bazel, we're mostly concerned with restricting file system | ||
access. More specifically, Bazel's file system sandbox contains only known | ||
inputs, such that compilers and other tools can't even see files they should | ||
not access. | ||
|
||
(We currently also mount a number of system directories into the sandbox to | ||
allow running locally installed tools and make it easier to write shell | ||
scripts. See below.) | ||
|
||
|
||
## Why are we sandboxing in Bazel? | ||
We believe that developers should never have to worry about correctness, and | ||
that every build should result in the same output, regardless of the current | ||
state of the output tree. If a compiler or tool reads a file without Bazel | ||
knowing it, then Bazel won't rerun the action if that file has changed, leading | ||
to incorrect incremental builds. | ||
|
||
We would also like to support remote caching in Bazel, where incorrect reuse of | ||
cache entries is even more of a problem than on the local machine. A bad cache | ||
entry in a shared cache affects every developer on the project, and the | ||
equivalent of 'bazel clean', namely wiping the entire remote cache, rather | ||
defeats the purpose. | ||
|
||
In addition, sandboxing is closely related to remote execution. If the build | ||
works well with sandboxing, then it will likely work well with remote | ||
execution - if we know all the inputs, we can just as well upload them to a | ||
remote machine. Uploading all files (including local tools) can significantly | ||
reduce maintenance costs for compile clusters compared to having to install the | ||
tools on every machine in the cluster every time you want to try out a new | ||
compiler or make a change to an existing tool. | ||
|
||
|
||
## How does it work? | ||
On Linux, we're using user namespaces, which are available in Linux 3.8 and | ||
later. Specifically, we create a new mount namespace. We create a temporary | ||
directory into which we mount all the files that the subprocess is allowed to | ||
see. We then use `pivot_root` to make the temporary directory appear as the | ||
root directory for all subprocesses. | ||
|
||
We also mount `/proc`, `/dev/null`, `/dev/zero`, and a temporary filesystem | ||
(tmpfs) on `/tmp`. We mount `/dev/random` and `/dev/urandom`, but recommend | ||
against their usage, as it can lead to non-reproducible builds. | ||
|
||
We currently also mount `/bin`, `/etc`, `/usr` (except `/usr/local`), and every | ||
directory starting with `/lib`, to allow running local tools. In the future, we | ||
are planning to provide a shell with a set of Linux utilities, and to require | ||
that all other tools are specified as inputs. | ||
|
||
|
||
## What about Mac and Windows? | ||
We are planning to implement sandboxing for OS X (using OS X sandboxing, see | ||
our [roadmap](/roadmap.html)) and eventually Windows as well. | ||
|
||
|
||
## What about networking? | ||
At some point, we'd like to also reduce network access, probably also using | ||
namespaces, with a separate opt-out mechanism. | ||
|
||
|
||
## How do I opt-out of sandboxing? | ||
Preferably, you should make all your rules and scripts work properly with | ||
sandboxing. If you need to opt out, you should talk to us first - at Google, | ||
the vast majority of actions is fully sandboxed, so we have some experience | ||
with how to make it work. For example, Bazel has a special mechanism to add | ||
information about the current user, date, time, or the current source control | ||
revision to generated binaries. | ||
|
||
If you still need to opt out for individual rules, you can add the `local = 1` | ||
attribute to `genrule` or `*_test` calls. | ||
|
||
If you're writing a custom rule in Skylark, then you cannot currently opt out. | ||
Instead, please [file a bug](https://github.com/bazelbuild/bazel/issues) and | ||
we'll help you make it work. |