Posso utilizzare i thread?
Sì, i thread sono supportati in Sandbox2.
Tutti i thread devono essere sottoposti a sandbox
A causa del funzionamento di Linux, il criterio seccomp-bpf viene applicato solo al thread corrente: ciò significa che il criterio non viene applicato ad altri thread esistenti, ma i thread futuri lo erediteranno:
- Se utilizzi Sandbox2 nella prima modalità in cui il sandboxing è abilitato prima di
execve()
, tutti i thread erediteranno il criterio e non ci saranno problemi. Questa è la modalità di sandboxing preferita. - Se utilizzi la seconda
modalità
in cui l'executor ha
set_enable_sandbox_before_exec(false)
e il Sandboxee comunica all'executor quando vuole essere sottoposto a sandbox conSandboxMeHere()
, assicurati che il filtro venga applicato a tutti i thread. In caso contrario, esiste il rischio di un'uscita dalla sandbox: il codice dannoso potrebbe migrare da un thread in sandbox a un thread non in sandbox.
Come devo compilare il mio Sandboxee?
Rispetto a un eseguibile collegato staticamente, la compilazione di sandboxee in un eseguibile collegato dinamicamente comporta un aumento significativo delle chiamate di sistema (ad es. open
/openat
, mmap
e così via) che devono essere inserite nella lista consentita. Tutte queste
chiamate di sistema aggiuntive sono necessarie a causa dell'invocazione del linker dinamico in fase di runtime
per caricare le librerie condivise.
Tuttavia, se si esaminano i sandboxee collegati staticamente: sebbene sia necessario inserire in una lista consentita un numero inferiore di chiamate di sistema, ci sono anche implicazioni per la sicurezza; l'entropia dell'heap ASLR è ridotta (da 30 bit a 8 bit), il che rende più facili gli exploit.
Questo è un dilemma che può essere essenzialmente ridotto a:
- Dinamico: ASLR heap buono, potenzialmente più difficile da ottenere l'esecuzione del codice iniziale, ma a costo di una policy sandbox meno efficace, potenzialmente più facile da violare.
- Statico: ASLR heap non valido, potenzialmente più facile da ottenere l'esecuzione iniziale del codice, ma una norma sandbox più efficace, potenzialmente più difficile da violare.
In passato, i binari collegati staticamente non supportavano il codice indipendente dalla posizione (pie
). Inoltre, Bazel ha aggiunto pie
per impostazione predefinita. Per poter definire un filtro syscall restrittivo, devi sovrascrivere il valore predefinito di Bazel.
I compilatori sono migliorati nel corso degli anni e ora supportano un'opzione static-pie
.
Con questa opzione, viene chiesto a un compilatore di generare codice indipendente dalla posizione,
ma rispetto a pie
ora include anche tutte le librerie collegate staticamente. Dal punto di vista della sicurezza, static-pie
riduce comunque l'entropia ASLR (da 30 bit a 14 bit), ma si tratta di un miglioramento rispetto alla situazione precedente senza pie
.
Poiché Bazel aggiunge pie
per impostazione predefinita e static è incompatibile, valuta la possibilità di utilizzare il flag delle opzioni del linker per passare il flag del linker -static-pie
alla regola cc_binary e sovrascrivere il valore predefinito:
linkstatic = 1,
linkopts=["-static-pie"],
Per un esempio di queste opzioni, guarda l'esempio
statico
BUILD:
static_bin.cc è collegato staticamente a static-pie
, il che consente di
avere un criterio syscall molto rigido. Questo funziona bene anche per il sandboxing
dei binari di terze parti.
Posso eseguire il sandboxing dei file binari x86 a 32 bit?
Sandbox2 può eseguire il sandboxing solo della stessa architettura con cui è stato compilato.
Inoltre, il supporto per x86 a 32 bit è stato rimosso da Sandbox2. Se provi a utilizzare un executor x86 a 64 bit per eseguire il sandboxing di un binario x86 a 32 bit o di un binario x86 a 64 bit che esegue chiamate di sistema a 32 bit (tramite int 0x80), entrambi genereranno una violazione del sandbox che può essere identificata dall'etichetta dell'architettura [X86-32].
Il motivo di questo comportamento è che i numeri delle chiamate di sistema differiscono tra le architetture e poiché le norme relative alle chiamate di sistema sono scritte nell'architettura dell'esecutore, sarebbe pericoloso consentire un'architettura diversa per Sandboxee. Infatti, ciò potrebbe portare a consentire una syscall apparentemente innocua che in realtà significa che un'altra syscall più dannosa potrebbe aprire la sandbox a un escape.
Esistono limiti al numero di sandbox che un processo di esecuzione può richiedere?
Per ogni istanza Sandboxee (nuovo processo generato da forkserver), viene creato un nuovo thread, che è il limite.
Un esecutore può richiedere la creazione di più sandbox?
No. Esiste una relazione 1:1: un'istanza Executor memorizza il PID di Sandboxee, gestisce l'istanza Comms nell'istanza Sandbox e così via.
Perché ricevo il messaggio "Function not implemented" (Funzione non implementata) in forkserver.cc?
Sandbox2 supporta l'esecuzione solo su kernel ragionevolmente nuovi. Il nostro limite attuale è il kernel 3.19, anche se potrebbe cambiare in futuro. Il motivo è che utilizziamo funzionalità del kernel relativamente nuove, tra cui spazi dei nomi utente e seccomp con il flag TSYNC.
Se utilizzi la produzione, questo non dovrebbe essere un problema, poiché quasi l'intera flotta esegue un kernel sufficientemente nuovo. In caso di problemi, contattaci.
Se utilizzi Debian o Ubuntu, l'aggiornamento del kernel è semplice come eseguire:
sudo apt-get install linux-image-<RECENT_VERSION>