Microdroid

‫Microdroid سیستم‌عامل Android کوچکی است که در pVM اجرا می‌شود. لازم نیست از Microdroid استفاده کنید، می‌توانید ماشین مجازی را با هر سیستم‌عاملی شروع کنید. بااین‌حال، موارد استفاده اصلی برای pVMها اجرای سیستم‌عامل مستقل نیست، بلکه ارائه محیط اجرای ایزوله‌شده برای اجرای بخشی از برنامه با ضمانت‌های محرمانگی و تمامیت قوی‌تر از آنچه Android می‌تواند ارائه دهد است.

در سیستم‌های عامل سنتی، ارائه محرمانگی و تمامیت قوی نیازمند کار نسبتاً زیادی است (که اغلب تکراری است) زیرا سیستم‌های عامل سنتی با معماری فراگیر Android سازگار نیستند. برای مثال، با معماری استاندارد Android، توسعه‌دهندگان باید روشی برای بار کردن و اجرای ایمن بخشی از برنامه خود در pVM پیاده‌سازی کنند و بار مفید دربرابر glibc ساخته می‌شود. برنامه Android از Bionic استفاده می‌کند، ارتباط به پروتکل سفارشی ازطریق vsock نیاز دارد، و اشکال‌زدایی بااستفاده از adb چالش‌برانگیز است.

Microdroid این شکاف‌ها را با ارائه یک تصویر سیستم‌عامل آماده پر می‌کند که به‌گونه‌ای طراحی شده است که به کمترین تلاش ازسوی توسعه‌دهندگان برای انتقال بخشی از برنامه خود به pVM نیاز داشته باشد. کد بومی دربرابر Bionic ساخته می‌شود، ارتباط ازطریق Binder انجام می‌شود، و این کد اجازه می‌دهد APEXها از Android میزبان وارد شوند و زیرمجموعه‌ای از Android API را آشکار می‌کند، مثل keystore برای عملیات رمزنگاری با کلیدهای سخت‌افزاری. به‌طورکلی، توسعه‌دهندگان باید Microdroid را محیطی آشنا با ابزارهایی که در سیستم عامل کامل Android به آن‌ها عادت کرده‌اند بیابند.

ویژگی‌ها

Microdroid نسخه ساده‌شده‌ای از Android است که چند مؤلفه اضافی مخصوص pVM دارد. ‫Microdroid از موارد زیر پشتیبانی می‌کند:

  • زیرمجموعه‌ای از میاناهای برنامه‌سازی کاربردی NDK (همه میاناهای برنامه‌سازی کاربردی برای پیاده‌سازی libc و Bionic در Android ارائه شده‌اند)
  • ویژگی‌های اشکال‌زدایی، مانند adb،‏ logcat،‏ tombstone، و gdb
  • «راه‌اندازی درستی‌سنجی‌شده» و SELinux
  • بار کردن و اجرای یک فایل باینری، به‌همراه کتابخانه‌های مشترک، جاسازی‌شده در یک فایل APK
  • Binder RPC ازطریق vsock و تبادل فایل‌ها با بررسی‌های تمامیت ضمنی
  • درحال بار کردن APEX

‫Microdroid از موارد زیر پشتیبانی نمی‌کند:

  • میاناهای برنامه‌سازی کاربردی Android Java در بسته‌های android.\*

  • SystemServer و Zygote

  • گرافیک/واسط کاربر

  • HALs

معماری Microdroid

Microdroid شبیه به Cuttlefish است، زیرا هر دو معماری‌ای دارند که شبیه به Android استاندارد است. Microdroid از تصاویر پارتیشن زیر تشکیل شده است که در یک تصویر دیسک ترکیبی گروه‌بندی شده‌اند:

  • bootloader - هسته را درستی‌سنجی و راه‌اندازی می‌کند.
  • boot.img - حاوی هسته و init ramdisk است.
  • vendor_boot.img - حاوی واحدهای هسته مختص ماشین مجازی، مثل virtio است.
  • super.img - شامل پارتیشن‌های منطقی سیستم و فروشنده است.
  • vbmeta.img - حاوی فراداده راه‌اندازی درستی‌سنجی‌شده است.

تصاویر پارتیشن در Virtualization APEX ارسال می‌شوند و در تصویر دیسک ترکیبی توسط VirtualizationService بسته‌بندی می‌شوند. علاوه‌بر تصویر دیسک ترکیبی سیستم‌عامل اصلی، VirtualizationService مسئول ایجاد این پارتیشن‌های دیگر است:

  • ‫payload - مجموعه‌ای از پارتیشن‌ها که با APEX و APK در Android پشتیبانی می‌شوند
  • instance - بخش‌بندی رمزگذاری‌شده برای تداوم داده‌های راه‌اندازی درستی‌سنجی‌شده هر نمونه، مثل نمک هر نمونه، کلیدهای عمومی APEX مورداعتماد، و شمارنده‌های بازگشت به نسخه قبلی

توالی راه‌اندازی

توالی راه‌اندازی Microdroid پس‌از راه‌اندازی دستگاه رخ می‌دهد. راه‌اندازی دستگاه در بخش «میان‌افزار pVM» در سند معماری مورد بحث قرار گرفته است. شکل ۱ مراحل انجام‌شده درطول توالی راه‌اندازی Microdroid را نشان می‌دهد:

جریان راه‌اندازی امن نمونه microdroid

شکل ۱. جریان راه‌اندازی امن نمونه microdroid

توضیح مراحل در اینجا آمده است:

  1. راه‌انداز سیستم توسط crosvm در حافظه بار می‌شود و pvmfw شروع به اجرا می‌کند. قبل‌از رفتن به بوت‌لودر، pvmfw دو کار را انجام می‌دهد:

    • راه‌انداز سیستم را تأیید می‌کند تا بررسی کند که از منبعی مطمئن (Google یا تولیدکننده تجهیزات اصلی) باشد.
    • تضمین می‌کند که از بارکننده یکسانی به‌طور پیوسته در چندین بوت از pVM یکسان ازطریق استفاده از تصویر نمونه استفاده شود. به‌طور خاص، pVM در ابتدا با تصویر نمونه خالی راه‌اندازی می‌شود. pvmfw هویت بوت‌لودر را در تصویر نمونه ذخیره می‌کند و آن را رمزگذاری می‌کند. بنابراین، دفعه بعدی که pVM با همان تصویر نمونه راه‌اندازی می‌شود، pvmfw هویت ذخیره‌شده را از تصویر نمونه رمزگشایی می‌کند و تأیید می‌کند که همان هویت ذخیره‌شده قبلی است. اگر هویت‌ها متفاوت باشند، pvmfw از راه‌اندازی خودداری می‌کند.

    سپس راه‌انداز سیستم Microdroid را راه‌اندازی می‌کند.

  2. بارکننده به دیسک نمونه دسترسی پیدا می‌کند. مشابه pvmfw، bootloader دارای یک درایو دیسک نمونه با اطلاعاتی درباره تصاویر پارتیشن استفاده‌شده در این نمونه درطول راه‌اندازی‌های قبلی، ازجمله کلید عمومی، است.

  3. راه‌انداز سیستم vbmeta و بخش‌های زنجیره‌ای، مانند boot و super را درستی‌سنجی می‌کند و درصورت موفقیت‌آمیز بودن، اسرار pVM مرحله بعدی را استخراج می‌کند. سپس Microdroid کنترل را به هسته واگذار می‌کند.

  4. چون پارتیشن super قبلاً توسط راه‌انداز سیستم درستی‌سنجی شده است (مرحله ۳)، هسته بدون قیدوشرط پارتیشن super را سوار می‌کند. همانند Android کامل، پارتیشن فوق از چندین پارتیشن منطقی تشکیل شده است که روی dm-verity نصب شده‌اند. سپس کنترل به فرایند init منتقل می‌شود که سرویس‌های بومی مختلفی را شروع می‌کند. برنامه init.rc شبیه به برنامه Android کامل است اما متناسب با نیازهای Microdroid طراحی شده است.

  5. فرایند init مدیر Microdroid را راه‌اندازی می‌کند که به تصویر نمونه دسترسی دارد. سرویس مدیر Microdroid بااستفاده از کلید منتقل‌شده از مرحله قبل، تصویر را رمزگشایی می‌کند و کلیدهای عمومی و شمارنده‌های بازگشت به نسخه قبلی APK و APEXهای مشتری را که این pVM به آن‌ها اعتماد دارد می‌خواند. این اطلاعات بعداً توسط zipfuse و apexd هنگام سوار کردن APK مشتری و APEXهای درخواست‌شده استفاده می‌شود.

  6. سرویس مدیر Microdroid در apexd شروع می‌شود.

  7. ‫apexd APEXها را در دایرکتوری‌های /apex/<name> سوار می‌کند. تنها تفاوت بین نحوه نصب APEX در Android و Microdroid این است که در Microdroid، فایل‌های APEX از دستگاه‌های بلوک مجازی (/dev/vdc1، …) می‌آیند، نه از فایل‌های معمولی (/system/apex/*.apex).

  8. zipfuse سیستم فایل FUSE مربوط به Microdroid است. ‫zipfuse فایل APK کارخواه را که اساساً یک فایل Zip به‌عنوان سیستم فایل است نصب می‌کند. در زیر، فایل APK توسط pVM با dm-verity به‌عنوان دستگاه بلوک مجازی منتقل می‌شود، همانند APEX. فایل APK حاوی فایل پیکربندی با فهرستی از APEXهایی است که توسعه‌دهنده برنامه برای این نمونه pVM درخواست کرده است. این فهرست توسط apexd هنگام فعال‌سازی APEXها استفاده می‌شود.

  9. جریان راه‌اندازی به سرویس مدیر Microdroid برمی‌گردد. سپس سرویس مدیر بااستفاده از Binder RPC با VirtualizationService Android ارتباط برقرار می‌کند تا بتواند رویدادهای مهمی مانند ازکارافتادن یا خاموش شدن را گزارش کند و درخواست‌هایی مانند پایان دادن به pVM را بپذیرد. سرویس مدیر مکان باینری اصلی را از فایل پیکربندی APK می‌خواند و آن را اجرا می‌کند.

تبادل فایل (AuthFS)

رایج است که عناصر Android از فایل‌ها برای ورودی، خروجی، و وضعیت استفاده کنند و این فایل‌ها را به‌عنوان توصیفگر فایل (نوع ParcelFileDescriptor در AIDL) با کنترل دسترسی توسط هسته Android منتقل کنند. ‫AuthFS عملکردی مشابه برای تبادل فایل بین نقاط پایانی که به یکدیگر اعتماد ندارند در مرزهای pVM تسهیل می‌کند.

اساساً، AuthFS یک سیستم فایل ازراه‌دور با بررسی‌های شفاف یکپارچگی در عملیات دسترسی فردی است، شبیه به fs-verity. این بررسی‌ها به بخش کاربری (مثلاً برنامه خواندن فایل که در pVM اجرا می‌شود) امکان می‌دهد تشخیص دهد که آیا بخش سرور غیرقابل‌اعتماد (معمولاً Android) محتوای فایل را دستکاری کرده است یا نه.

برای تبادل فایل‌ها، پس‌زمینه (fd\_server) با پیکربندی هر فایل شروع می‌شود که مشخص می‌کند آیا برای ورودی (فقط خواندنی) یا خروجی (خواندنی-نوشتنی) درنظر گرفته شده است. برای ورودی، بخش جلویی تضمین می‌کند که محتوا با یک درهم‌سازی شناخته‌شده مطابقت داشته باشد، علاوه‌بر درخت Merkle برای درستی‌سنجی درحین دسترسی. برای خروجی، AuthFS به‌طور داخلی درخت درهم‌سازی محتوا را همان‌طور که از عملیات نوشتن مشاهده می‌شود حفظ می‌کند و می‌تواند هنگام خواندن مجدد داده‌ها، یکپارچگی را اعمال کند.

حمل‌ونقل زیربنایی درحال‌حاضر براساس Binder RPC است، اما ممکن است در آینده برای بهینه‌سازی عملکرد تغییر کند.

مدیریت کلید

‫pVM با کلید مهروموم کردن پایدار که برای محافظت از داده‌های ماندگار مناسب است و کلید گواهی که برای تولید امضاهایی که به‌طور قابل‌تأیید توسط pVM تولید می‌شوند ارائه می‌شود.

Binder RPC

اکثر میاناهای Android در AIDL بیان می‌شوند که برپایه درایور هسته Binder Linux ساخته شده است. برای پشتیبانی از میاناهای بین pVMها، پروتکل Binder بازنویسی شده است تا در سوکت‌ها، vsock در مورد pVMها کار کند. عملکرد روی سوکت‌ها به میاناهای AIDL موجود Android اجازه می‌دهد در این محیط جدید استفاده شوند.

برای راه‌اندازی اتصال، یک نقطه پایانی، مانند بار pVM، شیء RpcServer ایجاد می‌کند، شیء ریشه را ثبت می‌کند، و شروع به گوش دادن برای اتصال‌های جدید می‌کند. کلاینت‌ها می‌توانند بااستفاده از شیء RpcSession به این سرور متصل شوند، شیء Binder را دریافت کنند، و دقیقاً مانند شیء Binder که با درایور Binder هسته استفاده می‌شود از آن استفاده کنند.