Medya çerçevesini sağlamlaştırma

Android 7.0, cihaz güvenliğini iyileştirmek için tekil mediaserver sürecini, izinleri ve özellikleri yalnızca her bir sürecin gerektirdiğiyle sınırlı olacak şekilde birden fazla sürece ayırır. Bu değişiklikler, medya çerçevesi güvenlik açıklarını aşağıdaki şekilde azaltır:

  • AV ardışık düzeni bileşenlerini uygulamaya özel korumalı alan süreçlerine bölme.
  • Güncellenebilir medya bileşenlerini (ayırıcı, codec vb.) etkinleştirme

Bu değişiklikler, medyayla ilgili güvenlik açıklarının çoğunun önemini önemli ölçüde azaltarak son kullanıcıların güvenliğini de artırır ve son kullanıcı cihazlarını ve verilerini güvende tutar.

OEM'lerin ve SoC tedarikçi firmalarının, HAL ve çerçeve değişikliklerini yeni mimariyle uyumlu hale getirmek için güncellemeleri gerekir. Daha açık belirtmek gerekirse, tedarikçi firma tarafından sağlanan Android kodu genellikle her şeyin aynı işlemde çalıştığını varsaydığında, tedarikçiler kodlarını, işlemler arasında anlamlı olan yerel tutamaçların (native_handle) aktarılması için güncellemelidir. Medya güçlendirmeyle ilgili değişikliklerin referans uygulaması için frameworks/av ve frameworks/native başlıklı makaleleri inceleyin.

Mimari değişiklikler

Android'in önceki sürümlerinde, çok sayıda izine (kamera erişimi, ses erişimi, video sürücüsü erişimi, dosya erişimi, ağ erişimi vb.) sahip tek bir monolitik mediaserver işlemi kullanılıyordu. Android 7.0, mediaserver sürecini her biri çok daha küçük bir izin grubu gerektiren birkaç yeni sürece ayırır:

medya sunucusu sıkılaştırma

Şekil 1. Medya sunucusunun güvenliğini artırmak için mimari değişiklikleri

Bu yeni mimari, bir işlemin güvenliği ihlal edilse bile kötü amaçlı kodun daha önce mediaserver tarafından sahip olunan izinlerin tamamına erişememesi için gerekli önlemleri alır. İşlemler SELinux ve seccomp politikalarıyla kısıtlanır.

Not: Tedarikçi bağımlılıkları nedeniyle bazı codec'ler hâlâ mediaserver içinde çalışır ve sonuç olarak mediaserver'ye gerekenden daha fazla izin verir. Daha açık belirtmek gerekirse Widevine Classic, Android 7.0 için mediaserver sürümünde çalışmaya devam eder.

MediaServer değişiklikleri

Android 7.0'da mediaserver işlemi, oynatma ve kaydı (ör. bileşenler ve işlemler arasında arabellekleri aktarma ve senkronize etme) yönetmek için kullanılır. İşlemler, standart Binder mekanizması aracılığıyla iletişim kurar.

Standart bir yerel dosya oynatma oturumunda uygulama, mediaserver'e (genellikle MediaPlayer Java API aracılığıyla) bir dosya tanımlayıcısı (FD) iletir ve mediaserver:

  1. FD'yi, ayıklayıcı işlemine iletilen ve Binder IPC'yi kullanarak dosyadan okumak için kullanan bir Binder DataSource nesnesine sarar. (mediaextractor, FD'yi almaz, bunun yerine verileri almak için mediaserver'ye geri Binder çağrıları yapar.)
  2. Dosyayı inceler, dosya türü için uygun ayıklayıcıyı (ör. MP3Extractor veya MPEG4Extractor) oluşturur ve mediaserver işlemine ayıklayıcı için bir Binder arayüzü döndürür.
  3. Dosyadaki veri türünü (ör. MP3 veya H.264 verileri) belirlemek için ayrıştırıcıya Binder IPC çağrıları yapar.
  4. Gerekli türde codec'ler oluşturmak için mediacodec sürecini çağırır; bu codec'ler için Binder arayüzlerini alır.
  5. Kodlanmış örnekleri okumak için ayıklayıcıya tekrar tekrar Binder IPC çağrıları yapar, kodlanmış verileri kod çözme işlemi için mediacodec işlemine göndermek üzere Binder IPC'yi kullanır ve kod çözülmüş verileri alır.

Bazı kullanım alanlarında kodlayıcı kullanılmaz (ör. kodlanmış verilerin doğrudan çıkış cihazına gönderildiği aktarılan oynatma) veya kodlayıcı, kodlanmış verilerin arabelleğini döndürmek yerine kodlanmış verileri doğrudan oluşturabilir (video oynatma).

MediaCodecService değişiklikleri

Kodek hizmeti, kodlayıcıların ve kod çözücülerin bulunduğu yerdir. Tedarikçi bağımlılıkları nedeniyle, tüm codec'ler henüz codec sürecinde kullanılamıyor. Android 7.0'da:

  • Güvenli olmayan kod çözücüler ve yazılım kodlayıcılar codec işleminde bulunur.
  • Güvenli kod çözücüler ve donanım kodlayıcılar mediaserver (değişmedi) sürümündedir.

Bir uygulama (veya mediaserver), gerekli türde bir codec oluşturmak için codec işlemini çağırır, ardından kodlanmış verileri iletmek ve kodlanmış verileri almak (kod çözme için) ya da kodlanmış verileri iletmek ve kodlanmış verileri almak (kodlama için) için bu codec'i çağırır. Kodeklere ve kodeklerden veri aktarımı zaten paylaşılan bellek kullandığından bu işlemde değişiklik yapılmamıştır.

MediaDrmServer değişiklikleri

DRM sunucusu, Google Play Filmler'deki filmler gibi DRM korumalı içerikler oynatırken kullanılır. Şifrelenmiş verilerin şifresini güvenli bir şekilde çözer ve bu nedenle sertifika, anahtar depolama ve diğer hassas bileşenlere erişebilir. Tedarikçi bağımlılıkları nedeniyle DRM süreci henüz her durumda kullanılmıyor.

AudioServer değişiklikleri

AudioServer işlemi, ses girişi ve çıkışı, ses yönlendirmesini belirleyen policymanager hizmeti ve FM radyo hizmeti gibi sesle ilgili bileşenleri barındırır. Ses değişiklikleri ve uygulamayla ilgili ayrıntılar için Sesi uygulama başlıklı makaleyi inceleyin.

CameraServer değişiklikleri

CameraServer, kamerayı kontrol eder ve video kaydederken kameradan video kareleri almak ve daha sonra bunları daha fazla işleme almak için mediaserver'e iletmek üzere kullanılır. Değişiklikler ve CameraServer değişiklikleri için uygulama kılavuzu hakkında ayrıntılı bilgi edinmek üzere Kamera Çerçevesi Güçlendirme başlıklı makaleyi inceleyin.

ExtractorService değişiklikleri

Ayıklama hizmeti, medya çerçevesi tarafından desteklenen çeşitli dosya biçimlerini ayrıştıran bileşenler olan ayıklama araçlarını barındırır. Ayıklama hizmeti, tüm hizmetler arasında en az ayrıcalıklı olanıdır. FD'leri okuyamadığı için dosyalara erişmek amacıyla bir Binder arayüzüne (mediaserver for her oynatma oturumu tarafından sağlanır) çağrı yapar.

Bir uygulama (veya mediaserver), IMediaExtractor elde etmek için ayrıştırıcı işlemine çağrı gönderir, dosyadaki parça için IMediaExtractor'ı çağırır ve ardından bu parçalardan veri okumak için IMediaSources'ı çağırır. IMediaSources

Uygulama (veya mediaserver), verileri Binder işleminin bir parçası olarak yanıt paketine dahil eder veya paylaşılan belleği kullanır:

  • Paylaşılan bellek kullanmak, paylaşılan belleği serbest bırakmak için ek bir Binder çağrısı gerektirir ancak büyük arabellekler için daha hızlıdır ve daha az güç kullanır.
  • Paket içi kullanmanın ekstra kopyalama işlemi gerektirmesi dezavantaj olsa da bu yöntem, 64 KB'tan küçük tamponlar için daha hızlıdır ve daha az güç tüketir.

Uygulama

MediaDrm ve MediaCrypto bileşenlerinin yeni mediadrmserver sürecine taşınmasını desteklemek için tedarikçilerin, güvenli tamponların süreçler arasında paylaşılmasına izin vermek üzere tamponların ayırma yöntemini değiştirmesi gerekir.

Önceki Android sürümlerinde güvenli tamponlar mediaserver tarafından OMX::allocateBuffer içinde ayrılır ve aşağıdaki gibi aynı işlemde şifre çözme sırasında kullanılır:

Şekil 2. Android 6.0 ve önceki sürümlerde medya sunucusunda arabellek ayırma.

Android 7.0'da, arabellek ayırma süreci, mevcut uygulamalar üzerindeki etkiyi en aza indirirken esneklik sağlayan yeni bir mekanizmayla değiştirildi. Yeni mediadrmserver sürecinde MediaDrm ve MediaCrypto yığınları kullanıldığında tamponlar farklı şekilde ayrılır ve MediaCodec, MediaCrypto üzerinde bir şifre çözme işlemi başlattığında tedarikçi firmaların güvenli tampon tutamaçlarını, binder üzerinden taşınabilmeleri için güncellemesi gerekir.

Şekil 3. Android 7.0 ve sonraki sürümlerde medya sunucusunda arabellek ayırma.

Yerel herkese açık kullanıcı adlarını kullanma

OMX::allocateBuffer, dosya tanımlayıcıları (FD'ler) ve ek tam sayı verileri içeren bir native_handle yapısının işaretçisini döndürmelidir. native_handle, serileştirme/seri bozma için mevcut bağlayıcı desteği de dahil olmak üzere FD'leri kullanmanın tüm avantajlarına sahiptir. Ayrıca, şu anda FD'leri kullanmayan tedarikçilere daha fazla esneklik sağlar.

Yerel herkese açık kullanıcı adını atamak için native_handle_create() öğesini kullanın. Çerçeve kodu, ayrılan native_handle struct'unun sahipliğini alır ve hem native_handle'ün ilk olarak ayrıldığı işlemde hem de seri dışına çıkarıldığı işlemde kaynakları serbest bırakmaktan sorumludur. Çerçeve, native_handle_close() ve ardından native_handle_delete() ile yerel alıcılar yayınlar ve Parcel::writeNativeHandle()/readNativeHandle() kullanarak native_handle öğesini serileştirir/seri dışına çıkarır.

Güvenli tamponları temsil etmek için FD'leri kullanan SoC tedarikçileri, native_handle içindeki FD'yi kendi FD'leriyle doldurabilir. FD kullanmayan tedarikçiler, native_buffer içinde ek alanlar kullanarak güvenli arabellekleri temsil edebilir.

Şifre çözme konumunu ayarlama

Tedarikçi firmalar, native_handle'yi yeni işlem alanında kullanılabilir hale getirmek için gerekli olan tedarikçiye özgü işlemleri gerçekleştirmek üzere native_handle üzerinde çalışan OEMCrypto şifre çözme yöntemini güncellemelidir (değişiklikler genellikle OEMCrypto kitaplıklarında yapılan güncellemeleri içerir).

allocateBuffer standart bir OMX işlemi olduğundan Android 7.0, bu desteği sorgulamak için yeni bir OMX uzantısı (OMX.google.android.index.allocateNativeHandle) ve OMX uygulamasına yerel imleçleri kullanması gerektiğini bildiren bir OMX_SetParameter çağrısı içerir.