스레드를 사용할 수 있나요?
예, Sandbox2에서 스레드가 지원됩니다.
모든 스레드는 샌드박스 처리되어야 합니다.
Linux 작동 방식 때문에 seccomp-bpf 정책은 현재 스레드에만 적용됩니다. 즉, 정책이 다른 기존 스레드에는 적용되지 않지만 향후 스레드는 정책을 상속합니다.
execve()
전에 샌드박스가 사용 설정된 첫 번째 모드에서 Sandbox2를 사용하는 경우 모든 스레드가 정책을 상속하므로 문제가 없습니다. 이 모드가 선호되는 샌드박스 모드입니다.- 실행기에
set_enable_sandbox_before_exec(false)
가 있고 Sandboxee가SandboxMeHere()
로 샌드박스 처리되기를 원하는 시점을 실행기에 알리는 두 번째 모드를 사용하는 경우 필터가 모든 스레드에 적용되는지 확인하세요. 그렇지 않으면 샌드박스 이스케이프 위험이 있습니다. 악성 코드가 샌드박스 처리된 스레드에서 샌드박스 처리되지 않은 스레드로 이전될 수 있습니다.
Sandboxee는 어떻게 컴파일해야 하나요?
정적으로 연결된 실행 파일과 비교할 때 샌드박스를 동적으로 연결된 실행 파일로 컴파일하면 허용 목록에 추가해야 하는 시스템 호출(예: open
/openat
, mmap
등)이 크게 증가합니다. 이러한 추가 시스템 호출은 모두 런타임에 공유 라이브러리를 로드하기 위한 동적 링커 호출로 인해 필요합니다.
하지만 정적으로 연결된 샌드박스를 살펴보면 허용 목록에 추가해야 하는 시스템 호출이 적은 반면 보안에 미치는 영향도 있습니다. ASLR 힙 엔트로피가 30비트에서 8비트로 감소하여 익스플로잇이 더 쉬워집니다.
이 딜레마는 기본적으로 다음과 같이 요약할 수 있습니다.
- 동적: 힙 ASLR이 양호하며 초기 코드 실행이 더 어려울 수 있지만 샌드박스 정책이 덜 효과적이라서 더 쉽게 빠져나갈 수 있습니다.
- 정적: 잘못된 힙 ASLR, 초기 코드 실행이 더 쉬울 수 있지만 더 효과적인 샌드박스 정책으로 인해 샌드박스에서 벗어나기가 더 어려울 수 있습니다.
이전에는 정적으로 연결된 바이너리가 위치 독립 코드 (pie
)를 지원하지 않았습니다. 또한 Bazel은 기본적으로 pie
를 추가했습니다. 엄격한 syscall 필터를 정의하려면 Bazel의 기본값을 덮어써야 했습니다.
컴파일러는 수년에 걸쳐 개선되었으며 이제 static-pie
옵션을 지원합니다.
이 옵션을 사용하면 컴파일러가 위치 독립 코드를 생성하도록 지시하지만, pie
와 비교할 때 이제 정적으로 연결된 모든 라이브러리도 포함됩니다. 보안 관점에서 static-pie
는 여전히 ASLR 엔트로피 (30비트에서 14비트로)를 줄이지만, 이는 pie
가 없는 이전 상황에 비해 개선된 것입니다.
Bazel은 기본적으로 pie
를 추가하고 정적은 이와 호환되지 않으므로 링커 옵션 플래그를 사용하여 -static-pie
링커 플래그를 cc_binary 규칙에 전달하고 기본값을 덮어쓰는 것이 좋습니다.
linkstatic = 1,
linkopts=["-static-pie"],
이러한 옵션의 예는 static 예시 BUILD를 참고하세요. static_bin.cc는 static-pie
와 정적으로 연결되어 매우 엄격한 syscall 정책을 사용할 수 있습니다. 이는 서드 파티 바이너리를 샌드박싱하는 데도 유용합니다.
32비트 x86 바이너리를 샌드박스 처리할 수 있나요?
Sandbox2는 컴파일된 것과 동일한 아키텍처만 샌드박스 처리할 수 있습니다.
또한 Sandbox2에서 32비트 x86 지원이 삭제되었습니다. 64비트 x86 실행기를 사용하여 32비트 x86 바이너리 또는 32비트 시스템 호출 (int 0x80을 통해)을 만드는 64비트 x86 바이너리를 샌드박스 처리하려고 하면 둘 다 아키텍처 라벨 [X86-32]로 식별할 수 있는 샌드박스 위반이 생성됩니다.
이 동작의 이유는 시스템 호출 번호가 아키텍처마다 다르기 때문입니다. 시스템 호출 정책은 실행기의 아키텍처로 작성되므로 Sandboxee에 다른 아키텍처를 허용하는 것은 위험합니다. 실제로 이는 무해해 보이는 시스템 호출이 사실은 더 유해한 다른 시스템 호출이 샌드박스를 탈출할 수 있도록 열어줄 수 있음을 의미할 수 있습니다.
실행기 프로세스에서 요청할 수 있는 샌드박스 수에 제한이 있나요?
각 Sandboxee 인스턴스 (forkserver에서 생성된 새 프로세스)에 대해 새 스레드가 생성됩니다. 여기에 제한이 있습니다.
실행기는 샌드박스를 두 개 이상 만들도록 요청할 수 있나요?
아니요. 1:1 관계가 있습니다. Executor 인스턴스는 Sandboxee의 PID를 저장하고, Sandbox 인스턴스에 대한 Comms 인스턴스를 관리합니다.
forkserver.cc 내부에 '함수가 구현되지 않음'이 표시되는 이유는 무엇인가요?
Sandbox2는 적절히 새로운 커널에서만 실행을 지원합니다. 현재 컷오프는 3.19 커널이지만 향후 변경될 수 있습니다. 이는 사용자 네임스페이스와 TSYNC 플래그가 있는 seccomp를 비롯한 비교적 새로운 커널 기능을 사용하기 때문입니다.
프로덕션에서 실행하는 경우 거의 전체 플릿이 충분히 새로운 커널을 실행하므로 이 문제가 발생하지 않습니다. 이와 관련해 문제가 있는 경우 문의해 주세요.
Debian 또는 Ubuntu에서 실행하는 경우 다음을 실행하여 커널을 쉽게 업데이트할 수 있습니다.
sudo apt-get install linux-image-<RECENT_VERSION>