מיקרו-דרואיד

Microdroid היא מערכת הפעלה מיני-Android שפועלת ב-pVM. אתם לא חייבים להשתמש ב-Microdroid, אפשר להפעיל מכונה וירטואלית עם כל מערכת הפעלה. עם זאת, התרחישים העיקריים לדוגמה לשימוש ב-pVMs לא כוללים הפעלה של מערכת הפעלה עצמאית, אלא סביבה מבודדת להרצה של חלק מאפליקציה עם ערבויות חזקות יותר של סודיות ושלמות מאשר Android יכול לספק.

במערכות הפעלה רגילות, כדי לשמור על סודיות ויושרה נדרשת כמות גדולה של עבודה (לעיתים קרובות כפול) כי מערכות הפעלה רגילות לא מתאימות לארכיטקטורה המקיפה של Android. לדוגמה, בארכיטקטורה הרגילה של Android, המפתחים צריכים להטמיע דרך לטעון ולבצע באופן מאובטח חלק מהאפליקציה ב-pVM, ועומס התועלת נבנה מול glibc. באפליקציית Android נעשה שימוש ב-Bionic, התקשורת דורשת פרוטוקול מותאם אישית דרך vsock ותיקון באגים באמצעות adb הוא מאתגר.

Microdroid ממלא את הפערים האלה על ידי מתן קובץ אימג' של מערכת הפעלה מוכנה לשימוש, שנועד לדרוש מהמפתחים את המאמץ המינימלי כדי להעביר חלק מהאפליקציה שלהם ל-pVM. הקוד המקומי נבנה על Bionic, התקשורת מתבצעת דרך Binder, הוא מאפשר לייבא קובצי APEX מ-Android המארח ומציג קבוצת משנה של Android API, כמו מאגר מפתחות לפעולות קריפטוגרפיות עם מפתחות שמגובים בחומרה. באופן כללי, המפתחים אמורים למצוא ב-Microdroid סביבה מוכרת עם הכלים שהם התרגלו אליהם ב-Android OS המלא.

תכונות

Microdroid היא גרסה פשוטה של Android עם כמה רכיבים נוספים שספציפיים ל-pVM. Microdroid תומך:

  • קבוצת משנה של ממשקי API של NDK (כל ממשקי ה-API להטמעה של Android ב-libc וב-Bionic)
  • תכונות לניפוי באגים, כמו adb, Logcat, tombstone ו-gdb.
  • הפעלה מאומתת ו-SELinux
  • טעינת קובץ בינארי והרצה שלו, יחד עם ספריות משותפות שמוטמעות ב-APK
  • Binder RPC ב-Pvock והחלפה של קבצים עם בדיקות תקינות מרומזות
  • מתבצעת טעינה של APEX

Microdroid לא תומך באפשרויות הבאות:

  • ממשקי API של Java ל-Android בחבילות android.\*

  • SystemServer ו-Zygote

  • גרפיקה/ממשק משתמש

  • HAL

ארכיטקטורת מיקרו-דרואיד

Microdroid דומה ל-Cuttlefish בכך שלשניהם יש ארכיטקטורה שדומה ל-Android רגיל. Microdroid מורכב מתמונות המחיצות הבאות שמקובצות יחד בתמונת דיסק מורכבת:

  • bootloader – אימות והפעלה של הליבה.
  • boot.img – מכיל את הליבה ואת init ramdisk.
  • vendor_boot.img – מכיל מודולים של ליבה ספציפיים למכונות וירטואליות, כמו virtio.
  • super.img – כולל מחיצות לוגיות של המערכת והספק.
  • vbmeta.img – מכיל מטא-נתונים של אתחול מאומת.

קובצי האימג' של המחיצות נשלחים ב-Virtualization APEX ומארזים בתמונה מורכבת של דיסק על ידי VirtualizationService. בנוסף לתמונת הדיסק המשולבת הראשית של מערכת ההפעלה, VirtualizationService אחראי ליצירת המחיצות הבאות:

  • payload - קבוצת מחיצות שמגובות על ידי חבילות APK ו-APEX של Android
  • instance – מחיצה מוצפנת לנתוני אתחול מאומתים שנשמרים לכל מכונה, כמו מלח לכל מכונה, מפתחות ציבוריים מהימנים של APEX ומספרי ספירה לביטול משיכה לאחור

רצף האתחול

רצף האתחול של Microdroid מתרחש אחרי הפעלת המכשיר. הפעלת המכשיר מוסבר בקטע 'קושחת pVM' במסמך Architecture. איור 1 מציג את השלבים שמתרחשים במהלך רצף ההפעלה של ה-Microdroid:

תהליך אתחול מאובטח של מכונת microdroid

איור 1. תהליך אתחול מאובטח של מכונת microdroid

זהו הסבר על השלבים:

  1. תוכנת האתחול נטענת בזיכרון על ידי crosvm ו-pvmfw מתחיל לפעול. לפני המעבר למחולל האתחול, pvmfw מבצע שתי משימות:

    • אימות של תוכנת האתחול כדי לבדוק אם היא ממקור מהימן (Google או יצרן ציוד מקורי).
    • מוודא שנעשה שימוש עקבי באותו bootloader במספר הפעלות של אותו pVM באמצעות שימוש בתמונת המכונה. באופן ספציפי, ה-pVM מופעל בהתחלה עם קובץ אימג' ריק של מכונה. ‏pvmfw שומר את הזהות של מנהל האתחול בקובץ האימג' של המכונה ומצפין אותו. כך, בפעם הבאה שתתבצע אתחול של ה-pVM עם אותה תמונת מכונה, pvmfw מפענח את הזהות השמורה מהתמונה של המכונה ומאמת שהיא זהה לזו שנשמרה בעבר. אם הזהויות שונות, pvmfw לא יתניע.

    לאחר מכן, תוכנת האתחול תפעיל את Microdroid.

  2. תוכנת האתחול ניגשת לדיסק של המכונה. בדומה ל-pvmfw, תוכנת האתחול כוללת כונן דיסק של מכונה עם מידע על תמונות של מחיצות שהיו בשימוש במכונה הקודמת, כולל המפתח הציבורי.

  3. תוכנת האתחול מאמתת את vbmeta ואת המחיצות המקושרות, כמו boot ו-super, ואם האימות מצליח, היא מייצרת את סודות ה-pVM בשלב הבא. לאחר מכן, Microdroid מעביר את השליטה לליבה.

  4. מכיוון שמחיצה העל כבר אומתה על ידי מנהל האתחול (שלב 3), הליבה מחברת את מחיצת העל ללא תנאים. בדומה ל-Android המלא, המחיצה העליונה מורכבת מכמה מחיצות לוגיות שממוטנות מעל dm-verity. לאחר מכן השליטה מועברת לתהליך init, שמפעיל שירותים מקומיים שונים. הסקריפט init.rc דומה לסקריפט של Android מלא, אבל מותאם לצרכים של Microdroid.

  5. התהליך init מפעיל את מנהל Microdroid, שמקבל גישה לתמונת המכונה. שירות הניהול של Microdroid מפענח את התמונה באמצעות המפתח שהוענק בשלב הקודם, וקורא את המפתחות הציבוריים ומספרי החזרה לאחור של חבילת ה-APK וה-APEX של הלקוח ש-pVM הזה סומך עליהם. המידע הזה ישמש את zipfuse ו-apexd מאוחר יותר כשהם יטענו את קובץ ה-APK של הלקוח ואת קובצי ה-APEX המבוקשים, בהתאמה.

  6. שירות הניהול של Microdroid מתחיל ב-apexd.

  7. apexd מחבר את ה-APEXes לספריות /apex/<name>. ההבדל היחיד בין האופן שבו קבצים מסוג APEX מותקנים ב-Android וב-Microdroid הוא שב-Microdroid, קבצי ה-APEX מגיעים ממכשירי בלוק וירטואליים (/dev/vdc1, …), ולא מקובצים רגילים (/system/apex/*.apex).

  8. zipfuse היא מערכת הקבצים של Microdroid. zipfuse טוען את ה-APK של הלקוח, שהוא בעצם קובץ ZIP בתור מערכת קבצים. מתחת, קובץ ה-APK מועבר כמכשיר בלוק וירטואלי על ידי ה-pVM עם dm-verity, כמו ב-APEX. חבילת ה-APK מכילה קובץ תצורה עם רשימת APEX שמפתח האפליקציה ביקש למופע ה-pVM הזה. הרשימה משמשת את apexd כשמפעילים חשבונות APEX.

  9. תהליך האתחול חוזר לשירות הניהול של Microdroid. לאחר מכן, שירות הניהול מתקשר עם VirtualizationService של Android באמצעות Binder RPC כדי לדווח על אירועים חשובים כמו קריסה או כיבוי, ולקבל בקשות כמו סיום של ה-pVM. שירות הניהול קורא את המיקום של הקובץ הבינארי הראשי מקובץ התצורה של ה-APK ומריץ אותו.

החלפת קבצים (AuthFS)

רכיבים של Android משתמשים בדרך כלל בקבצים להזנת קלט, לפלט ולמצב, ומעבירים אותם כמזהים של קבצים (ParcelFileDescriptor type ב-AIDL) עם גישה שנשלטת על ידי הליבה של Android. AuthFS מאפשרת פונקציונליות דומה להחלפת קבצים בין נקודות קצה מהימנות הדדיות בין גבולות pVM.

ביסודו, AuthFS היא מערכת קבצים מרוחקת עם בדיקות תקינות שקופות של פעולות גישה ספציפיות, בדומה ל-fs-verity. הבדיקות מאפשרות לקצה הקדמי, כמו תוכנית לקריאת קבצים שפועלת ב-pVM, לזהות אם הקצה העורפי הלא מהימן, בדרך כלל Android, שינה את תוכן הקובץ.

כדי להחליף קבצים, הקצה העורפי (fd\_server) מתחיל עם הגדרות אישיות לכל קובץ, שמציינת אם הוא מיועד לקלט (לקריאה בלבד) או לפלט (קריאה-כתיבה). לגבי קלט, ממשק הקצה אוכף שהתוכן תואם ל-hash ידוע, מעל עץ Merkle לאימות בזמן הגישה. לצורך פלט, AuthFS שומרת באופן פנימי את עץ הגיבוב (hash) של התוכן של התוכן כפי שנמדד מפעולות כתיבה, והיא יכולה לאכוף את התקינות בזמן הקריאה החוזרת של הנתונים.

התעבורה הבסיסית מבוססת כרגע על Binder RPC, אבל יכול להיות שהיא תשתנה בעתיד כדי לבצע אופטימיזציה של הביצועים.

ניהול מפתחות

למכונות הווירטואליות יש מפתח סגירה יציב שמתאים להגנה על נתונים קבועים, ומפתח אימות שמתאים ליצירת חתימות שמופקות על ידי ה-pVM בצורה מאומתת.

RPC ב-Binder

רוב ממשקי Android מבוססים על AIDL, שנבנה על גבי מנהל ההתקן של ליבה של Binder Linux. כדי לתמוך בממשקים בין מכונות pVM, פרוטוקול Binder נכתב מחדש כדי שיעבוד עם sockets, למשל vsock במקרים של מכונות pVM. הפעולה דרך שקעים מאפשרת להשתמש בממשקי ה-AIDL הקיימים של Android בסביבה החדשה הזו.

כדי להגדיר את החיבור, נקודת קצה אחת, כמו מטען ייעודי (payload) של pVM, יוצרת אובייקט RpcServer, רושמת אובייקט ברמה הבסיסית (root) ומתחילה להאזין לחיבורים חדשים. לקוחות יכולים להתחבר לשרת הזה באמצעות אובייקט RpcSession, לקבל את האובייקט Binder ולהשתמש בו בדיוק כמו שמשתמשים באובייקט Binder עם מנהל ה-Binder של הליבה.