Introduction
============

*out-of-tree* is written in *Go*, it uses *Docker* for generating
kernel/filesystem images and *Qemu* for virtualization.

Also it possible to generate kernels from the host system and use the
custom one.

*out-of-tree* supports *GNU/Linux* (usually it's tested on NixOS and
latest Ubuntu LTS) and *macOS*. Technically all systems that supported
by Go, Docker, and Qemu must work well. Create the issue if you'll
notice any issue in integration for your operating system.

All *Qemu* interaction is stateless.

*out-of-tree* is allow and require metadata (``.out-of-tree.toml``)
for work. TOML (Tom's Obvious, Minimal Language) is used for kernel
module/exploit description.

``.out-of-tree.toml`` is mandatory, you need to have in the current
directory (usually, it's a project of kernel module/exploit) or use
the ``--path`` flag.

Files
-----

All data is stored in ``~/.out-of-tree/``.

- *db.sqlite* contains logs related to run with ``out-of-tree pew``,
  debug mode (``out-of-tree debug``) is not store any data.

- *images* used for filesystem images (rootfs images that used for
  ``qemu -hda ...``) that can be generated with the
  ``tools/qemu-*-img/...``.

- *kernels* stores all kernel ``vmlinuz/initrd/config/...`` files that
  generated previously with a some *Docker magic*.

- *kernels.toml* contains metadata for generated kernels. It's not
  supposed to be edited by hands.

- *kernels.user.toml* is default path for custom kernels definition.

- *Ubuntu* (or *Centos*/*Debian*/...) is the Dockerfiles tree
  (DistroName/DistroVersion/Dockerfile). Each Dockerfile contains a
  base layer and incrementally updated list of kernels that must be
  installed.

Overview
---------

*out-of-tree* creating debugging environment based on **defined** kernels::

    $ out-of-tree debug --kernel 'Ubuntu:4.15.0-58-generic'
    [*] KASLR SMEP SMAP
    [*] gdb is listening on tcp::1234
    [*] build result copied to /tmp/exploit

    ssh -o StrictHostKeyChecking=no -p 29308 root@127.133.45.236
    gdb /usr/lib/debug/boot/vmlinux-4.15.0-58-generic -ex 'target remote tcp::1234'

    out-of-tree> help
    help    : print this help message
    log     : print qemu log
    clog    : print qemu log and cleanup buffer
    cleanup : cleanup qemu log buffer
    ssh     : print arguments to ssh command
    quit    : quit
    out-of-tree>

*out-of-tree* uses three stages for automated runs:

- Build

  - Inside the docker container (default).
  - Binary version (de facto skip stage).
  - On host.

- Run

  - Insmod for the kernel module.
  - This step is skipped for exploits.

- Test

  - Run the test.sh script on the target machine.
  - Test script is run from *root* for the kernel module.
  - Test script is run from *user* for the kernel exploit.
  - Test script for the kernel module is fully custom (only return
    value is checked).
  - Test script for the kernel exploit receives two parameters:

    - Path to exploit
    - Path to file that must be created with root privileges.

  - If there's no test.sh script then default
    (``echo touch FILE | exploit``) one is used.

Security
--------

*out-of-tree* is not supposed to be used on multi-user systems or with
an untrusted input.

Meanwhile, all modern hypervisors are supporting nested
virtualization, which means you can use it for isolating *out-of-tree*
if you want to work with an untrusted input (e.g. with a mass-scale
testing public proofs-of-concept).