Posso usare i thread?
Sì, i thread sono supportati in Sandbox2.
Tutti i thread devono essere in sandbox
A causa del funzionamento di Linux, la policy seccomp-bpf viene applicata solo al thread corrente: ciò significa che la policy non viene applicata ad altri thread esistenti, ma i thread futuri la erediteranno:
- Se utilizzi Sandbox2 nella prima
modalità
in cui la sandbox è abilitata prima di
execve(), tutti i thread erediteranno la policy e non ci saranno problemi. Questa è la modalità di sandbox preferita. - Se utilizzi la seconda
modalità
in cui l'executor ha
set_enable_sandbox_before_exec(false)e Sandboxee indica all'executor quando vuole essere in 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 Sandboxee?
Rispetto a un eseguibile collegato staticamente, la compilazione di Sandboxee in un
eseguibile collegato dinamicamente comporterà 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 della chiamata del linker dinamico in fase di runtime per caricare le librerie condivise.
Tuttavia, se esaminiamo i Sandboxee collegati staticamente, mentre è necessario inserire nella lista consentita un numero inferiore di chiamate di sistema, ci sono anche implicazioni per la sicurezza: l'entropia dell'heap ASLR viene ridotta (da 30 bit a 8 bit), il che semplifica gli exploit.
Questo è un dilemma che può essere essenzialmente ridotto a:
- Dinamico: ASLR heap valido, potenzialmente più difficile ottenere l'esecuzione iniziale del codice ma a costo di una policy di sandbox meno efficace, potenzialmente più facile da interrompere.
- Statico: ASLR heap non valido, potenzialmente più facile ottenere l'esecuzione iniziale del codice ma una policy di sandbox più efficace, potenzialmente più difficile da interrompere.
Storicamente, i file binari collegati staticamente non supportavano il codice indipendente dalla posizione (pie). Inoltre, Bazel ha aggiunto pie per impostazione predefinita. Per poter definire un filtro di chiamate di sistema restrittivo, devi aver sovrascritto il valore predefinito di Bazel.
I compilatori sono migliorati nel corso degli anni e ora supportano un'opzione static-pie.
Con questa opzione, a un compilatore viene chiesto 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 statico non è compatibile, valuta la possibilità di
utilizzare il flag delle opzioni del linker per passare il -static-pie flag del linker alla
cc_binary
e sovrascrivere il valore predefinito:
linkstatic = 1,
linkopts=["-static-pie"],
Per un esempio di queste opzioni, consulta l'
esempio statico
BUILD:
static_bin.cc è collegato staticamente con static-pie, il che consente di
avere una policy di chiamate di sistema molto restrittiva. Questa soluzione funziona bene anche per la sandbox dei file binari di terze parti.
Posso mettere in sandbox i file binari x86 a 32 bit?
Sandbox2 può mettere in sandbox solo la 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 mettere in sandbox un file binario x86 a 32 bit o un file binario x86 a 64 bit che effettua chiamate di sistema a 32 bit (tramite int 0x80), entrambi genereranno una violazione della sandbox identificabile dall'etichetta dell'architettura [X86-32].
Il motivo di questo comportamento è che i numeri delle chiamate di sistema differiscono tra le architetture e, poiché la policy delle chiamate di sistema è scritta nell'architettura dell'executor, sarebbe pericoloso consentire un'architettura diversa per Sandboxee. Infatti, ciò potrebbe portare a consentire una chiamata di sistema apparentemente innocua che in realtà significa che un'altra chiamata di sistema più dannosa potrebbe aprire la sandbox a un'uscita.
Esistono limiti al numero di sandbox che un processo executor può richiedere?
Per ogni istanza Sandboxee (nuovo processo generato da forkserver), viene creato un nuovo thread: è qui che risiede la limitazione.
Un executor può richiedere la creazione di più di una sandbox?
No. Esiste una relazione 1:1: un'istanza Executor memorizza il PID di Sandboxee, gestisce l'istanza Comms per l'istanza Sandbox e così via.
Perché ricevo il messaggio "Funzione non implementata" in forkserver.cc?
Sandbox2 supporta solo l'esecuzione 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'intero parco risorse utilizza un kernel sufficientemente nuovo. Se riscontri problemi, contattaci.
Se utilizzi Debian o Ubuntu, l'aggiornamento del kernel è semplice come eseguire:
sudo apt-get install linux-image-<RECENT_VERSION>