Czy mogę używać wątków?
Tak, wątki są obsługiwane w Sandbox2.
Wszystkie wątki muszą być uruchamiane w piaskownicy
Ze względu na sposób działania systemu Linux zasada seccomp-bpf jest stosowana tylko do bieżącego wątku. Oznacza to, że nie jest ona stosowana do innych istniejących wątków, ale przyszłe wątki będą dziedziczyć tę zasadę:
- Jeśli używasz Sandbox2 w pierwszym trybie, w którym piaskownica jest włączona przed
execve()
, wszystkie wątki dziedziczą zasady i nie ma problemu. Jest to preferowany tryb piaskownicy. - Jeśli używasz drugiego trybu, w którym wykonawca ma wartość
set_enable_sandbox_before_exec(false)
, a proces podrzędny informuje wykonawcę, kiedy chce być uruchomiony w piaskownicy, za pomocą wartościSandboxMeHere()
, upewnij się, że filtr jest stosowany do wszystkich wątków. W przeciwnym razie istnieje ryzyko wydostania się z piaskownicy: złośliwy kod może przenieść się z wątku w piaskownicy do wątku poza nią.
Jak skompilować Sandboxee?
W porównaniu z wykonywalnym plikiem połączonym statycznie skompilowanie procesu podrzędnego do postaci wykonywalnego pliku połączonego dynamicznie spowoduje znaczny wzrost liczby wywołań systemowych (np. open
/openat
, mmap
itp.), które muszą być dodane do listy dozwolonych. Wszystkie te dodatkowe wywołania systemowe są wymagane ze względu na wywołanie dynamicznego linkera w czasie działania programu w celu załadowania bibliotek współużytkowanych.
W przypadku statycznie połączonych procesów podlegających piaskownicy: chociaż trzeba dodać do listy dozwolonych mniej wywołań systemowych, wiąże się to też z konsekwencjami dla bezpieczeństwa. Entropia sterty ASLR jest zmniejszona (z 30 bitów do 8 bitów), co ułatwia wykorzystanie luk w zabezpieczeniach.
Ten dylemat można sprowadzić do następującego pytania:
- Dynamiczna: dobra losowość adresów w stercie, potencjalnie trudniej uzyskać początkowe wykonanie kodu, ale kosztem mniej skutecznej zasady piaskownicy, z której potencjalnie łatwiej się wydostać.
- Statyczna: słaby ASLR sterty, potencjalnie łatwiejsze uzyskanie początkowego wykonania kodu, ale skuteczniejsza zasada piaskownicy, potencjalnie trudniejsza do obejścia.
W przeszłości statycznie połączone pliki binarne nie obsługiwały kodu niezależnego od pozycji (pie
). Dodatkowo Bazel domyślnie dodawał pie
. Aby zdefiniować ścisły filtr wywołań systemowych, trzeba było zastąpić wartość domyślną Bazela.
Kompilatory z biegiem lat zostały ulepszone i obecnie obsługują opcję static-pie
.
Ta opcja nakazuje kompilatorowi generowanie kodu niezależnego od pozycji, ale w porównaniu z pie
obejmuje teraz również wszystkie biblioteki połączone statycznie. Z punktu widzenia bezpieczeństwa static-pie
nadal zmniejsza entropię ASLR (z 30 bitów do 14 bitów), ale jest to poprawa w stosunku do poprzedniej sytuacji bez pie
.
Bazel domyślnie dodaje pie
, a statyczne jest z nim niezgodne, więc rozważ użycie flagi opcji linkera, aby przekazać flagę linkera -static-pie
do reguły cc_binary i zastąpić wartość domyślną:
linkstatic = 1,
linkopts=["-static-pie"],
Przykład tych opcji znajdziesz w statycznym przykładzie BUILD: plik static_bin.cc jest połączony statycznie z static-pie
, co umożliwia stosowanie bardzo restrykcyjnych zasad dotyczących wywołań systemowych. Sprawdza się to też w przypadku piaskownicy
binarnych plików innych firm.
Czy mogę umieścić w piaskownicy 32-bitowe pliki binarne x86?
Sandbox2 może działać w piaskownicy tylko w przypadku tej samej architektury, z którą został skompilowany.
Ponadto z Sandbox2 usunięto obsługę 32-bitowej architektury x86. Jeśli spróbujesz użyć 64-bitowego wykonawcy x86 do umieszczenia w piaskownicy 32-bitowego pliku binarnego x86 lub 64-bitowego pliku binarnego x86 wykonującego 32-bitowe wywołania systemowe (za pomocą int 0x80), w obu przypadkach nastąpi naruszenie piaskownicy, które można zidentyfikować za pomocą etykiety architektury [X86-32].
Wynika to z faktu, że numery wywołań systemowych różnią się w zależności od architektury. Ponieważ zasady wywołań systemowych są zapisywane w architekturze wykonawcy, zezwolenie na inną architekturę w przypadku Sandboxee byłoby niebezpieczne. Może to prowadzić do zezwolenia na pozornie nieszkodliwe wywołanie systemowe, które w rzeczywistości oznacza, że inne, bardziej szkodliwe wywołanie systemowe może otworzyć piaskownicę na ucieczkę.
Czy istnieje limit liczby piaskownic, o które może poprosić proces wykonawczy?
Dla każdej instancji Sandboxee (nowego procesu utworzonego na podstawie serwera rozwidlenia) tworzony jest nowy wątek. To jest właśnie ograniczenie.
Czy wykonawca może poprosić o utworzenie więcej niż 1 piaskownicy?
Nie. Istnieje relacja 1:1 – instancja wykonawcy przechowuje identyfikator PID procesu Sandboxee, zarządza instancją Comms w instancji Sandbox itp.
Dlaczego w pliku forkserver.cc pojawia się komunikat „Function not implemented”?
Sandbox2 obsługuje tylko uruchamianie na stosunkowo nowych jądrach. Obecnie jest to jądro 3.19, ale w przyszłości może się to zmienić. Wynika to z faktu, że używamy stosunkowo nowych funkcji jądra, w tym przestrzeni nazw użytkowników i seccomp z flagą TSYNC.
Jeśli korzystasz z wersji produkcyjnej, nie powinno to stanowić problemu, ponieważ prawie cała flota korzysta z wystarczająco nowego jądra. Jeśli masz z tym problemy, skontaktuj się z nami.
Jeśli korzystasz z Debiana lub Ubuntu, aktualizacja jądra jest tak prosta, jak uruchomienie:
sudo apt-get install linux-image-<RECENT_VERSION>