Perguntas frequentes

Posso usar linhas de execução?

Sim, as linhas de execução são compatíveis com o Sandbox2.

Todas as linhas de execução precisam estar em sandbox

Devido à forma como o Linux funciona, a política seccomp-bpf é aplicada apenas à thread atual. Isso significa que a política não é aplicada a outras threads existentes, mas as threads futuras vão herdar a política:

  • Se você estiver usando o Sandbox2 no primeiro modo em que o sandboxing é ativado antes de execve(), todas as linhas de execução vão herdar a política, e não haverá problemas. Esse é o modo preferencial de isolamento em sandbox.
  • Se você estiver usando o segundo modo em que o executor tem set_enable_sandbox_before_exec(false) e o Sandboxee informa ao executor quando quer ser colocado em sandbox com SandboxMeHere(), verifique se o filtro está aplicado a todas as linhas de execução. Caso contrário, há risco de fuga da sandbox: um código malicioso pode migrar de uma thread em sandbox para uma sem sandbox.

Como devo compilar meu Sandboxee?

Em comparação com um executável vinculado de forma estática, a compilação do sandboxee para um executável vinculado de forma dinâmica resulta em um aumento significativo de syscalls (por exemplo, open/openat, mmap etc.) que precisam ser adicionadas à lista de permissões. Todas essas chamadas de sistema adicionais são necessárias devido à invocação do vinculador dinâmico no tempo de execução para carregar as bibliotecas compartilhadas.

No entanto, ao analisar os sandboxees vinculados de forma estática, embora menos syscalls precisem ser adicionadas à lista de permissões, também há implicações de segurança. A entropia do heap ASLR é reduzida (de 30 bits para 8 bits), o que facilita os exploits.

Esse é um dilema que pode ser reduzido a:

  • Dinâmica: boa ASLR de heap, potencialmente mais difícil de conseguir a execução inicial do código, mas ao custo de uma política de sandbox menos eficaz, potencialmente mais fácil de sair.
  • Estático: ASLR de heap ruim, potencialmente mais fácil de obter a execução inicial do código, mas uma política de sandbox mais eficaz, potencialmente mais difícil de sair.

Historicamente, os binários vinculados estaticamente não eram compatíveis com código independente de posição (pie). Além disso, o Bazel adicionou pie por padrão. Para definir um filtro de syscalls restrito, era necessário substituir o valor padrão do Bazel.

Os compiladores melhoraram ao longo dos anos e agora oferecem suporte a uma opção static-pie. Com essa opção, um compilador é instruído a gerar código independente de posição, mas, em comparação com pie, isso também inclui todas as bibliotecas vinculadas estaticamente. Do ponto de vista da segurança, o static-pie ainda reduz a entropia do ASLR (de 30 bits para 14 bits), mas isso é uma melhoria em relação à situação anterior sem o pie.

Como o Bazel adiciona pie por padrão e o estático é incompatível com ele, considere usar a flag de opções do vinculador para transmitir a flag do vinculador -static-pie à regra cc_binary e substituir o padrão:

  linkstatic = 1,
  linkopts=["-static-pie"],

Para um exemplo dessas opções, consulte o exemplo static BUILD: static_bin.cc é vinculado estaticamente com static-pie, o que permite ter uma política de syscall muito restrita. Isso também funciona bem para isolamento de binários de terceiros.

Posso usar sandbox em binários x86 de 32 bits?

O Sandbox2 só pode isolar a mesma arquitetura com que foi compilado.

Além disso, o suporte para x86 de 32 bits foi removido do Sandbox2. Se você tentar usar um executor x86 de 64 bits para isolar um binário x86 de 32 bits ou um binário x86 de 64 bits fazendo chamadas de sistema de 32 bits (via int 0x80), ambos vão gerar uma violação de isolamento que pode ser identificada pelo rótulo de arquitetura [X86-32].

O motivo desse comportamento é que os números de syscalls são diferentes entre as arquiteturas. Como a política de syscalls é escrita na arquitetura do executor, seria perigoso permitir uma arquitetura diferente para o Sandboxee. Isso pode permitir uma syscall aparentemente inofensiva que, na verdade, significa que outra syscall mais prejudicial pode abrir a caixa de areia para uma fuga.

Há limites para o número de sandboxes que um processo de executor pode solicitar?

Para cada instância do Sandboxee (novo processo gerado pelo forkserver), uma nova thread é criada. É aí que está a limitação.

Um executor pode solicitar a criação de mais de uma sandbox?

Não. Há uma relação de 1:1. Uma instância do Executor armazena o PID do Sandboxee, gerencia a instância do Comms para a instância do Sandbox etc.

Por que recebo "Function not implemented" em forkserver.cc?

O Sandbox2 só funciona em kernels razoavelmente novos. Nosso corte atual é o kernel 3.19, mas isso pode mudar no futuro. O motivo é que estamos usando recursos relativamente novos do kernel, incluindo namespaces de usuário e seccomp com a flag TSYNC.

Se você estiver executando na produção, isso não será um problema, já que quase toda a frota está executando um kernel novo o suficiente. Se você tiver algum problema, entre em contato com nossa equipe.

Se você estiver usando o Debian ou o Ubuntu, atualizar o kernel é tão fácil quanto executar:

sudo apt-get install linux-image-<RECENT_VERSION>