Medya çerçevesinin güçlendirilmesi

Android 7.0, cihaz güvenliğini geliştirmek için monolitik mediaserver sürecini, yalnızca her işlemin gerektirdiği izinler ve yeteneklerle sınırlı olacak şekilde birden çok işleme böler. Bu değişiklikler aşağıdakileri yaparak medya çerçevesi güvenlik açıklarını azaltır:

  • AV işlem hattı bileşenlerini uygulamaya özel korumalı alan işlemlerine bölme.
  • Güncellenebilir medya bileşenlerini etkinleştirme (çıkarıcılar, codec'ler vb.).

Bu değişiklikler aynı zamanda medyayla ilgili güvenlik açıklarının çoğunun ciddiyetini önemli ölçüde azaltarak, son kullanıcı cihazlarını ve verilerini güvende tutarak son kullanıcılar için güvenliği de artırıyor.

OEM'lerin ve SoC satıcılarının HAL'lerini ve çerçeve değişikliklerini yeni mimariyle uyumlu hale getirmek için güncellemeleri gerekiyor. Spesifik olarak, satıcı tarafından sağlanan Android kodu genellikle her şeyin aynı süreçte çalıştığını varsaydığından, satıcıların, süreçler arasında anlam taşıyan yerel tanıtıcıları ( native_handle ) aktaracak şekilde kodlarını güncellemeleri gerekir. Medyanın güçlendirilmesiyle ilgili değişikliklerin referans uygulaması için frameworks/av ve frameworks/native bakın.

Mimari değişiklikler

Android'in önceki sürümleri, çok sayıda izne (kamera erişimi, ses erişimi, video sürücüsü erişimi, dosya erişimi, ağ erişimi vb.) sahip tek, yekpare bir mediaserver işlemi kullanıyordu. Android 7.0, mediaserver işlemini, her biri çok daha küçük izinler gerektiren birkaç yeni işleme böler:

medya sunucusu sertleştirme

Şekil 1. Medya sunucusunun güçlendirilmesi için mimari değişiklikler

Bu yeni mimari, bir sürecin güvenliği ihlal edilse bile, kötü amaçlı kodun daha önce mediaserver tarafından tutulan izinlerin tamamına erişmemesini sağlar. İşlemler SElinux ve seccomp politikalarıyla kısıtlanmıştır.

Not: Satıcı bağımlılıkları nedeniyle bazı codec bileşenleri hâlâ mediaserver sunucusunda çalışıyor ve sonuç olarak mediaserver gerekenden daha fazla izin veriyor. Özellikle Widevine Classic, Android 7.0 için mediaserver sunucusunda çalışmaya devam ediyor.

Medya Sunucusu değişiklikleri

Android 7.0'da, oynatmayı ve kaydetmeyi yönlendirmek, örneğin bileşenler ve işlemler arasında arabellekleri geçirmek ve senkronize etmek için mediaserver işlemi mevcuttur. Süreçler standart Binder mekanizması aracılığıyla iletişim kurar.

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

  1. FD'yi, Binder IPC'yi kullanarak dosyadan okumak için kullanan çıkarıcı işlemine iletilen bir Binder DataSource nesnesine sarar. (Medya çıkarıcı FD'yi almaz ancak bunun yerine verileri almak için Binder'ın mediaserver sunucusuna geri çağrı yapmasını sağlar.)
  2. Dosyayı inceler, dosya türü için uygun çıkarıcıyı oluşturur (örn. MP3Extractor veya MPEG4Extractor) ve çıkarıcı için mediaserver işlemine bir Binder arayüzü döndürür.
  3. Dosyadaki veri tipini (örn. MP3 veya H.264 verileri) belirlemek için Binder IPC'nin çıkarıcıya çağrı yapmasını sağlar.
  4. Gerekli türde codec bileşenleri oluşturmak için mediacodec sürecine çağrılar; bu codec bileşenleri için Binder arayüzlerini alır.
  5. Kodlanmış örnekleri okumak için çıkarıcıya tekrarlanan Binder IPC çağrıları yapar, kod çözme amacıyla kodlanmış verileri mediacodec işlemine göndermek için Binder IPC'yi kullanır ve kodu çözülmüş verileri alır.

Bazı kullanım durumlarında, herhangi bir codec bileşeni dahil edilmez (örneğin, kodlanmış verilerin doğrudan çıkış cihazına gönderildiği yüksüz oynatma gibi) veya codec, kodu çözülmüş verinin bir arabelleğini (video oynatma) döndürmek yerine kodu çözülmüş verileri doğrudan işleyebilir.

MediaCodecService değişiklikleri

Codec hizmeti, kodlayıcıların ve kod çözücülerin yaşadığı yerdir. Satıcı bağımlılıklarından dolayı codec'lerin tümü henüz codec sürecinde yer almıyor. Android 7.0'da:

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

Bir uygulama (veya mediaserver ), gerekli türde bir codec bileşeni oluşturmak için codec sürecini çağırır, ardından kodlanmış verileri iletmek ve kodu çözülmüş verileri almak (kod çözme için) veya kodu çözülmüş verileri iletmek ve kodlanmış verileri almak (kodlama için) için bu codec bileşenini çağırır. . Codec'lere veri aktarımı ve codec'lerden veri aktarımı zaten paylaşılan belleği kullanıyor, dolayısıyla bu işlem değişmedi.

MediaDrmServer değişiklikleri

DRM sunucusu, Google Play Filmler'deki filmler gibi DRM korumalı içeriği oynatırken kullanılır. Şifrelenmiş verilerin şifresini güvenli bir şekilde çözmeyi gerçekleştirir ve bu nedenle sertifikaya, anahtar depolamaya ve diğer hassas bileşenlere erişime sahiptir. Satıcı bağımlılıkları nedeniyle DRM işlemi henüz tüm durumlarda kullanılmamaktadır.

Ses Sunucusu değişiklikleri

AudioServer işlemi, ses girişi ve çıkışı, ses yönlendirmesini belirleyen politika yöneticisi hizmeti ve FM radyo hizmeti gibi sesle ilgili bileşenleri barındırır. Ses değişiklikleri ve uygulama kılavuzu hakkında ayrıntılar için bkz . Sesi uygulama .

Kamera Sunucusu değişiklikleri

CameraServer kamerayı kontrol eder ve video kaydederken kameradan video kareleri almak ve daha sonra bunları daha ileri işlemler için mediaserver aktarmak için kullanılır. Değişikliklere ilişkin ayrıntılar ve CameraServer değişikliklerine yönelik uygulama kılavuzu için Camera Framework Sertleştirme'ye bakın.

Çıkarıcı Hizmeti değişiklikleri

Çıkarıcı hizmeti, medya çerçevesi tarafından desteklenen çeşitli dosya formatlarını ayrıştıran bileşenler olan çıkarıcıları barındırır. Çıkarıcı hizmeti, tüm hizmetler arasında en az ayrıcalıklı olanıdır; FD'leri okuyamaz, dolayısıyla dosyalara erişmek için bir Binder arayüzüne (her oynatma oturumu mediaserver for tarafından kendisine sağlanır) çağrılar yapar.

Bir uygulama (veya mediaserver ), bir IMediaExtractor elde etmek için çıkarıcı işlemine bir çağrı yapar, dosyada bulunan parça için IMediaSources almak üzere IMediaExtractor çağırır ve ardından onlardan veri okumak için IMediaSources çağırır.

Verileri işlemler arasında aktarmak için uygulama (veya mediaserver ), Binder işleminin bir parçası olarak verileri yanıt paketine dahil eder veya paylaşılan belleği kullanır:

  • Paylaşılan belleği kullanmak, paylaşılan belleği serbest bırakmak için fazladan bir Binder çağrısı gerektirir ancak daha hızlıdır ve büyük arabellekler için daha az güç kullanır.
  • Paket içi kullanımı ekstra kopyalama gerektirir ancak daha hızlıdır ve 64 KB'tan küçük arabellekler için daha az güç kullanır.

Uygulama

MediaDrm ve MediaCrypto bileşenlerinin yeni mediadrmserver sürecine taşınmasını desteklemek için satıcıların, arabelleklerin işlemler arasında paylaşılmasına izin verecek şekilde güvenli arabelleklerin tahsis yöntemini değiştirmesi gerekir.

Önceki Android sürümlerinde, güvenli arabellekler mediaserver OMX::allocateBuffer tarafından tahsis edilir ve aşağıda gösterildiği gibi aynı süreçte şifre çözme sırasında kullanılır:

Şekil 2. Android 6.0 ve medya sunucusunda daha düşük arabellek tahsisi.

Android 7.0'da arabellek tahsisi süreci, mevcut uygulamalar üzerindeki etkiyi en aza indirirken esneklik sağlayan yeni bir mekanizmaya dönüştü. Yeni mediadrmserver işlemindeki MediaDrm ve MediaCrypto yığınlarıyla, arabellekler farklı şekilde tahsis edilir ve satıcıların, MediaCodec MediaCrypto üzerinde bir şifre çözme işlemini çağırdığında bağlayıcı boyunca taşınabilmeleri için güvenli arabellek tanıtıcılarını güncellemeleri gerekir.

Şekil 3. Mediaserver'da Android 7.0 ve üzeri arabellek tahsisi.

Yerel tanıtıcıları kullan

OMX::allocateBuffer , dosya tanımlayıcıları (FD'ler) ve ek tamsayı verilerini içeren bir native_handle yapısına bir işaretçi döndürmelidir. native_handle , serileştirme/seri durumdan çıkarma için mevcut ciltleyici desteği de dahil olmak üzere FD kullanmanın tüm avantajlarına sahiptir ve aynı zamanda halihazırda FD kullanmayan satıcılar için daha fazla esneklik sağlar.

Yerel tanıtıcıyı tahsis etmek için native_handle_create() işlevini kullanın. Çerçeve kodu, tahsis edilen native_handle yapısının sahipliğini alır ve hem native_handle orijinal olarak tahsis edildiği süreçte hem de seri durumdan çıkarıldığı süreçte kaynakların serbest bırakılmasından sorumludur. Çerçeve, native_handle_close() ardından native_handle_delete() ile yerel tanıtıcıları serbest bırakır ve Parcel::writeNativeHandle()/readNativeHandle() kullanarak native_handle serileştirir/seri durumdan çıkarır.

Güvenli arabellekleri temsil etmek için FD'leri kullanan SoC satıcıları, FD'yi native_handle FD'leriyle doldurabilir. FD kullanmayan satıcılar, native_buffer içindeki ek alanları kullanarak güvenli arabellekleri temsil edebilir.

Şifre çözme konumunu ayarla

Satıcıların, native_handle yeni işlem alanında kullanılabilir hale getirmek için gerekli satıcıya özel işlemleri gerçekleştirmek üzere native_handle üzerinde çalışan OEMCrypto şifre çözme yöntemini güncellemesi gerekir (değişiklikler genellikle OEMCrypto kitaplıklarına yönelik 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ını yerel tanıtıcıları kullanması gerektiğini bildiren bir OMX_SetParameter çağrısı içerir.