Exemplos

Visão geral

Preparamos alguns exemplos para demonstrar como usar o Sandbox2 em diferentes cenários e como escrever políticas.

Você pode encontrá-los em //sandboxed_api/sandbox2/examples. Confira abaixo explicações detalhadas.

CRC4

O exemplo de CRC4 é um cálculo intencionalmente com bugs de um checksum CRC4, que demonstra como isolar outro programa em sandbox e se comunicar com ele.

  • crc4bin.cc: o programa que queremos colocar em sandbox (ou seja, o Sandboxee).
  • crc4sandbox.cc: o programa sandbox que vai executar o código (ou seja, o executor).

Como funciona:

  1. O executor inicia o Sandboxee do caminho do arquivo usando ::sandbox2::GetDataDependencyFilePath().
  2. O executor envia a entrada para o Sandboxee pelo canal de comunicação Comms usando SendBytes().
  3. O Sandboxee calcula o CRC4 e envia as respostas de volta ao executor pelo canal de comunicação Comms, que as recebe com RecvUint32().

Se o programa fizer qualquer syscall que não seja de comunicação (read() e write()), ele será encerrado devido a uma violação da política.

static

O exemplo estático demonstra como isolar um binário vinculado estaticamente, como um binário de terceiros para o qual você não tem a origem, o que significa que ele não sabe que será isolado.

  • static_bin.cc: o Sandboxee é um binário C estático que converte texto ASCII da entrada padrão em maiúsculas.
  • static_sandbox.cc: o executor com a política, os limites e o uso de um descritor de arquivo para entrada do Sandboxee.

Como funciona:

  1. O executor inicia o Sandboxee do caminho do arquivo usando GetDataDependencyFilepath, assim como para CRC4.
  2. Ele define limites, abre um descritor de arquivo em /proc/version e o marca para ser mapeado no Sandboxee com MapFd.
  3. A política permite que algumas syscalls (open) retornem um erro (ENOENT) em vez de serem encerradas devido a uma violação da política. Isso pode ser útil ao isolar um programa de terceiros em sandbox, em que não é possível modificar quais syscalls são feitos. Em vez disso, podemos fazer com que eles falhem normalmente.

ferramenta

O exemplo de ferramenta é uma ferramenta para desenvolver suas próprias políticas e testar as APIs do Sandbox2, além de uma demonstração dos recursos.

  • sandbox2tool.cc: o executor que demonstra:
    • como executar outro binário em sandbox,
    • como configurar verificações do sistema de arquivos e
    • como o executor pode executar o Sandboxee de forma assíncrona para ler a saída progressivamente.

Faça um teste:

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

Sinalizações:

  • --sandbox2tool_resolve_and_add_libraries para resolver e montar as bibliotecas necessárias para o Sandboxee
  • --sandbox2tool_additional_bind_mounts <PATHS> para disponibilizar outros diretórios ao Sandboxee
  • --sandbox2tool_keep_env para manter as variáveis de ambiente atuais.
  • --sandbox2tool_redirect_fd1 para receber o Sandboxee STDOUT_FILENO (1) e gerar a saída localmente
  • --sandbox2tool_cpu_timeout para definir o tempo limite da CPU em segundos
  • --sandbox2tool_walltime_timeout para definir o tempo limite de tempo real em segundos
  • --sandbox2tool_file_size_creation_limit para definir o tamanho máximo dos arquivos criados
  • --sandbox2tool_cwd para definir o diretório de trabalho atual da sandbox

custom_fork

O exemplo custom_fork demonstra como criar uma sandbox que vai inicializar o binário e aguardar as solicitações fork() do executor principal.

Esse modo oferece um desempenho potencialmente maior em relação a outros tipos de sandbox, já que, aqui, a criação de novas instâncias de Sandboxees não exige a execução de novos binários, apenas a ramificação dos existentes.

  • custom_fork_bin.cc: o servidor de fork personalizado, que recebe solicitações para fork() (via Client::WaitAndFork) para gerar novos Sandboxees.
  • custom_fork_sandbox.cc: o executor, que inicia um servidor de fork personalizado. Em seguida, ele envia solicitações (por novos executores) para gerar (por fork()) novos Sandboxees.

rede

O namespace de rede, que é ativado por padrão, impede que o processo em sandbox se conecte ao mundo externo. Este exemplo mostra como lidar com esse problema.

Uma conexão é inicializada dentro do executor, e o soquete resultante é transmitido por ::sandbox2::Comms::SendFD(). O Sandboxee recebe o soquete usando ::sandbox2::Comms::RecvFD() e pode usá-lo para trocar os dados normalmente.

  • network_bin.cc: o programa que queremos colocar em sandbox (ou seja, o Sandboxee).
  • network_sandbox.cc: o programa de sandbox que vai executar (ou seja, o executor).

network_proxy

Este exemplo demonstra uma maneira alternativa de lidar com um namespace de rede. Internamente, ele funciona exatamente da mesma forma que o exemplo acima, mas é exposto como uma API mais conveniente.

O Sandboxee pode estabelecer uma conexão de rede de duas maneiras diferentes:

  • automático: instalando um manipulador automático e emitindo chamadas de conexão regulares.
  • manual: obtenha um NetworkProxyClient e use NetworkProxyClient::Connect diretamente.

Este exemplo mostra os dois métodos. O modo automático é usado quando a flag connect_with_handler está definida. Caso contrário, o modo manual é usado.