## Overview

We have prepared a few examples to demonstrate how to use Sandbox2 in different scenarios and how to write policies.

You can find them in [//sandboxed_api/sandbox2/examples](https://github.com/google/sandboxed-api/blob/master/sandboxed_api/sandbox2/examples), see below for detailed explanations.

## CRC4

The CRC4 example is an intentionally buggy calculation of a CRC4 checksum, which demonstrates how to sandbox another program and how to communicate with it.

- [crc4bin.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/crc4/crc4bin.cc): The program we want to sandbox (i.e. the Sandboxee)
- [crc4sandbox.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/crc4/crc4sandbox.cc): The sandbox program that will run it (i.e. the executor).

### How it works:

1. The executor starts the Sandboxee from its file path using `::sandbox2::GetDataDependencyFilePath()`.
2. The executor sends input to the Sandboxee over the communication channel `Comms` using `SendBytes()`.
3. The Sandboxee calculates the CRC4 and sends its replies back to the executor over the communication channel `Comms` which receives it with `RecvUint32()`.

If the program makes any syscall other than communicating (`read()` and `write()`), it is killed due to a policy violation.

## static

The static example demonstrates how to sandbox a statically linked binary, such as a third-party binary for which you do not have the source, meaning it is not aware that it will be sandboxed.

- [static_bin.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/static/static_bin.cc): The Sandboxee is a static C binary that converts ASCII text from standard input to uppercase.
- [static_sandbox.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/static/static_sandbox.cc): The executor with its policy, limits, and using a file descriptor for Sandboxee input.

### How it works:

1. The executor starts the Sandboxee from its file path using `GetDataDependencyFilepath`, just like for CRC4.
2. It sets up limits, opens a file descriptor on `/proc/version`, and marks it to be mapped in the Sandboxee with `MapFd`.
3. The policy allows some syscalls (`open`) to return an error (`ENOENT`) rather than being killed due to a policy violation. This can be useful when sandboxing a third-party program where we cannot modify which syscalls are made, so instead we can make them fail gracefully.

## tool

The tool example is both a tool to develop your own policies and experiment with Sandbox2 APIs, as well as a demonstration of its features.

- [sandbox2tool.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/tool/sandbox2tool.cc): The executor demonstrating:
  - how to run another binary sandboxed,
  - how to set up filesystem checks, and
  - how the executor can run the Sandboxee asynchronously to read its output progressively.

Try it yourself:

### Bazel

    bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
    --sandbox2tool_resolve_and_add_libraries \
    --sandbox2tool_additional_bind_mounts /etc \
    /bin/cat /etc/hostname

### CMake + Ninja

    cd build-dir
    ninja sandbox2_sandbox2tool && \
    ./sandbox2_sandbox2tool \
    --sandbox2tool_resolve_and_add_libraries \
    --sandbox2tool_additional_bind_mounts /etc \
    /bin/cat /etc/hostname

### Google3 (Blaze)

    blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
     --sandbox2tool_resolve_and_add_libraries \
     --sandbox2tool_additional_bind_mounts /etc \
     /bin/cat /etc/hostname

Flags:

- `--sandbox2tool_resolve_and_add_libraries` to resolve and mount the required libraries for the Sandboxee
- `--sandbox2tool_additional_bind_mounts <PATHS>` to make additional directories available to the Sandboxee
- `--sandbox2tool_keep_env` to keep current environment variables
- `--sandbox2tool_redirect_fd1` to receive the Sandboxee `STDOUT_FILENO (1)` and output it locally
- `--sandbox2tool_cpu_timeout` to set CPU timeout in seconds
- `--sandbox2tool_walltime_timeout` to set wall-time timeout in seconds
- `--sandbox2tool_file_size_creation_limit` to set the maximum size of created files
- `--sandbox2tool_cwd` to set the sandbox's current working directory

## custom_fork

The `custom_fork` example demonstrates how to create a sandbox which will initialize the binary, and then wait for `fork()` requests coming from the parent executor.

This mode offers potentially increased performance with regard to other types of sandboxing, as here, creating new instances of Sandboxees doesn't require executing new binaries, just forking the existing ones

- [custom_fork_bin.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/custom_fork/custom_fork_bin.cc): The custom fork-server, receiving requests to `fork()` (via `ForkingClient::EnterForkLoop`) in order to spawn new Sandboxees.
- [custom_fork_sandbox.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/custom_fork/custom_fork_sandbox.cc): The executor, which starts a custom fork server. Then it sends requests to it (via new executors) to spawn (via `fork()`) new Sandboxees.

## network

The network namespace, which is enabled by default, prevents the sandboxed process from connecting to the outside world. This example demonstrates how to deal with this problem.

A connection is initialized inside the executor and the resulting socket is passed via `::sandbox2::Comms::SendFD()`. The Sandboxee receives the socket by using `::sandbox2::Comms::RecvFD()` and then it can use this socket to exchange the data as usual.

- [network_bin.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/network/network_bin.cc): The program we want to sandbox (i.e. the Sandboxee).
- [network_sandbox.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/network/network_sandbox.cc): The sandbox program that will run it (i.e. the executor).

## network_proxy

This example demonstrates an alternative way of dealing with a network namespace. Internally, it works in exactly the same way as the above example, but is exposed as a more convenient API.

The Sandboxee can establish a network connection in 2 different ways:

- **automatic** -- By installing an automatic handler and then issuing regular connect calls.
- **manual** -- By obtaining a `NetworkProxyClient` and directly using `NetworkProxyClient::Connect`.

This example shows both methods. Automatic mode is used when the `connect_with_handler` flag is set, otherwise manual mode is used.

- [network_bin.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_bin.cc): The program we want to sandbox (i.e. the Sandboxee).
- [network_sandbox.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_sandbox.cc): The sandbox program that will run it (the executor).