이 페이지에서는 샌드박스 처리된 API (SAPI)를 사용하여 샌드박스 처리된 C/C++ 라이브러리를 만드는 방법을 알아봅니다. 헤더 파일의 예 및 코드 문서와 함께 가이드로 사용하세요.
종속 항목 빌드
다음 종속 항목이 시스템에 설치되어 있어야 합니다.
- UTS, IPC, 사용자, PID, 네트워크 네임스페이스를 지원하는 Linux 커널
- Linux 사용자 공간 API 헤더
- 코드 컴파일: GCC 6 (버전 7 이상 권장) 또는 Clang 7 (이상)
- 헤더 파일을 자동 생성하는 경우: Clang Python 바인딩
- Python 3.5 이상
- Bazel 버전 2.2.0 또는 CMake 버전 3.12 이상
Bazel 사용
Bazel은 권장되는 빌드 시스템이며 통합하기 가장 쉽습니다.
문서에서는 Clang 컴파일러를 사용합니다. 특정 도구 모음(예: 컴파일러, 링커 등)이 필요한 경우 기본 컴파일러 도구 모음을 변경하는 방법에 관한 정보는 Bazel 문서를 참고하세요.
Debian 10(Buster)
빌드 종속 항목을 설치하려면 다음 단계를 따르세요.
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-dev
pip3 install clang
Gentoo
필수 커널 옵션:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
빌드 종속 항목을 설치하려면 다음 단계를 따르세요.
emerge dev-util/bazel dev-python/typing dev-python/clang-python
CMake 사용
CMake는 Ninja 또는 Make와 같은 빌드 도구의 프로젝트 파일을 생성하는 인기 있는 오픈소스 메타 빌드 시스템입니다.
Debian 10(Buster)
빌드 종속 항목을 설치하려면 다음 단계를 따르세요.
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang
Gentoo
필수 커널 옵션:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
빌드 종속 항목을 설치하려면 다음 단계를 따르세요.
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
개발 프로세스
C/C++ 라이브러리를 샌드박스 처리하려면 프로젝트에 다음 두 항목을 준비해야 합니다.
- 샌드박스 라이브러리
- 샌드박스 처리된 라이브러리에서 노출된 기능을 사용하는 호스트 코드 빌드 프로세스 중에 SAPI가 SAPI 객체 및 RPC 스텁을 자동으로 생성합니다.
여기에서 전체 프로그램(zpipe.c)이 샌드박스 처리된 Sandbox2 예의 zlib을 잘 알고 계실 수도 있습니다. 다음 단계에서는 SAPI를 사용하여 zlib 라이브러리를 샌드박스 처리하고 샌드박스 처리된 라이브러리를 사용하는 방법을 알아봅니다.
1. 필요한 함수 결정
zlib 호스트 코드(main_zlib.cc)를 살펴보면 도구의 기능은 stdin에서 데이터를 읽고 zlib의 deflate()
함수를 사용하여 EOF
마커가 읽힐 때까지 데이터를 압축하는 것입니다.
이 프로그램은 zlib에서 다음 세 가지 함수를 사용합니다.
deflateInit_()
: 압축을 위해 초기화deflate()
: 데이터 청크에 압축 작업을 실행합니다.deflateEnd()
: 압축을 종료하고 동적으로 할당된 데이터 구조를 해제합니다.
실제 사례에서는 C/C++ 라이브러리를 검토하고 필요한 함수를 결정합니다. 가능한 전략은 호스트 코드로 시작하고 라이브러리를 샌드박스 처리되지 않은 상태로 사용하는 것입니다. 그런 다음 두 번째 단계에서 샌드박스 처리된 라이브러리를 생성하고 샌드박스 처리된 함수 호출을 사용하도록 호스트 코드를 조정할 수 있습니다.
2. sapi_library 빌드 규칙 작성
샌드박스 처리된 zlib 라이브러리에서 필요한 세 개의 zlib 함수를 식별한 후 BUILD 파일에서 빌드 규칙을 정의할 수 있습니다. sapi_library
빌드 규칙에 관한 문서는 빌드 규칙 페이지에서 확인할 수 있습니다.
아래 코드 스니펫은 zlib SAPI 예의 sapi_library
정의를 보여줍니다. lib
속성을 사용하여 Bazel은 WORKSPACE 파일에서 zlib 라이브러리를 찾도록 지시받습니다.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
그 결과 샌드박스 처리된 zlib 라이브러리가 생성됩니다. 출력은 호스트 코드에 포함될 수 있고 RPC 호출을 통해 샌드박스 라이브러리와 통신하는 데 사용될 수 있는 SAPI 객체입니다. 이 예에 사용된 샌드박스 정책은 기본 정책입니다.
3. 호스트 코드 작성 또는 변경
이제 생성된 SAPI 라이브러리를 호스트 코드에 통합할 차례입니다.
샌드박스 만들기
sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());
를 사용하여 샌드박스 객체를 만듭니다.
sapi::zlib::ZlibApi api(&sandbox);
를 사용하여 SAPI 객체를 인스턴스화하여 샌드박스 함수를 사용할 수 있도록 합니다.
SAPI 유형 사용
SAPI 유형은 일반 C 유형이 작동하지 않는 경우가 있으므로 SAPI에서 제공하는 C++ 클래스 형태의 특수 유형입니다.
SAPI 유형의 첫 번째 사용은 SAPI 구조체가 사용되는 strm
선언에서 확인할 수 있습니다. sapi::v::Struct<sapi::zlib::z_stream> strm;
템플릿 유형 (sapi::zlib::z_stream
)은 빌드 규칙에 의해 자동으로 생성되는 코드의 좋은 예입니다.
자세한 내용은 변수 페이지를 참고하세요.
API 호출
defalteInit_
, deflate
또는 deflateEnd
를 호출하려면 SAPI 객체를 사용하세요. '변경' 접근 방식을 사용하기로 결정한 경우 함수 매개변수가 예상 값과 일치하는지 확인해야 합니다.
zlib 예시의 각 호출 예:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
SAPI 트랜잭션 사용
SAPI는 호스트 코드를 샌드박스 라이브러리에서 격리하고 호출자에게 문제가 있는 데이터 처리 요청을 다시 시작하거나 중단할 수 있는 기능을 제공합니다. SAPI 트랜잭션은 한 단계 더 나아가 실패한 프로세스를 자동으로 반복합니다.
자세한 내용은 SAPI 트랜잭션 페이지를 참고하세요.
예
예에서 SAPI팀이 이미 준비한 몇 가지 라이브러리를 확인할 수 있습니다.