Najczęstsze pytania

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ści SandboxMeHere(), 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>