Häufig gestellte Fragen

Kann ich Threads verwenden?

Ja, Threads werden in Sandbox2 unterstützt.

Alle Threads müssen in einer Sandbox ausgeführt werden

Aufgrund der Funktionsweise von Linux wird die Richtlinie „seccomp-bpf“ nur auf den aktuellen Thread angewendet. Das bedeutet, dass die Richtlinie nicht auf andere vorhandene Threads angewendet wird, zukünftige Threads jedoch die Richtlinie übernehmen:

  • Wenn Sie Sandbox2 im ersten Modus verwenden, in dem vor dem execve() Sandboxing aktiviert ist, übernehmen alle Threads die Richtlinie und es gibt kein Problem. Dies ist der bevorzugte Sandbox-Modus.
  • Wenn Sie den zweiten Modus verwenden, in dem der Executor set_enable_sandbox_before_exec(false) hat und das Sandboxee dem Executor mitteilt, wann er mit SandboxMeHere() in einer Sandbox ausgeführt werden möchte, achten Sie darauf, dass der Filter auf alle Threads angewendet wird. Andernfalls besteht das Risiko eines Escape-Vorgangs in der Sandbox: Schadcode könnte von einem Thread, der in einer Sandbox ausgeführt wird, zu einem Thread ohne Sandbox migriert werden.

Wie sollte ich mein Sandboxee-Paket kompilieren?

Wenn Sie nicht vorsichtig sind, können viele Abhängigkeiten und Nebenwirkungen (zusätzliche Systemaufrufe, Dateizugriffe oder sogar Netzwerkverbindungen) übernommen werden, die das Sandboxing erschweren (das Aufspüren aller Nebeneffekte) und weniger sicher machen (weil die Systemaufruf- und Dateirichtlinien breiter gefasst sind). Einige Kompilierungsoptionen können dazu beitragen, solche Probleme zu reduzieren:

  • Kompilieren Sie die Sandboxee-Binärdatei statisch, um dynamische Verknüpfungen zu vermeiden, die viele Systemaufrufe (open/openat, mmap usw.) erfordern.
  • Da Bazel standardmäßig pie hinzufügt, statisch nicht damit kompatibel ist, können Sie die Verwendung des Flags „features“ über die folgenden Optionen in den cc_binary-Regeln erzwingen:

    linkstatic = 1,
    features = [
        "fully_static_link",  # link libc statically
        "-pie",
    ],
    

Allerdings hat eine statische Verwendung den Nachteil, dass die ASLR-Heap-Entropie reduziert wird (von 30 Bit auf 8 Bit), was Exploits vereinfacht. Entscheiden Sie sorgfältig, was abhängig von Ihrer Sandbox-Implementierung und -Richtlinie besser ist:

  • not static: gute Heap-ASLR, möglicherweise schwieriger, die anfängliche Codeausführung zu erhalten, aber auf Kosten einer weniger effektiven Sandbox-Richtlinie; möglicherweise leichter durchbrechen.
  • Statisch: ASLR mit schlechter Heap-Technologie; die anfängliche Codeausführung ist möglicherweise einfacher, aber eine effektivere Sandbox-Richtlinie, sodass der Durchbruch möglicherweise schwieriger ist.

Diese Entscheidung ist leider nicht korrekt, da der Compiler keine statischen PIE-Dateien (Position Independent Executables) unterstützt. PIE wird implementiert, indem die Binärdatei ein dynamisches Objekt ist, und das dynamische Ladeprogramm ordnet sie vor der Ausführung an einer zufälligen Position zu. Da der Heap normalerweise in einem zufälligen Offset nach der Basisadresse der Binärdatei platziert und mit brk syscall erweitert wird, bedeutet dies bei statischen Binärprogrammen, dass die Heap-ASLR-Entropie nur dieses Offset ist, da es keinen PIE gibt.

Beispiele für diese Kompilierungsoptionen finden Sie im statischen Beispiel BUILD.bazel: static_bin.cc wird statisch kompiliert, was eine sehr enge Systemaufrufrichtlinie ermöglicht. Dies funktioniert auch gut in einer Sandbox-Umgebung mit Binärprogrammen von Drittanbietern.

Kann ich 32-Bit-x86-Binärdateien in einer Sandbox ausführen?

Sandbox2 kann nur die Architektur in einer Sandbox ausführen, mit der sie kompiliert wurde.

Außerdem wird die Unterstützung für 32-Bit-x86 aus Sandbox2 entfernt. Wenn Sie versuchen, einen 64-Bit-x86-Executor für die Sandbox-Technologie eines 32-Bit-x86-Binärprogramms oder ein 64-Bit-x86-Binärprogramm zu verwenden, das 32-Bit-Sysaufrufe (über int 0x80) durchführt, erzeugen beide einen Sandbox-Verstoß, der durch das Architekturlabel [X86-32] identifiziert werden kann.

Der Grund für dieses Verhalten ist, dass sich die Systemaufrufzahlen je nach Architektur unterscheiden. Da die Syscall-Richtlinie in der Architektur des Executors geschrieben ist, wäre es gefährlich, eine andere Architektur für Sandboxee zuzulassen. Dies könnte zu einem scheinbar harmlosen Systemaufruf führen, der tatsächlich bedeutet, dass ein weiterer schädlicher Systemaufruf die Sandbox öffnen könnte, um zu entkommen.

Gibt es Beschränkungen für die Anzahl der Sandboxes, die ein Executor-Prozess anfordern kann?

Für jede Sandboxee-Instanz (d. h. ein neuer, vom Forkserver erzeugter Prozess) wird ein neuer Thread erstellt – dort liegt die Einschränkung.

Kann ein Executor die Erstellung mehrerer Sandbox anfordern?

Nein. Es gibt eine 1:1-Beziehung – eine Executor-Instanz speichert die PID des Sandboxee, verwaltet die Kommunikationsinstanz in der Sandbox-Instanz usw.

Warum erhalte ich in forkserver.cc die Meldung „Funktion nicht implementiert“?

Sandbox2 unterstützt nur relativ neue Kernel. Unsere aktuelle Einstellung ist der Kernel 3.19. Dies kann sich jedoch in Zukunft ändern. Der Grund dafür ist, dass wir relativ neue Kernel-Funktionen verwenden, einschließlich Nutzer-Namespaces und seccomp mit dem TSYNC-Flag.

Wenn Sie das Produkt in der Produktion ausführen, sollte dies kein Problem sein, da fast die gesamte Flotte einen ausreichend neuen Kernel ausführt. Bei Problemen wenden Sie sich bitte an uns.

Wenn Sie Debian oder Ubuntu verwenden, ist die Aktualisierung Ihres Kernels so einfach wie das Ausführen von:

sudo apt-get install linux-image-<RECENT_VERSION>