میکرودروئید

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

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

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

ویژگی‌ها

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

  • زیرمجموعه‌ای از APIهای NDK (تمام APIهای لازم برای پیاده‌سازی libc و Bionic در اندروید ارائه شده‌اند)
  • ویژگی‌های اشکال‌زدایی، مانند adb، logcat، tombstone و gdb
  • بوت تأیید شده و SELinux
  • بارگیری و اجرای یک فایل باینری، همراه با کتابخانه‌های مشترک، تعبیه شده در یک APK
  • اتصال RPC روی vsock و تبادل فایل‌ها با بررسی‌های ضمنی یکپارچگی
  • بارگذاری APEXها

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

  • رابط‌های برنامه‌نویسی کاربردی جاوا اندروید در بسته‌های android.\*

  • سرور سیستم و زیگوت

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

  • HAL ها

معماری میکرودروید

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

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

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

  • payload - مجموعه‌ای از پارتیشن‌ها که توسط APEXها و APKهای اندروید پشتیبانی می‌شوند
  • instance - یک پارتیشن رمزگذاری شده برای نگهداری داده‌های بوت تأیید شده برای هر نمونه، مانند salt برای هر نمونه، کلیدهای عمومی قابل اعتماد APEX و شمارنده‌های rollback.

توالی بوت

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

جریان بوت امن نمونه میکرودروید

شکل ۱. جریان بوت امن نمونه میکرودروید

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

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

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

    سپس بوت لودر، میکرودروید را بوت می‌کند.

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

  3. بوت‌لودر، vbmeta و پارتیشن‌های زنجیر شده، مانند boot و super را تأیید می‌کند و در صورت موفقیت، اسرار pVM مرحله بعدی را استخراج می‌کند. سپس، میکرودروید کنترل را به هسته (kernel) می‌سپارد.

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

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

  6. The Microdroid manager service starts apexd .

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

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

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

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

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

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

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

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

مدیریت کلید

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

چسب RPC

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

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