Posso usar threads?
Sim, as threads são compatíveis com o Sandbox2.
Todas as threads 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, mas as futuras vão herdar a política:
- Se você estiver usando o Sandbox2 no primeiro
modo
em que o sandbox é ativado antes de
execve(), todas as threads vão herdar a política, e não haverá problemas. Esse é o modo preferencial de 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 ele quer estar em sandbox comSandboxMeHere(), verifique se o filtro é aplicado a todas as threads. Caso contrário, há risco de fuga do sandbox: um código malicioso pode migrar de uma thread em sandbox para uma thread fora do sandbox.
Como faço para compilar meu Sandboxee?
Em comparação com um executável vinculado estaticamente, a compilação do Sandboxee em um
executável vinculado dinamicamente resulta em um aumento significativo de syscalls
(por exemplo, open/openat, mmap, etc.) que precisam ser permitidas. Todas essas syscalls 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 estaticamente, embora menos syscalls precisem ser permitidas, 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âmico: bom 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 conseguir 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 ofereciam suporte a código independente de posição (pie). Além disso, o Bazel adicionou pie por padrão. Para definir um filtro de syscalls restrito, você precisava 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 agora também inclui todas as bibliotecas vinculadas estaticamente. Do ponto de vista da segurança, static-pie ainda reduz a entropia ASLR (de 30 bits para 14 bits), mas isso é uma melhoria em relação à situação anterior
sem pie.
Como o Bazel adiciona pie por padrão e o estático é incompatível com ele, considere
usar o flag de opções do vinculador para transmitir o -static-pie flag do vinculador à
cc_binary
e substituir o padrão:
linkstatic = 1,
linkopts=["-static-pie"],
Para um exemplo dessas opções, consulte o
exemplo estático
BUILD:
static_bin.cc está vinculado estaticamente com static-pie, o que permite
ter uma política de syscalls muito restrita. Isso também funciona bem para colocar em sandbox binários de terceiros.
Posso colocar em sandbox binários x86 de 32 bits?
O Sandbox2 só pode colocar em sandbox 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 colocar em sandbox um binário x86 de 32 bits ou um binário x86 de 64 bits que faz syscalls de 32 bits (via int 0x80), ambos vão gerar uma violação de sandbox 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 e, como a política de syscalls é escrita na arquitetura do executor, seria perigoso permitir uma arquitetura diferente para o Sandboxee. Isso pode levar a permitir uma syscall aparentemente inofensiva que, na verdade, significa que outra syscall mais prejudicial pode abrir o sandbox para uma fuga.
Há limites para o número de sandboxes que um processo 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 um sandbox?
Não. Há uma relação 1:1. Uma instância do executor armazena o PID do Sandboxee, gerencia a instância de comunicação com a instância do sandbox etc.
Por que recebo a mensagem "Função não implementada" em forkserver.cc?
O Sandbox2 só oferece suporte à execução em kernels razoavelmente novos. Nosso limite atual é o kernel 3.19, embora isso possa mudar no futuro. O motivo é que estamos usando recursos de kernel relativamente novos, incluindo namespaces de usuário e seccomp com o 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 problemas com isso, entre em contato conosco.
Se você estiver executando no Debian ou no Ubuntu, atualizar o kernel é tão fácil quanto executar:
sudo apt-get install linux-image-<RECENT_VERSION>