Explicação sobre o Sandbox2

O design do Sandbox2 se baseia em tecnologias conhecidas e estabelecidas, uma estrutura de políticas e dois processos: o executor do sandbox e o sandboxee.

Tecnologias envolvidas

As seções a seguir abordam as tecnologias que criam a camada de base do Sandbox2.

Namespaces do Linux

Os namespaces do Linux são uma tentativa de fornecer virtualização no nível do sistema operacional. Embora vários espaços de usuário sejam executados aparentemente de forma independente, eles compartilham uma única instância de kernel. O Sandbox2 usa os seguintes tipos de namespaces:

  • IPC
  • Rede (a menos que seja desativada explicitamente chamando PolicyBuilder::AllowUnrestrictedNetworking())
  • Montagem (usando uma visualização personalizada da árvore do sistema de arquivos)
  • PID
  • Usuário
  • UTS

Saiba mais sobre os namespaces do Linux em Wikipédia ou na página de manual relacionada.

IPC

O Sandbox2 permite a troca de dados arbitrários entre o executor do sandbox e o sandboxee não confiável. Ele oferece suporte a mensagens de tipo-comprimento-valor (TLV, na sigla em inglês), transmissão de descritores de arquivo e troca de credenciais por tokens e identificadores.

Seccomp-BPF

O Sandbox2 depende do seccomp-bpf, que é uma extensão do modo de computação segura (seccomp) que permite o uso de regras do Berkeley Packet Filter (BPF) para filtrar syscalls.

O seccomp é um recurso do kernel do Linux que restringe as chamadas do sistema de um processo para permitir apenas exit, sigreturn, read e write. Se um processo tentar executar outra syscall, ele será encerrado. A extensão seccomp-bpf permite mais flexibilidade do que o seccomp. Em vez de permitir um conjunto fixo de syscalls, o seccomp-bpf executa um programa BPF nos dados de syscall e, dependendo do valor de retorno do programa, ele pode executar a syscall, pular a syscall e retornar um valor fictício, encerrar o processo, gerar um sinal ou notificar o rastreador.

Ptrace

A syscall ptrace (rastreamento de processos) fornece funcionalidades que permitem que o processo de rastreamento observe e controle a execução do processo rastreado. O processo de rastreamento tem controle total sobre o rastreado depois de anexado. Saiba mais sobre o ptrace em Wikipédia ou na página de manual relacionada.

Política de sandbox

A política de sandbox é a parte mais importante de um sandbox, porque especifica as ações que o sandboxee pode e não pode executar. Há duas partes em uma política de sandbox:

  • Política de syscall
  • Configuração de namespace

Política de syscall padrão

A política padrão bloqueia syscalls que são sempre perigosas e tem precedência sobre a política estendida fornecida pelo usuário.

Política de syscall estendida

A política de syscall estendida pode ser criada usando nossa PolicyBuilder. Essa classe define várias regras de conveniência (por exemplo, AllowStaticStartup, AllowDynamicStartup, AllowOpen) que podem ser usadas para melhorar a legibilidade da política.

Na maioria dos casos, é melhor começar com DefaultPolicyBuilder (sapi::Sandbox2Config::DefaultPolicyBuilder()), que retorna um PolicyBuilder pré-configurado com uma política de linha de base para bibliotecas típicas de linha única e pode ser personalizado ainda mais com regras adicionais (como .AllowDynamicStartup() e .AddLibrariesForBinary() ao colocar um binário em sandbox). Na API em sandbox (SAPI), DefaultPolicyBuilder() é usado por sapi::SandboxConfig::DefaultConfig() com sapi::SandboxConfig::DefaultFlags(), sapi::SandboxConfig::DefaultEnvironmentVariables() e sapi::Sandbox2Config::DefaultLimits(). A construção de um PolicyBuilder diretamente só deve ser usada quando DefaultPolicyBuilder() não puder ser usado ou quando uma configuração precisa for necessária.

Se você quiser restringir ainda mais as syscalls ou exigir regras mais complexas, pode especificar macros BPF brutas com AddPolicyOnSyscall e AddPolicyOnSyscalls. O exemplo crc4 usa esse mecanismo para restringir argumentos para as syscalls read, write e close.

Em geral, quanto mais restrita for a política de sandbox, melhor, porque a exploração de qualquer vulnerabilidade presente no código será limitada pela política. Se você puder especificar exatamente quais syscalls e argumentos são necessários para a operação normal do programa, qualquer invasor que explorar uma vulnerabilidade de execução de código também será restrito aos mesmos limites.

Uma política de sandbox muito restrita pode negar todas as syscalls, exceto leituras e gravações em descritores de arquivo de entrada e saída padrão. Dentro desse sandbox, um programa pode receber entrada, processá-la e retornar a saída. No entanto, se o processo tentar fazer qualquer outra syscall, ele será encerrado devido a uma violação da política. Portanto, se o processo for comprometido (execução de código por um usuário mal-intencionado), ele não poderá fazer nada mais nefasto do que produzir uma saída ruim (que o executor e outros ainda precisam processar corretamente).

Configuração de namespace

O objeto PolicyBuilder também é usado para configurar a visualização individual do sistema de arquivos de um sandboxee. Arquivos únicos (AddFile / AddFileAt), diretórios inteiros (AddDirectory / AddDirectoryAt), bem como armazenamento temporário (AddTmpfs) podem ser mapeados para o ambiente do sandboxee. Além disso, AddLibrariesForBinary pode ser usado para mapear automaticamente todas as bibliotecas necessárias pelo executável vinculado dinamicamente especificado.

Flags de linha de comando

Qualquer política do Sandbox2 pode ser desativada especificando um dos seguintes flags de linha de comando. Esses flags são destinados a fins de teste (por exemplo, ao refinar a política de syscall estendida).

  • --sandbox2_danger_danger_permit_all
  • --sandbox2_danger_danger_permit_all_and_log

Executor do sandbox

O executor do sandbox é um processo que não está em sandbox. É o processo de rastreamento ptrace que se conecta ao sandboxee (processo rastreado ptrace). O executor do sandbox também configura e executa uma instância do monitor que rastreia o sandboxee e fornece informações de status.

O Sandbox2 permite três modos de execução: independente, forkserver do Sandbox2 e forkserver personalizado. Se você usar um forkserver, o sandboxee será criado como um processo filho do executor do sandbox. Esses modos são explicados em detalhes aqui.

Sandboxee

O sandboxee é o processo executado no ambiente restrito e em sandbox definido pela política de sandbox. O executor do sandbox envia a política para o sandboxee via IPC. Em seguida, o sandboxee aplica a política. Qualquer violação da política resultará no encerramento do processo, a menos que configurado de outra forma (consulte Política de sandbox).