ตัวอย่าง

ภาพรวม

เราได้เตรียมตัวอย่าง 2-3 รายการเพื่อสาธิตวิธีใช้ Sandbox2 ในสถานการณ์ต่างๆ และวิธีเขียนนโยบาย

หาคำอธิบายใน //sandboxed_api/sandbox2/examples ดูคำอธิบายโดยละเอียดด้านล่าง

CRC4

ตัวอย่าง CRC4 คือการคำนวณผลรวมตรวจสอบของ CRC4 แบบจงใจ ซึ่งจะสาธิตวิธีแซนด์บ็อกซ์โปรแกรมอื่นและวิธีสื่อสารกับโปรแกรมดังกล่าว

  • crc4bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น แซนด์บ็อกซ์)
  • crc4sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะเรียกใช้โปรแกรม (เช่น ผู้ดำเนินการ)

วิธีการทำงาน

  1. ตัวดำเนินการเริ่มต้นแซนด์บ็อกซ์จากเส้นทางไฟล์โดยใช้ ::sandbox2::GetDataDependencyFilePath()
  2. ผู้ดำเนินการจะส่งอินพุตไปยังแซนด์บ็อกซ์ผ่านช่องทางการสื่อสาร Comms โดยใช้ SendBytes()
  3. แซนด์บ็อกซ์จะคำนวณ CRC4 และส่งการตอบกลับกลับไปยังผู้ดำเนินการผ่านช่องทางการสื่อสาร Comms ซึ่งรับด้วย RecvUint32()

หากโปรแกรมทำการเรียกใช้ Syscall ใดๆ นอกเหนือไปจากการสื่อสาร (read() และ write()) โปรแกรมจะถูกปิดเนื่องจากการละเมิดนโยบาย

คงที่

ตัวอย่างแบบคงที่แสดงวิธีแซนด์บ็อกซ์ไบนารีที่ลิงก์แบบคงที่ เช่น ไบนารีของบุคคลที่สามซึ่งคุณไม่มีแหล่งที่มา ซึ่งหมายความว่าไม่ทราบว่ามีการแซนด์บ็อกซ์

  • static_bin.cc: แซนด์บ็อกซ์เป็นไบนารี C แบบคงที่ที่แปลงข้อความ ASCII จากอินพุตมาตรฐานเป็นตัวพิมพ์ใหญ่
  • static_sandbox.cc: ไฟล์ปฏิบัติการที่มีนโยบาย ขีดจำกัด และการใช้คำอธิบายไฟล์สำหรับอินพุตแซนด์บ็อกซ์

วิธีการทำงาน

  1. ตัวดำเนินการเริ่มต้นแซนด์บ็อกซ์จากเส้นทางไฟล์โดยใช้ GetDataDependencyFilepath เช่นเดียวกับ CRC4
  2. โดยจะตั้งขีดจำกัด เปิดคำอธิบายไฟล์ใน /proc/version และทำเครื่องหมายเพื่อแมปในแซนด์บ็อกซ์ด้วย MapFd
  3. นโยบายนี้อนุญาตให้ syscall (open) บางรายการแสดงผลข้อผิดพลาด (ENOENT) แทนที่จะปิดเนื่องจากการละเมิดนโยบาย ซึ่งจะมีประโยชน์เมื่อทำแซนด์บ็อกซ์โปรแกรมของบุคคลที่สามที่เราไม่สามารถแก้ไข syscalls ที่สร้างขึ้นได้ ดังนั้น เราจึงทำให้ syscall ล้มเหลวได้

เครื่องมือ

ตัวอย่างเครื่องมือนี้เป็นทั้งเครื่องมือในการพัฒนานโยบายของคุณเองและทดสอบกับ Sandbox2 API รวมถึงการสาธิตฟีเจอร์ต่างๆ

  • sandbox2tool.cc: ผู้ดำเนินการที่แสดงสิ่งต่อไปนี้
    • วิธีเรียกใช้ไบนารีอื่นแบบแซนด์บ็อกซ์
    • วิธีตั้งค่าการตรวจสอบระบบไฟล์ และ
    • วิธีที่ผู้ดำเนินการสามารถเรียกใช้แซนด์บ็อกซ์แบบอะซิงโครนัสเพื่ออ่านเอาต์พุตอย่างต่อเนื่องได้

ลองดูเองได้เลย

Bazel

bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

CMake + นินจา

cd build-dir
ninja sandbox2_sandbox2tool && \
./sandbox2_sandbox2tool \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname

Google3 (Blaze)

blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
 --sandbox2tool_resolve_and_add_libraries \
 --sandbox2tool_additional_bind_mounts /etc \
 /bin/cat /etc/hostname

การแจ้ง:

  • --sandbox2tool_resolve_and_add_libraries เพื่อแก้ปัญหาและต่อเชื่อมไลบรารีที่จำเป็นสำหรับแซนด์บ็อกซ์
  • --sandbox2tool_additional_bind_mounts <PATHS> เพื่อทำให้ไดเรกทอรีเพิ่มเติมพร้อมใช้งานสำหรับแซนด์บ็อกซ์
  • --sandbox2tool_keep_env เพื่อเก็บตัวแปรสภาพแวดล้อมปัจจุบันไว้
  • --sandbox2tool_redirect_fd1 เพื่อรับแซนด์บ็อกซ์ STDOUT_FILENO (1) และเอาต์พุตในเครื่อง
  • --sandbox2tool_cpu_timeout เพื่อตั้งค่าระยะหมดเวลาของ CPU เป็นวินาที
  • --sandbox2tool_walltime_timeout เพื่อตั้งระยะหมดเวลาของหน้าจอในหน่วยวินาที
  • --sandbox2tool_file_size_creation_limit เพื่อกำหนดขนาดสูงสุดของไฟล์ที่สร้างขึ้น
  • --sandbox2tool_cwd เพื่อตั้งค่าไดเรกทอรีการทำงานปัจจุบันของแซนด์บ็อกซ์

custom_fork

ตัวอย่าง custom_fork แสดงวิธีสร้างแซนด์บ็อกซ์ซึ่งจะเริ่มต้นไบนารี แล้วรอคำขอ fork() จากผู้ดำเนินการระดับบนสุด

โหมดนี้อาจทำให้มีประสิทธิภาพเพิ่มขึ้นเมื่อใช้แซนด์บ็อกซ์ประเภทอื่นๆ เนื่องจากการสร้างอินสแตนซ์ใหม่ของแซนด์บ็อกซ์ไม่จำเป็นต้องดำเนินการไบนารีใหม่ เพียงแค่แยกรายการที่มีอยู่

  • custom_fork_bin.cc: เซิร์ฟเวอร์ Fork ที่กำหนดเองที่ได้รับคำขอไปยัง fork() (ผ่าน Client::WaitAndFork) เพื่อสร้างแซนด์บ็อกซ์ใหม่
  • custom_fork_sandbox.cc: ผู้ดำเนินการ ซึ่งจะเริ่มต้นเซิร์ฟเวอร์ Fork ที่กำหนดเอง จากนั้นจะส่งคำขอไปยังแซนด์บ็อกซ์ (ผ่านทางผู้ดำเนินการรายใหม่) เพื่อสร้าง (ผ่าน fork()) แซนด์บ็อกซ์ใหม่

เครือข่าย

เนมสเปซของเครือข่ายซึ่งเปิดใช้โดยค่าเริ่มต้นจะป้องกันไม่ให้กระบวนการที่ทำแซนด์บ็อกซ์เชื่อมต่อกับโลกภายนอก ตัวอย่างนี้แสดงวิธีจัดการกับปัญหานี้

การเชื่อมต่อจะเริ่มต้นภายในตัวดำเนินการและซ็อกเก็ตที่เป็นผลลัพธ์จะส่งผ่าน ::sandbox2::Comms::SendFD() ผู้แซนด์บ็อกซ์จะได้รับซ็อกเก็ตโดยใช้ ::sandbox2::Comms::RecvFD() และจากนั้นจะใช้ซ็อกเก็ตนี้เพื่อแลกเปลี่ยนข้อมูลได้ตามปกติ

  • network_bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น แซนด์บ็อกซ์)
  • network_sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะเรียกใช้โปรแกรม (เช่น ผู้ดำเนินการ)

network_proxy

ตัวอย่างนี้แสดงให้เห็นถึงทางเลือกในการจัดการกับเนมสเปซของเครือข่าย โดยภายในจะทำงานในลักษณะเดียวกับตัวอย่างข้างต้น แต่แสดงเป็น API ที่สะดวกกว่า

แซนด์บ็อกซ์จะสร้างการเชื่อมต่อเครือข่ายได้ 2 วิธีดังนี้

  • automatic - ติดตั้งเครื่องจัดการอัตโนมัติแล้วออกการเรียกเชื่อมต่อตามปกติ
  • ด้วยตนเอง – ขอรับ NetworkProxyClient และใช้ NetworkProxyClient::Connect โดยตรง

ตัวอย่างนี้แสดงทั้ง 2 วิธี ระบบจะใช้โหมดอัตโนมัติเมื่อมีการตั้งค่าสถานะ connect_with_handler มิเช่นนั้นระบบจะใช้โหมดแมนวล

  • network_bin.cc: โปรแกรมที่เราต้องการแซนด์บ็อกซ์ (เช่น แซนด์บ็อกซ์)
  • network_sandbox.cc: โปรแกรมแซนด์บ็อกซ์ที่จะเรียกใช้โปรแกรม (ผู้ดำเนินการ)