ไมโครดรอยด์

Microdroid เป็นระบบปฏิบัติการ Android ขนาดเล็กที่ทำงานในรูปแบบ pVM คุณไม่จำเป็นต้องใช้ Microdroid คุณสามารถเริ่ม VM โดยใช้ระบบปฏิบัติการใดก็ได้ อย่างไรก็ตาม กรณีการใช้งานหลักสำหรับ pVM นั้นไม่ใช่ระบบปฏิบัติการแบบสแตนด์อโลน แต่ให้สภาพแวดล้อมการดำเนินการแยกต่างหากเพื่อเรียกใช้แอปบางส่วนที่มีการรับประกันความเป็นส่วนตัวและความสมบูรณ์ดีกว่าที่ Android มอบให้ได้

ในระบบปฏิบัติการแบบดั้งเดิม การรักษาความลับและความสมบูรณ์ที่เข้มงวดต้องใช้ความพยายามอย่างมาก (มักทำซ้ำกัน) เนื่องจากระบบปฏิบัติการแบบดั้งเดิมไม่เหมาะกับสถาปัตยกรรมโดยรวมของ Android ตัวอย่างเช่น สถาปัตยกรรม Android มาตรฐานทำให้นักพัฒนาแอปต้องใช้วิธีการโหลดและเรียกใช้แอปบางส่วนอย่างปลอดภัยใน pVM และเพย์โหลดสร้างขึ้นโดยเทียบกับ glibc แอป Android ใช้ Bionic, การสื่อสารต้องใช้โปรโตคอลที่กำหนดเองผ่าน vsock และการแก้ไขข้อบกพร่องโดยใช้ adb นั้นทำได้ยาก

Microdroid เติมเต็มช่องว่างเหล่านี้ด้วยการจัดหาภาพระบบปฏิบัติการสำเร็จรูปที่ออกแบบมาเพื่อให้นักพัฒนาแอปทำงานน้อยที่สุดในการย้ายข้อมูลบางส่วนของแอปไปยัง pVM โค้ดแบบเนทีฟนั้นสร้างบน Bionic การสื่อสารเกิดขึ้นผ่าน Binder และทำให้สามารถนำเข้า APEX จากโฮสต์ Android และแสดง API บางส่วนของ Android เช่น คีย์สโตร์สำหรับการดำเนินการเข้ารหัสด้วยคีย์ที่รองรับฮาร์ดแวร์ โดยรวมแล้ว นักพัฒนาซอฟต์แวร์ควรพบว่า Microdroid พบสภาพแวดล้อมที่คุ้นเคย กับเครื่องมือที่พัฒนาจนคุ้นเคยในระบบปฏิบัติการ Android เวอร์ชันเต็ม

ฟีเจอร์

Microdroid เป็น Android เวอร์ชันที่มีการตัดทอนออกไปซึ่งมีองค์ประกอบเพิ่มเติมเล็กน้อยสำหรับ pVM โดยเฉพาะ Microdroid รองรับการดำเนินการต่อไปนี้

  • ชุดย่อยของ NDK API (มี API ทั้งหมดสำหรับการติดตั้งใช้งาน libc และ Bionic ของ Android)
  • ฟีเจอร์การแก้ไขข้อบกพร่อง เช่น adb, logcat, tombstone และ gdb
  • การเปิดเครื่องที่ได้รับการยืนยันและ SELinux
  • การโหลดและเรียกใช้ไบนารีพร้อมกับไลบรารีที่ใช้ร่วมกันซึ่งฝังอยู่ใน APK
  • Binder RPC ผ่าน vsock และการแลกเปลี่ยนไฟล์ที่มีการตรวจสอบความสมบูรณ์โดยนัย
  • การโหลด APEX

Microdroid ไม่รองรับสิ่งต่อไปนี้

  • Android Java API ในแพ็กเกจ android.\*

  • SystemServer และ Zygote

  • กราฟิก/UI

  • HAL

สถาปัตยกรรม Microdroid

Microdroid คล้ายกับ Cuttlefish ตรงที่ทั้ง 2 แพลตฟอร์มมีสถาปัตยกรรมที่คล้ายกับ Android มาตรฐาน Microdroid ประกอบด้วยพาร์ติชันต่อไปนี้ซึ่งจัดกลุ่มรูปภาพไว้ด้วยกันในภาพดิสก์แบบคอมโพสิต

  • bootloader - ยืนยันและเริ่มเคอร์เนล
  • boot.img - มีเคอร์เนลและ init ramdisk
  • vendor_boot.img - มีโมดูลเคอร์เนลสำหรับ VM โดยเฉพาะ เช่น virtio
  • super.img - ประกอบด้วยพาร์ติชันตรรกะของระบบและผู้ให้บริการ
  • vbmeta.img - มีข้อมูลเมตาการเปิดเครื่องที่ได้รับการยืนยัน

อิมเมจพาร์ติชันจะมาพร้อมกับ APEX การจำลองเสมือนและจะบรรจุอยู่ในอิมเมจดิสก์คอมโพสิตโดย VirtualizationService นอกเหนือจากอิมเมจดิสก์คอมโพสิตของระบบปฏิบัติการหลักแล้ว VirtualizationService ยังมีหน้าที่สร้างพาร์ติชันอื่นๆ ต่อไปนี้

  • payload - ชุดพาร์ติชันที่สำรองข้อมูลโดย APEX และ APK ของ Android
  • instance - พาร์ติชันที่เข้ารหัสสำหรับการจัดเก็บข้อมูลการบูตที่ได้รับการยืนยันของแต่ละอินสแตนซ์ เช่น Salt ของแต่ละอินสแตนซ์ คีย์สาธารณะ APEX ที่เชื่อถือได้ และตัวนับการย้อนกลับ

ลำดับการบูต

ลำดับการบูต Microdroid จะเกิดขึ้นหลังจากการบูตอุปกรณ์ การบูตอุปกรณ์จะกล่าวถึงในส่วนเฟิร์มแวร์ pVM ของเอกสารสถาปัตยกรรม รูปที่ 1 แสดงขั้นตอนที่เกิดขึ้นระหว่างลําดับการบูตของ Microdroid

ขั้นตอนการเปิดเครื่องที่ปลอดภัยของอินสแตนซ์ Microdroid

รูปที่ 1 ขั้นตอนการเปิดเครื่องที่ปลอดภัยของอินสแตนซ์ microdroid

ต่อไปนี้เป็นคำอธิบายขั้นตอนต่างๆ

  1. crosvm จะโหลดบูตโหลดเดอร์ลงในหน่วยความจำและ pvmfw เริ่มทำงาน pvmfw จะทํางาน 2 อย่างก่อนข้ามไปยังบูตโหลดเดอร์

    • ยืนยัน Bootloader เพื่อตรวจสอบว่ามาจากแหล่งที่มาที่เชื่อถือได้หรือไม่ (Google หรือ OEM)
    • ตรวจสอบว่ามีการใช้บูตโหลดเดอร์เดียวกันอย่างสม่ำเสมอในการบูต pVM เดียวกันหลายครั้งผ่านการใช้รูปภาพอินสแตนซ์ กล่าวโดยละเอียดคือ pVM จะบูตด้วยอิมเมจอินสแตนซ์ที่ว่างเปล่าในตอนแรก pvmfw จะจัดเก็บข้อมูลประจำตัวของบูตโหลดเดอร์ในอิมเมจอินสแตนซ์และเข้ารหัส ดังนั้น เมื่อบูต pVM ด้วยอิมเมจอินสแตนซ์เดียวกันในครั้งถัดไป pvmfw จะถอดรหัสข้อมูลประจำตัวที่บันทึกไว้จากอิมเมจอินสแตนซ์ และยืนยันว่าข้อมูลดังกล่าวเหมือนกับที่บันทึกไว้ก่อนหน้านี้ หากข้อมูลระบุตัวตนแตกต่างกัน pvmfw จะไม่ยอมบูต

    จากนั้น Bootloader จะบูต Microdroid

  2. บูตโหลดเดอร์จะเข้าถึงดิสก์อินสแตนซ์ เช่นเดียวกับ pvmfw บูตโหลดเดอร์จะมีไดรฟ์ดิสก์อินสแตนซ์ที่มีข้อมูลเกี่ยวกับอิมเมจพาร์ติชันที่ใช้ในอินสแตนซ์นี้ระหว่างการบูตก่อนหน้านี้ รวมถึงคีย์สาธารณะ

  3. Bootloader จะยืนยัน vbmeta และพาร์ติชันที่ลิงก์กัน เช่น boot และ super และหากสำเร็จ ก็จะดึงข้อมูลลับ pVM ระยะถัดไป จากนั้น Microdroid จะส่งการควบคุมไปยังเคอร์เนล

  4. เนื่องจากบูตโหลดเดอร์ได้ยืนยันพาร์ติชันซุปเปอร์แล้ว (ขั้นตอนที่ 3) เคอร์เนลจึงมาสก์พาร์ติชันซุปเปอร์โดยไม่มีเงื่อนไข ซูเปอร์พาร์ติชันประกอบด้วยพาร์ติชันเชิงตรรกะหลายพาร์ติชันที่ติดตั้งผ่าน dm-verity เช่นเดียวกับ Android เวอร์ชันสมบูรณ์ จากนั้นระบบจะส่งการควบคุมไปยังกระบวนการ init ซึ่งจะเริ่มต้นบริการเนทีฟต่างๆ สคริปต์ init.rc คล้ายกับสคริปต์ของ Android เวอร์ชันเต็ม แต่ปรับให้เหมาะกับความต้องการของ Microdroid

  5. กระบวนการ init จะเริ่มต้นตัวจัดการ Microdroid ซึ่งจะเข้าถึงอินสแตนซ์ image บริการจัดการ Microdroid จะถอดรหัสรูปภาพโดยใช้คีย์ที่ส่งมาจากระยะก่อนหน้า และอ่านคีย์สาธารณะและตัวนับการย้อนกลับของ APK และ APEX ของไคลเอ็นต์ที่ pVM นี้เชื่อถือ zipfuse และ apexd จะใช้ข้อมูลนี้ในภายหลังเมื่อมาเทมเพลต APK ของลูกค้าและ APEX ที่ขอตามลำดับ

  6. บริการตัวจัดการ Microdroid จะเริ่มในวันที่ apexd

  7. apexd ต่อเชื่อม APEX ที่ไดเรกทอรี /apex/<name> ความแตกต่างเพียงอย่างเดียวระหว่างวิธีที่ Android และ Microdroid ใส่ APEX คือใน Microdroid ไฟล์ APEX มาจากอุปกรณ์บล็อกเสมือน (/dev/vdc1, …), ไม่ใช่จากไฟล์ปกติ (/system/apex/*.apex)

  8. zipfuse คือระบบไฟล์ FUSE ของ Microdroid zipfuse จะต่อเชื่อม APK ของลูกค้า ซึ่งโดยพื้นฐานแล้วคือไฟล์ Zip ที่เป็นระบบไฟล์ ด้านล่างนี้ pVM จะส่งไฟล์ APK เป็นอุปกรณ์บล็อกเสมือนด้วย dm-verity เช่นเดียวกับ APEX APK มีไฟล์การกําหนดค่าที่มีรายการ APEX ที่ผู้พัฒนาแอปขอสําหรับอินสแตนซ์ pVM นี้ apexd จะใช้รายการนี้เมื่อเปิดใช้งาน APEX

  9. ขั้นตอนการบูตจะกลับไปที่บริการจัดการ Microdroid จากนั้นบริการผู้จัดการจะสื่อสารกับ VirtualizationService ของ Android โดยใช้ Binder RPC เพื่อให้รายงานเหตุการณ์สำคัญ เช่น ข้อขัดข้องหรือการปิดระบบ และยอมรับคำขอต่างๆ เช่น การสิ้นสุด pVM บริการจัดการจะอ่านตำแหน่งของไบนารีหลักจากไฟล์กำหนดค่าของ APK แล้วดำเนินการ

การแลกเปลี่ยนไฟล์ (AuthFS)

ปกติแล้วคอมโพเนนต์ของ Android จะใช้ไฟล์สำหรับอินพุต เอาต์พุต และสถานะ และส่งต่อข้อมูลเหล่านี้เป็นตัวบ่งชี้ไฟล์ (ParcelFileDescriptor ประเภทใน AIDL) ด้วยสิทธิ์เข้าถึงที่ควบคุมโดยเคอร์เนลของ Android AuthFS ช่วยให้การดำเนินการที่คล้ายกันสำหรับการแลกเปลี่ยนไฟล์ระหว่างอุปกรณ์ปลายทางที่ไม่ไว้ใจกันข้ามขอบเขต pVM เป็นไปได้

โดยพื้นฐานแล้ว AuthFS เป็นระบบไฟล์ระยะไกลที่มีการตรวจสอบความสมบูรณ์แบบโปร่งใสในการดำเนินการเข้าถึงแต่ละรายการ ซึ่งคล้ายกับ fs-verity การตรวจสอบช่วยให้ส่วนหน้า เช่น โปรแกรมอ่านไฟล์ที่ทำงานใน pVM ตรวจจับได้ว่าแบ็กเอนด์ที่ไม่น่าเชื่อถือ ซึ่งโดยปกติจะเป็น Android มีการแก้ไขเนื้อหาไฟล์หรือไม่

หากต้องการแลกเปลี่ยนไฟล์ ระบบจะเริ่มต้นแบ็กเอนด์ (fd\_server) ด้วยการกำหนดค่าไฟล์ต่อไฟล์ที่ระบุว่าไฟล์มีไว้สำหรับอินพุต (อ่านอย่างเดียว) หรือเอาต์พุต (อ่านและเขียน) สำหรับอินพุต ฟรอนต์เอนด์จะบังคับให้เนื้อหาตรงกับแฮชที่รู้จัก บนยอดของ Merkle Tree เพื่อการยืนยันเมื่อเข้าถึง สำหรับเอาต์พุต AuthFS จะดูแลรักษาต้นไม้แฮชของเนื้อหาที่สังเกตได้จากการดำเนินการเขียนภายใน และสามารถบังคับใช้ความสมบูรณ์ได้เมื่ออ่านข้อมูลกลับ

ปัจจุบันการรับส่งข้อมูลที่สำคัญใช้ RPC ของ Binder แต่อาจมีการเปลี่ยนแปลงในอนาคตเพื่อเพิ่มประสิทธิภาพ

การจัดการคีย์

pVM มีคีย์การปิดผนึกที่เสถียรซึ่งเหมาะสำหรับปกป้องข้อมูลถาวร และคีย์การรับรองที่เหมาะสำหรับสร้างลายเซ็นที่ pVM สร้างขึ้นและตรวจสอบได้

Binder RPC

อินเทอร์เฟซส่วนใหญ่ของ Android แสดงเป็น AIDL ซึ่งสร้างขึ้นจากไดรเวอร์เคอร์เนล Binder ของ Linux โปรโตคอล Binder ได้รับการเขียนใหม่ให้ทำงานผ่านซ็อกเก็ต vsock ในกรณีของ pVM เพื่อรองรับอินเทอร์เฟซระหว่าง pVM การทำงานผ่านซ็อกเก็ตช่วยให้ใช้อินเทอร์เฟซ AIDL ที่มีอยู่ของ Android ในสภาพแวดล้อมใหม่นี้ได้

หากต้องการตั้งค่าการเชื่อมต่อ อุปกรณ์ปลายทาง 1 เครื่อง เช่น เพย์โหลด pVM จะสร้างออบเจ็กต์ RpcServer ลงทะเบียนออบเจ็กต์รูท และเริ่มรอการเชื่อมต่อใหม่ ไคลเอ็นต์สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้โดยใช้ออบเจ็กต์ RpcSession รับออบเจ็กต์ Binder และใช้ออบเจ็กต์ดังกล่าวได้เหมือนกับการใช้ออบเจ็กต์ Binder กับไดรเวอร์ Binder ของเคอร์เนล