On this page, you will learn how to create your own sandboxed C/C++ library with Sandboxed API (SAPI). Use it as a guide alongside the [examples](https://developers.google.com/code-sandboxing/sandboxed-api/examples) and code documentation in the header files.

## Build Dependencies

The following dependencies must be installed on the system:

- Linux kernel with support for UTS, IPC, user, PID, and network namespaces
- Linux userspace API headers
- To compile your code: GCC 6 (version 7 or higher preferred) or Clang 7 (or higher)
- For auto-generating header files: Clang Python Bindings
- Python 3.5 or later
- [Bazel](https://bazel.build/) version 2.2.0 or [CMake](https://cmake.org/) version 3.12 or higher.
  - CMake only: [GNU Make](https://www.gnu.org/software/make/) or a version of the libcap library headers and a build tool such as [Ninja](https://ninja-build.org/) (recommended).

### Using Bazel

Bazel is the recommended build system and is the easiest to integrate with.

Our documentation uses the Clang compiler. If you need a specific toolchain (e.g. compiler, linker, etc.), refer to the [Bazel documentation](https://docs.bazel.build/versions/master/bazel-overview.html) for information on how to change the default compiler toolchain.

### Debian 10 (Buster)

To install build dependencies:

    echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \
      sudo tee /etc/apt/sources.list.d/bazel.list
    wget -qO - https://releases.bazel.build/bazel-release.pub.gpg | sudo apt-key add -
    sudo apt-get update
    sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \
      python3-pip libclang-dev
    pip3 install clang

### Gentoo

Kernel options required:

    General setup  --->
    -*- Namespaces support
    [*]   UTS namespace
    [*]   IPC namespace
    [*]   User namespace (EXPERIMENTAL)
    [*]   PID Namespaces
    [*]   Network namespace

To install build dependencies:

    emerge dev-util/bazel dev-python/typing dev-python/clang-python

### Using CMake

[CMake](https://cmake.org/) is a popular open-source meta build system that generates project files for build tools such as [Ninja](https://ninja-build.org/) or [Make](https://www.gnu.org/software/make/).

### Debian 10 (Buster)

To install build dependencies:

    sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \
      python3 python3-pip libclang-dev libcap-dev
    pip3 install absl-py clang

### Gentoo

Kernel options required:

    General setup  --->
    -*- Namespaces support
    [*]   UTS namespace
    [*]   IPC namespace
    [*]   User namespace (EXPERIMENTAL)
    [*]   PID Namespaces
    [*]   Network namespace

To install build dependencies:

    emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
    dev-python/clang-python

## Development Process

To sandbox a C/C++ library, you will have to prepare two items for your project:

- The [Sandboxed Library](https://developers.google.com/code-sandboxing/sandboxed-api)
- The [Host Code](https://developers.google.com/code-sandboxing/sandboxed-api/explained#host_code) which will make use of the functionality exposed by your Sandboxed Library. SAPI will generate the [SAPI Object and RPC Stub](https://developers.google.com/code-sandboxing/sandboxed-api/explained#sapi_object_and_rpc_stub) automatically for you during the build process.

You may be familiar with the [zlib from the Sandbox2 examples](https://github.com/google/sandboxed-api/tree/main/sandboxed_api/sandbox2/examples/zlib) here a whole program ([zpipe.c](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/sandbox2/examples/zlib/zpipe.c)) was sandboxed. In the following steps, you will learn how to use SAPI to [sandbox the zlib](https://developers.google.com/code-sandboxing/sandboxed-api/examples#zlib) library and make use of the Sandboxed Library.

### 1. Decide which functions are needed

If you look at the zlib host code ([main_zlib.cc](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/examples/zlib/main_zlib.cc)), you can see that the tool's functionality is to read data from stdin and use zlib's `deflate()` function to compress the data until an `EOF` marker is read. In total, the program uses three functions from zlib:

- `deflateInit_()`: To initialize for compression
- `deflate()`: To perform the compression operation on the data chunk
- `deflateEnd()`: To end the compression and free dynamically allocated data structures

In a real life example you would review the C/C++ library and decide which functions are needed. A possible strategy is to start with the Host Code and use the library unsandboxed. Then, in a second step, you could generate the Sandboxed Library and adapt the Host Code to use the sandboxed function calls.

### 2. Write the sapi_library Build Rule

After you have identified the three zlib functions that are needed from the sandboxed zlib library, you can define the build rule in the [BUILD](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/examples/zlib/BUILD.bazel) file. The documentation for the `sapi_library` build rule can be found on the [Build Rules](https://developers.google.com/code-sandboxing/sandboxed-api/build-rules) page.

The code snippet below shows the `sapi_library` definition for the zlib SAPI example. Using the `lib` attribute, Bazel is instructed to look in the [WORKSPACE](https://github.com/google/sandboxed-api/blob/main/WORKSPACE) file for the zlib library.

    sapi_library(
        name = "zlib-sapi",
        srcs = [],
        hdrs = [],
        functions = [
            "deflateInit_",
            "deflate",
            "deflateEnd",
        ],
        lib = "@net_zlib//:zlib",
        lib_name = "Zlib",
        namespace = "sapi::zlib",
    )

The result is that the sandboxed zlib library is generated. The output is the SAPI Object which can be included into the Host Code and be used to communicate with the sandboxed library via RPC calls. The Sandbox Policy used in this example is the default policy.

### 3. Write or Change the Host Code

It's now time to incorporate the generated SAPI Library into the Host Code.

#### Create the Sandbox

Use `sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());` to create a sandbox object.

Use `sapi::zlib::ZlibApi api(&sandbox);` to instantiate the SAPI Object and thus make the sandboxed functions available for use.

#### Use SAPI Types

[SAPI Types](https://developers.google.com/code-sandboxing/sandboxed-api/variables#sapi_types) are special types in the form of C++ classes that SAPI provides because sometimes regular C-types will not work.

The first use of a SAPI type can be observed in the declaration of `strm`, where a SAPI Struct is used: `sapi::v::Struct<sapi::zlib::z_stream> strm;`

The template type (`sapi::zlib::z_stream`) is a good example of code automatically generated by the build rule.

Take a look at the [Variables page](https://developers.google.com/code-sandboxing/sandboxed-api/variables) for more details.

#### Make API Calls

To make calls to either `defalteInit_`, `deflate`, or `deflateEnd`, use the SAPI Object. If you decide to use the 'change' approach, you have to make sure that the function parameters match the expected values.

An example of each of the calls in the [zlib example](https://developers.google.com/code-sandboxing/sandboxed-api/examples#zlib):

-

  ```
  api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
      version.PtrBefore(), sizeof(sapi::zlib::z_stream));
  ```
-

  ```
  api.deflate(strm.PtrBoth(), flush);
  ```
-

  ```
  api.deflateEnd(strm.PtrBoth()).IgnoreError();
  ```

#### Using SAPI Transactions

SAPI isolates the Host Code from the Sandboxed Library and gives the caller the ability to restart or abort problematic data processing requests. SAPI Transaction goes one step further and automatically repeats failed processes.

Take a look at the [SAPI Transactions Page](https://developers.google.com/code-sandboxing/sandboxed-api/transactions) for more details.

## Examples

Under [Examples](https://developers.google.com/code-sandboxing/sandboxed-api/examples) you can find a few libraries, already prepared by the SAPI team.