Microdroid

Microdroid, pVM'de çalışan mini bir Android OS'dir. Microdroid kullanmanız gerekmez, herhangi bir işletim sistemiyle sanal makine başlatabilirsiniz. Ancak pVM'lerin temel kullanım alanları, bağımsız bir işletim sistemi çalıştırmak değil, uygulamanın bir bölümünü Android'in sağlayabileceğinden daha güçlü gizlilik ve bütünlük garantileriyle çalıştırmak için yalıtılmış bir yürütme ortamı sunmaktır.

Geleneksel işletim sistemlerinde güçlü gizlilik ve bütünlük sağlamak için oldukça fazla çalışma (genellikle tekrarlanan) gerekir. Bunun nedeni, geleneksel işletim sistemlerinin genel Android mimarisine uygun olmamasıdır. Örneğin, standart Android mimarisinde geliştiricilerin uygulamalarının bir bölümünü pVM'ye güvenli bir şekilde yükleyip yürütmek için bir yöntem uygulaması gerekir ve yük, glibc'ye göre oluşturulur. Android uygulaması Bionic'i kullanıyor. İletişim için vsock üzerinden özel bir protokol gerekiyor ve adb kullanılarak hata ayıklama zor oluyor.

Microdroid, geliştiricilerin uygulamalarının bir bölümünü pVM'ye yük aktarmak için en az çaba göstermelerini sağlayacak şekilde tasarlanmış, kullanıma hazır bir OS görüntüsü sunarak bu boşlukları doldurur. Yerel kod Bionic'e karşı oluşturulur, iletişim Binder üzerinden gerçekleşir ve ana makine Android'den APEX'lerin içe aktarılmasına izin verir. Ayrıca, donanım destekli anahtarlarla kriptografik işlemler için anahtar deposu gibi Android API'nin bir alt kümesini kullanıma sunar. Genel olarak geliştiriciler, Microdroid'i tam Android OS'te alıştıkları araçlarla dolu, tanıdık bir ortam olarak değerlendirebilir.

Özellikler

Microdroid, Android'in basitleştirilmiş bir sürümüdür ve pVM'lere özel birkaç ek bileşen içerir. Microdroid'in desteklediği özellikler:

  • NDK API'lerinin bir alt kümesi (Android'in libc ve Bionic uygulaması için tüm API'ler sağlanır)
  • adb, logcat, tombstone ve gdb gibi hata ayıklama özellikleri
  • Doğrulanmış Başlatma ve SELinux
  • Bir APK'ya yerleştirilmiş paylaşılan kitaplıklarla birlikte bir ikili programın yüklenmesi ve yürütülmesi
  • vsock üzerinden Binder RPC ve örtülü bütünlük kontrolleriyle dosya değişimi
  • APEX'lerin yüklenmesi

Microdroid şunları desteklemez:

  • android.\* paketlerindeki Android Java API'leri

  • SystemServer ve Zygote

  • Grafikler/Kullanıcı Arayüzü

  • HAL'ler

Microdroid mimarisi

Microdroid, standart Android'e benzer bir mimariye sahip olması bakımından Cuttlefish'e benzer. Microdroid, aşağıdaki bölüm resimlerinden oluşur. Bu resimler, birleşik disk görüntüsünde birlikte gruplandırılır:

  • bootloader: Çekirdeği doğrular ve başlatır.
  • boot.img - Çekirdek ve init ramdisk'i içerir.
  • vendor_boot.img - virtio gibi sanal makineye özgü çekirdek modüllerini içerir.
  • super.img - Sistem ve tedarikçi mantıksal bölümlerinden oluşur.
  • vbmeta.img - Doğrulanmış başlatma meta verilerini içerir.

Bölüm görüntüleri, Virtualization APEX'te gönderilir ve VirtualizationService tarafından bileşik disk görüntüsü olarak paketlenir. VirtualizationService, ana OS bileşik disk görüntüsüne ek olarak aşağıdaki diğer bölümleri oluşturmaktan da sorumludur:

  • payload - Android'in APEX'leri ve APK'ları tarafından desteklenen bir bölüm grubu
  • instance - Her örnek için doğrulanmış önyükleme verilerini (ör. her örnek için tuz, güvenilir APEX genel anahtarları ve geri alma sayaçları) kalıcı hale getirmek için şifrelenmiş bir bölüm

Başlatma sırası

Microdroid başlatma sırası, cihaz başlatıldıktan sonra gerçekleşir. Cihazın başlatılması, Mimari dokümanının pVM Donanım Yazılımı bölümünde ele alınmıştır. Şekil 1'de, Microdroid başlatma sırası sırasında gerçekleşen adımlar gösterilmektedir:

Microdroid örneğinin güvenli başlatma akışı

Şekil 1. Microdroid örneğinin güvenli başlatma akışı

Adımlar aşağıda açıklanmıştır:

  1. Bootloader, crosvm tarafından belleğe yüklenir ve pvmfw yürütülmeye başlar. pvmfw, önyükleyiciye geçmeden önce iki görev gerçekleştirir:

    • Güvenilir bir kaynaktan (Google veya bir OEM) gelip gelmediğini kontrol etmek için bootloader'ı doğrular.
    • Örnek resim kullanılarak aynı pVM'nin birden fazla başlatılmasında aynı önyükleyicinin tutarlı bir şekilde kullanılmasını sağlar. Daha net bir ifadeyle, pVM başlangıçta boş bir örnek resmiyle başlatılır. pvmfw, önyükleyicinin kimliğini örnek resminde saklar ve şifreler. Bu nedenle, pVM aynı örnek görüntüsüyle bir sonraki başlatıldığında pvmfw, kaydedilen kimliği örnek görüntüsünden çözer ve daha önce kaydedilen kimlikle aynı olduğunu doğrular. Kimlikler farklıysa pvmfw, başlatmayı reddeder.

    Ardından önyükleyici, Microdroid'i başlatır.

  2. Bootloader, örnek diske erişir. pvmfw'ye benzer şekilde, önyükleyicide ortak anahtar da dahil olmak üzere, önceki başlatma işlemleri sırasında bu örnekte kullanılan bölüm görüntüleri hakkında bilgiler içeren bir örnek disk sürücüsü bulunur.

  3. Bootloader, vbmeta'yı ve boot ile super gibi zincirleme bölümleri doğrular. Doğrulama başarılı olursa sonraki aşama pVM sırlarını türetir. Ardından Microdroid, kontrolü çekirdeğe devreder.

  4. Süper bölüm, önyükleyici tarafından zaten doğrulandığı için (3. adım) çekirdek, süper bölümü koşulsuz olarak bağlar. Tam Android'de olduğu gibi, süper bölüm de dm-verity üzerinden monte edilmiş birden fazla mantıksal bölümden oluşur. Ardından kontrol, çeşitli yerel hizmetleri başlatan init işlemine aktarılır. init.rc komut dosyası, tam Android'e benzer ancak Microdroid'in ihtiyaçlarına göre uyarlanmıştır.

  5. init işlemi, örnek görüntüye erişen Microdroid yöneticisini başlatır. Microdroid yöneticisi hizmeti, önceki aşamadan iletilen anahtarı kullanarak görüntünün şifresini çözer ve bu pVM'nin güvendiği istemci APK'sının ve APEX'lerin ortak anahtarlarını ve geri alma sayaçlarını okur. Bu bilgiler daha sonra zipfuse ve apexd tarafından istemci APK'sını ve istenen APEX'leri sırasıyla bağladıklarında kullanılır.

  6. Microdroid yöneticisi hizmeti apexd tarihinde başlar.

  7. apexd, APEX'leri /apex/<name> dizinlerine bağlar. Android ile Microdroid'in APEX'leri bağlama şekli arasındaki tek fark, Microdroid'de APEX dosyalarının normal dosyalardan (/system/apex/*.apex) değil, sanal blok cihazlardan (/dev/vdc1, …) gelmesidir.

  8. zipfuse, Microdroid'in FUSE dosya sistemidir. zipfuse, istemci APK'sını (temelde bir Zip dosyası) dosya sistemi olarak bağlar. APK dosyası, APEX'te olduğu gibi dm-verity ile pVM tarafından sanal blok cihazı olarak iletilir. APK, uygulama geliştiricinin bu pVM örneği için istediği APEX'lerin listesini içeren bir yapılandırma dosyası içerir. Liste, APEX'ler etkinleştirilirken apexd tarafından kullanılır.

  9. Başlatma akışı, Microdroid yöneticisi hizmetine geri döner. Yönetici hizmeti, kilitlenme veya kapatma gibi önemli etkinlikleri bildirebilmek ve pVM'yi sonlandırma gibi istekleri kabul edebilmek için Binder RPC'yi kullanarak Android'in VirtualizationService ile iletişim kurar. Yönetici hizmeti, ana ikili programın konumunu APK'nın yapılandırma dosyasından okur ve yürütür.

Dosya değişimi (AuthFS)

Android bileşenlerinin giriş, çıkış ve durum için dosyaları kullanması ve bunları Android çekirdeği tarafından kontrol edilen erişimle dosya tanımlayıcıları (AIDL'de ParcelFileDescriptor türü) olarak iletmesi yaygın bir durumdur. AuthFS, pVM sınırları içinde birbirine güvenmeyen uç noktalar arasında dosya alışverişi için benzer işlevler sağlar.

AuthFS, temelde fs-verity'ya benzer şekilde, bağımsız erişim işlemlerinde şeffaf bütünlük kontrolleri olan uzak bir dosya sistemidir. Bu kontroller, pVM'de çalışan bir dosya okuma programı gibi ön uçların, genellikle Android olan güvenilmeyen arka ucun dosya içeriğiyle oynayıp oynamadığını algılamasına olanak tanır.

Dosya alışverişi için arka uç (fd\_server), dosya başına yapılandırmayla başlatılır. Bu yapılandırma, dosyanın giriş (salt okunur) veya çıkış (okuma-yazma) için olup olmadığını belirtir. Giriş için ön uç, erişim sırasında doğrulama amacıyla Merkle ağacının yanı sıra içeriğin bilinen bir karma ile eşleşmesini zorunlu kılar. AuthFS, çıkış için yazma işlemlerinden gözlemlenen içeriklerin karma ağacını dahili olarak korur ve veriler geri okunduğunda bütünlüğü zorunlu kılabilir.

Temel aktarım şu anda Binder RPC'ye dayanmaktadır ancak performansı optimize etmek için gelecekte bu durum değişebilir.

Anahtar yönetimi

pVM'ler, kalıcı verilerin korunmasına uygun olan kararlı bir mühürleme anahtarı ve pVM tarafından doğrulanabilir şekilde oluşturulan imzalar üretmeye uygun bir onay anahtarı ile sağlanır.

Binder RPC

Android'in arayüzlerinin çoğu, Binder Linux çekirdek sürücüsünün üzerine inşa edilmiş AIDL ile ifade edilir. pVM'ler arasındaki arayüzleri desteklemek için Binder protokolü, pVM'ler söz konusu olduğunda vsock soketleri üzerinden çalışacak şekilde yeniden yazıldı. Soketler üzerinden çalışma, Android'in mevcut AIDL arayüzlerinin bu yeni ortamda kullanılmasını sağlar.

Bağlantıyı ayarlamak için bir uç nokta (ör. pVM yükü) RpcServer nesnesi oluşturur, bir kök nesne kaydeder ve yeni bağlantıları dinlemeye başlar. İstemciler, RpcSession nesnesi kullanarak bu sunucuya bağlanabilir, Binder nesnesini alabilir ve bunu, çekirdek Binder sürücüsüyle Binder nesnesi kullanılıyormuş gibi kullanabilir.