ในหน้านี้ คุณจะได้เรียนรู้วิธีสร้างไลบรารี C/C++ แบบแซนด์บ็อกซ์ของคุณเองด้วย Sandboxed API (SAPI) ใช้เอกสารนี้เป็นแนวทางควบคู่ไปกับตัวอย่างและเอกสารโค้ดในไฟล์ส่วนหัว
สร้างทรัพยากร Dependency
ต้องติดตั้งทรัพยากร Dependency ต่อไปนี้ในระบบ
- เคอร์เนล Linux ที่รองรับ UTS, IPC, ผู้ใช้, PID และเนมสเปซของเครือข่าย
- ส่วนหัว Linux userspace API
- วิธีคอมไพล์โค้ด: GCC 6 (แนะนำให้ใช้เวอร์ชัน 7 หรือสูงกว่า) หรือ Clang 7 (หรือสูงกว่า)
- สําหรับไฟล์ส่วนหัวที่สร้างอัตโนมัติ: การเชื่อมโยง Clang Python
- Python 3.5 ขึ้นไป
- Bazel เวอร์ชัน 2.2.0 หรือ CMake เวอร์ชัน 3.12 ขึ้นไป
การใช้ Bazel
Bazel เป็นระบบบิลด์ที่แนะนำและผสานรวมได้ง่ายที่สุด
เอกสารของเราใช้คอมไพเลอร์ Clang หากต้องการเครื่องมือเชนที่เฉพาะเจาะจง (เช่น คอมไพเลอร์, Linker ฯลฯ) โปรดอ่านเอกสารของ Belle เพื่อดูวิธีเปลี่ยนเชนเครื่องมือคอมไพเลอร์เริ่มต้น
Debian 10 (ป้องกัน)
วิธีติดตั้งทรัพยากร Dependency ของบิลด์
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
เจนทู
ตัวเลือกเคอร์เนลที่จำเป็น:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
วิธีติดตั้งทรัพยากร Dependency ของบิลด์
emerge dev-util/bazel dev-python/typing dev-python/clang-python
การใช้ CMake
CMake เป็นระบบสร้างเมตาโอเพนซอร์สยอดนิยมที่สร้างไฟล์โปรเจ็กต์สำหรับเครื่องมือสร้าง เช่น Ninja หรือ Make
Debian 10 (ป้องกัน)
วิธีติดตั้งทรัพยากร Dependency ของบิลด์
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
เจนทู
ตัวเลือกเคอร์เนลที่จำเป็น:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
วิธีติดตั้งทรัพยากร Dependency ของบิลด์
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
กระบวนการพัฒนา
ในการทำแซนด์บ็อกซ์กับไลบรารี C/C++ คุณจะต้องเตรียมรายการ 2 รายการสำหรับโปรเจ็กต์ของคุณ ดังนี้
- ไลบรารีแซนด์บ็อกซ์
- โค้ดโฮสต์ซึ่งจะใช้ฟังก์ชันที่ไลบรารีแซนด์บ็อกซ์ของคุณแสดงไว้ SAPI จะสร้างออบเจ็กต์ SAPI และ RPC Stub โดยอัตโนมัติให้คุณในระหว่างขั้นตอนการสร้าง
คุณอาจคุ้นเคยกับ zlib จากตัวอย่าง Sandbox2 ที่นี่ซึ่งทั้งโปรแกรม (zpipe.c) ถูกแซนด์บ็อกซ์ไว้ ในขั้นตอนต่อไปนี้ คุณจะได้เรียนรู้วิธีใช้ SAPI เพื่อทำแซนด์บ็อกซ์ของไลบรารี zlib และใช้ประโยชน์จากไลบรารีที่แซนด์บ็อกซ์ไว้
1. เลือกฟังก์ชันที่จำเป็น
หากคุณดูโค้ดโฮสต์ของ zlib (main_zlib.cc) คุณจะเห็นได้ว่าฟังก์ชันการทำงานของเครื่องมือคือการอ่านข้อมูลจาก stdin และใช้ฟังก์ชัน deflate()
ของ zlib เพื่อบีบอัดข้อมูลจนกว่าจะมีการอ่านเครื่องหมาย EOF
โดยรวมแล้ว โปรแกรมนี้ใช้ฟังก์ชัน 3 อย่างจาก zlib ดังนี้
deflateInit_()
: วิธีเริ่มต้นสำหรับการบีบอัดdeflate()
: เพื่อบีบอัดกลุ่มข้อมูลdeflateEnd()
: วิธีสิ้นสุดการบีบอัดและปล่อยโครงสร้างข้อมูลที่จัดสรรแบบไดนามิก
ในชีวิตจริง คุณจะตรวจสอบไลบรารี C/C++ และตัดสินใจว่าจำเป็นต้องใช้ฟังก์ชันใดบ้าง กลยุทธ์ที่เป็นไปได้คือ การเริ่มต้นด้วยโค้ดโฮสต์และใช้ไลบรารีที่ไม่ได้อยู่ในแซนด์บ็อกซ์ จากนั้นในขั้นที่ 2 คุณสามารถสร้างไลบรารีแซนด์บ็อกซ์ และปรับโค้ดโฮสต์เพื่อใช้การเรียกฟังก์ชันที่ทำแซนด์บ็อกซ์
2. เขียนกฎการสร้าง sapi_library
หลังจากระบุฟังก์ชัน zlib ทั้ง 3 รายการที่จำเป็นต้องใช้จากไลบรารี zlib ที่ทำแซนด์บ็อกซ์แล้ว คุณจะกำหนดกฎการสร้างในไฟล์ BUILD ได้ เอกสารสำหรับกฎการสร้าง sapi_library
จะมีอยู่ในหน้าสร้างกฎ
ข้อมูลโค้ดด้านล่างแสดงคําจํากัดความของ sapi_library
สําหรับตัวอย่าง zlib SAPI เมื่อใช้แอตทริบิวต์ lib
Bazel จะได้รับคำสั่งให้หาไลบรารี zlib ในไฟล์ WORKSPACE
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
ผลที่ได้คือระบบจะสร้างไลบรารี zlib ที่ทำแซนด์บ็อกซ์ เอาต์พุตคือออบเจ็กต์ SAPI ซึ่งสามารถรวมไว้ในโค้ดโฮสต์และใช้เพื่อสื่อสารกับไลบรารีที่ทำแซนด์บ็อกซ์ผ่านการเรียก RPC นโยบายแซนด์บ็อกซ์ที่ใช้ในตัวอย่างนี้เป็นนโยบายเริ่มต้น
3. เขียนหรือเปลี่ยนโค้ดโฮสต์
ถึงเวลารวมไลบรารี SAPI ที่สร้างขึ้นกับโค้ดโฮสต์แล้ว
สร้างแซนด์บ็อกซ์
ใช้ sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());
เพื่อสร้างออบเจ็กต์แซนด์บ็อกซ์
ใช้ sapi::zlib::ZlibApi api(&sandbox);
เพื่อสร้างอินสแตนซ์ออบเจ็กต์ SAPI ซึ่งทำให้ฟังก์ชันแซนด์บ็อกซ์พร้อมใช้งาน
ใช้ประเภท SAPI
ประเภท SAPI คือประเภทพิเศษในรูปแบบคลาส C++ ที่ SAPI มีให้ เนื่องจากบางครั้งประเภท C ปกติจะใช้ไม่ได้
คุณจะดูการใช้ประเภท SAPI ครั้งแรกได้ในการประกาศ strm
ซึ่งเป็นส่วนที่ใช้โครงสร้าง SAPI: 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 จัดเตรียมไว้ให้แล้ว