Politika uyumluluğu

Bu sayfada, yeni platform SELinux ayarlarının eski tedarikçi SELinux ayarlarından farklı olabileceği durumlarda, Android'in platform kablosuz (OTA) güncellemeleriyle ilgili politika uyumluluğu sorunlarını nasıl ele aldığı açıklanmaktadır.

Nesne sahipliği ve etiketleme

Platform ve satıcı politikalarını ayrı tutmak için her nesnenin sahipliği net bir şekilde tanımlanmalıdır. Örneğin, bir sonraki OTA'da satıcı politikası /dev/foo ve platform politikası /dev/foo etiketlenirse beklenmedik bir ret gibi tanımlanmamış bir davranış veya daha da önemlisi bir başlatma hatası oluşur. SELinux için bu durum, etiketleme çakışması olarak ortaya çıkar. Cihaz düğümünde, en son uygulanan etikete çözümlenen tek bir etiket olabilir. Sonuç olarak:

  • Başarısızlıkla uygulanan etikete erişmesi gereken işlemler kaynağa erişimi kaybeder.
  • Dosyaya erişim kazanan işlemler, yanlış cihaz düğümü oluşturulduğu için bozulabilir.

Platform ve satıcı etiketleri arasındaki çakışmalar, özellikler, hizmetler, işlemler, dosyalar ve soketler dahil olmak üzere SELinux etiketi olan tüm nesnelerde meydana gelebilir. Bu sorunları önlemek için bu nesnelerin sahipliğini net bir şekilde tanımlayın.

Tür/özellik ad alanı

SELinux türü ve özellik adları, etiket çakışmalarına ek olarak da çakışabilir. SELinux, aynı tür ve özelliklerin birden fazla kez bildirilmesine izin vermez. Yinelenen beyanlara sahip bir politika derlenemez. Tür ve özellik adı çakışmalarını önlemek için tüm tedarikçi beyanlarının vendor_ önekiyle başlaması önemle tavsiye edilir. Örneğin, satıcılar type foo, domain; yerine type vendor_foo, domain; kullanmalıdır.

Dosya sahipliği

Platform ve satıcı politikası genellikle tüm dosya sistemleri için etiket sağladığından dosyalarla ilgili çakışmaları önlemek zordur. Tür adlandırmanın aksine, dosyaların ad alanına yerleştirilmesi pratik değildir. Bunun nedeni, dosyaların çoğunun çekirdek tarafından oluşturulmasıdır. Bu çakışmaları önlemek için bu bölümdeki dosya sistemleriyle ilgili adlandırma yönergelerini uygulayın. Android 8.0'da bunlar, teknik zorunluluk içermeyen önerilerdir. Bu öneriler gelecekte Vendor Test Suite (VTS) tarafından zorunlu kılınacaktır.

Sistem (/system)

Yalnızca sistem görüntüsü, /system bileşenleri için file_contexts, service_contexts vb. aracılığıyla etiket sağlamalıdır. /system bileşenleri için etiketler satıcı politikasına eklenirse yalnızca çerçeve içeren bir OTA güncellemesi mümkün olmayabilir.

Tedarikçi (/vendor)

AOSP SELinux politikası, platformun etkileşimde bulunduğu vendor bölümünün bazı kısımlarını zaten etiketler. Bu sayede, platform işlemlerinin vendor bölümünün bazı kısımlarıyla iletişim kurabilmesi veya bu kısımlara erişebilmesi için SELinux kuralları yazılabilir. Örnekler:

/vendor path Platform tarafından sağlanan etiket Etikete bağlı olarak platform süreçleri
/vendor(/.*)? vendor_file Çerçevedeki tüm HAL istemcileri, ueventd vb.
/vendor/framework(/.*)? vendor_framework_file dex2oat, appdomain vb.
/vendor/app(/.*)? vendor_app_file dex2oat, installd, idmap vb.
/vendor/overlay(/.*) vendor_overlay_file system_server, zygote, idmap vb.

Bu nedenle, neverallows bölümündeki ek dosyaları etiketlerken belirli kurallara uyulması (vendor aracılığıyla zorunlu kılınır) gerekir:

  • vendor_file , vendor bölümündeki tüm dosyaların varsayılan etiketi olmalıdır. Platform politikası, geçiş HAL uygulamalarına erişmek için bu ayarın yapılmasını zorunlu kılar.
  • Satıcı politikası aracılığıyla vendor bölümüne eklenen tüm yeni exec_types, vendor_file_type özelliğine sahip olmalıdır. Bu, neverallow'lar aracılığıyla zorunlu kılınır.
  • Gelecekteki platform/çerçeve güncellemeleriyle çakışmaları önlemek için exec_types dışındaki dosyaları vendor bölümünde etiketlemeyin.
  • AOSP tarafından aynı işlem HAL'leri olarak tanımlanan tüm kitaplık bağımlılıkları same_process_hal_file. olarak etiketlenmelidir.

Procfs (/proc)

/proc içindeki dosyalar yalnızca genfscon etiketi kullanılarak etiketlenebilir. Android 7.0'da, procfs içindeki dosyaları etiketlemek için hem platform hem de sağlayıcı politikası genfscon kullanıldı.

Öneri: Yalnızca platform politikası etiketleri /proc. Tedarikçi süreçlerinin, şu anda varsayılan etiketle (proc) etiketlenmiş /proc içindeki dosyalara erişmesi gerekiyorsa tedarikçi politikası bunları açıkça etiketlememeli ve bunun yerine tedarikçi alan adları için kurallar eklemek üzere genel proc türünü kullanmalıdır. Bu sayede, platform güncellemeleri procfs üzerinden kullanıma sunulan gelecekteki çekirdek arayüzlerini destekleyebilir ve gerektiğinde bunları açıkça etiketleyebilir.

Debugfs (/sys/kernel/debug)

Debugfs, hem file_contexts hem de genfscon olarak etiketlenebilir. Android 7.0 ile Android 10'da hem platform hem de satıcı etiketi debugfs.

Android 11'de debugfs, üretim cihazlarında erişilemez veya bağlanamaz. Cihaz üreticileri debugfs öğesini kaldırmalıdır.

Tracefs (/sys/kernel/debug/tracing)

Tracefs, hem file_contexts hem de genfscon olarak etiketlenebilir. Android 7.0'da yalnızca platform etiketleri tracefs.

Öneri: Yalnızca platform, tracefs etiketini kullanabilir.

Sysfs (/sys)

/sys içindeki dosyalar hem file_contexts hem de genfscon kullanılarak etiketlenebilir. Android 7.0'da hem platform hem de satıcı, sysfs içindeki dosyaları etiketlemek için genfscon kullanır.

Öneri: Platform, cihaza özel olmayan sysfs düğümlerini etiketleyebilir. Aksi takdirde, dosyaları yalnızca satıcı etiketleyebilir.

tmpfs (/dev)

/dev klasöründeki dosyalar file_contexts içinde etiketlenebilir. Android 7.0'da hem platform hem de satıcı etiket dosyaları burada bulunur.

Öneri: Tedarikçi, yalnızca /dev/vendor (örneğin, /dev/vendor/foo, /dev/vendor/socket/bar) içindeki dosyaları etiketleyebilir.

Rootfs (/)

/ klasöründeki dosyalar file_contexts içinde etiketlenebilir. Android 7.0'da hem platform hem de satıcı etiket dosyaları burada bulunur.

Öneri: Yalnızca sistem, / içindeki dosyaları etiketleyebilir.

Veriler (/data)

Veriler, file_contexts ve seapp_contexts kombinasyonuyla etiketlenir.

Öneri: Satıcı etiketlemesine dışarıda izin vermeyin /data/vendor. Yalnızca platform, /data öğesinin diğer kısımlarını etiketleyebilir.

Genfs etiketleri sürümü

Tedarikçi API düzeyi 202504'ten itibaren, genfscon ile system/sepolicy/compat/plat_sepolicy_genfs_ver.cil içinde atanan yeni SELinux etiketleri, eski vendor bölümleri için isteğe bağlıdır. Bu sayede eski vendor bölümler mevcut SEPolicy uygulamalarını koruyabilir. Bu, BOARD_GENFS_LABELS_VERSION Makefile değişkeni tarafından kontrol edilir ve /vendor/etc/selinux/genfs_labels_version.txt içinde depolanır.

Örnek:

  • Tedarikçi API düzeyi 202404'te /sys/class/udc düğümü varsayılan olarak sysfs şeklinde etiketlenir.
  • Tedarikçi API düzeyi 202504'ten itibaren /sys/class/udc, sysfs_udc olarak etiketlenir.

Ancak /sys/class/udc, API düzeyi 202404'ü kullanan vendor bölümlerinde varsayılan sysfs etiketi veya tedarikçiye özel bir etiketle birlikte kullanılıyor olabilir. /sys/class/udc'yı koşulsuz olarak sysfs_udc şeklinde etiketlemek, bu vendor bölümleriyle uyumluluğu bozabilir. BOARD_GENFS_LABELS_VERSION işaretlendiğinde platform, eski vendor bölümleri için önceki etiketleri ve izinleri kullanmaya devam eder.

BOARD_GENFS_LABELS_VERSION, satıcı API düzeyinden büyük veya bu düzeye eşit olabilir. Örneğin, vendor API düzeyi 202404'ü kullanan bölümler, 202504'te kullanıma sunulan yeni etiketleri benimsemek için BOARD_GENFS_LABELS_VERSION değerini 202504 olarak ayarlayabilir. 202504'e özel genfs etiketlerinin listesini inceleyin.

genfscon düğümleri etiketlenirken platform, eski vendor bölümleri dikkate almalı ve gerektiğinde uyumluluk için yedek mekanizmalar uygulamalıdır. Platform, genfs etiketleri sürümünü sorgulamak için yalnızca platforma özel kitaplıkları kullanabilir.

Platform-kamu politikası

Platform SELinux politikası, özel ve herkese açık olarak ikiye ayrılır. Platform-public politikası, platform ile satıcı arasında API görevi gören, satıcı API düzeyinde her zaman kullanılabilen türler ve özelliklerden oluşur. Bu politika, satıcıların satıcı politikası dosyaları oluşturabilmesi için satıcı politikası yazarlarına sunulur. Bu dosyalar, platforma özel politika ile birleştirildiğinde cihaz için tam işlevsel bir politika oluşturur. Platform kamu politikası system/sepolicy/public adresinde tanımlanmıştır.

Örneğin, tedarikçi bağlamında başlatma sürecini temsil eden vendor_init türü, system/sepolicy/public/vendor_init.te altında tanımlanır:

type vendor_init, domain;

Tedarikçiler, özel politika kuralları yazmak için vendor_init türüne başvurabilir:

# Allow vendor_init to set vendor_audio_prop in vendor's init scripts
set_prop(vendor_init, vendor_audio_prop)

Uyumluluk özellikleri

SELinux politikası, belirli nesne sınıfları ve izinler için kaynak ve hedef türler arasındaki etkileşimdir. SELinux politikasından etkilenen her nesne (ör. işlemler, dosyalar) yalnızca bir türe sahip olabilir ancak bu türün birden fazla özelliği olabilir.

Politika, çoğunlukla mevcut türler açısından yazılmıştır. Burada hem vendor_init hem de debugfs türdür:

allow vendor_init debugfs:dir { mounton };

Bu, politika tüm türler hakkında bilgi sahibi olunarak yazıldığı için işe yarar. Ancak satıcı politikası ve platform politikası belirli türleri kullanıyorsa ve belirli bir nesnenin etiketi yalnızca bu politikalardan birinde değişiyorsa diğerinde, daha önce erişim kazanmış veya kaybetmiş politika bulunabilir. Örneğin, platform politikasının sysfs düğümlerini sysfs olarak etiketlediğini varsayalım:

/sys(/.*)? u:object_r:sysfs:s0

Sağlayıcı politikası, /sys/usb olarak etiketlenen sysfs öğesine erişim izni verir:

allow vendor_init sysfs:chr_file rw_file_perms;

Platform politikası, /sys/usb öğesini sysfs_usb olarak etiketleyecek şekilde değiştirilirse satıcı politikası aynı kalır ancak yeni sysfs_usb türü için politika olmadığından vendor_init, /sys/usb öğesine erişimini kaybeder:

/sys/usb u:object_r:sysfs_usb:s0

Android, bu sorunu çözmek için sürüm oluşturulmuş özellikler kavramını sunar. Derleme sırasında, derleme sistemi, tedarikçi politikasında kullanılan platform herkese açık türlerini bu sürümlendirilmiş özelliklere otomatik olarak çevirir. Bu çeviri, sürüm oluşturulmuş bir özelliği platformdaki bir veya daha fazla genel türle ilişkilendiren eşleme dosyaları sayesinde sağlanır.

Örneğin, /sys/usb'nın 202504 platform politikasında sysfs olarak etiketlendiğini ve 202504 tedarikçi politikasının vendor_init'ye /sys/usb erişimi verdiğini varsayalım. Bu durumda:

  • 202504 platform politikasında /sys/usb, sysfs olarak etiketlendiği için sağlayıcı politikası bir kural allow vendor_init sysfs:chr_file rw_file_perms; yazıyor. Derleme sistemi, satıcı politikasını derlediğinde kuralı otomatik olarak allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms;'ya çevirir. vendor_init_202504 ve sysfs_202504 özellikleri, platform tarafından tanımlanan türler olan vendor_init ve sysfs türlerine karşılık gelir.
  • Derleme sistemi, bir kimlik eşleme dosyası oluşturur /system/etc/selinux/mapping/202504.cil. Hem system hem de vendor bölümleri aynı 202504 sürümünü kullandığından eşleme dosyası, type_202504 ile type arasındaki kimlik eşlemelerini içerir. Örneğin, vendor_init_202504, vendor_init ile eşlenir ve sysfs_202504, sysfs ile eşlenir:
    (typeattributeset sysfs_202504 (sysfs))
    (typeattributeset vendor_init_202504 (vendor_init))
    ...

Sürüm 202504'ten 202604'e yükseltildiğinde, 202504 vendor bölümleri için system/sepolicy/private/compat/202504/202504.cil altında yeni bir eşleme dosyası oluşturulur. Bu dosya, 202604 veya daha yeni system bölümleri için /system/etc/selinux/mapping/202504.cil'ye yüklenir. Başlangıçta bu eşleme dosyası, daha önce açıklandığı gibi kimlik eşlemelerini içerir. 202604 platform politikasına sysfs_usb için yeni bir etiket /sys/usb eklenirse eşleme dosyası, sysfs_202504 öğesini sysfs_usb ile eşleyecek şekilde güncellenir:

(typeattributeset sysfs_202504 (sysfs sysfs_usb))
(typeattributeset vendor_init_202504 (vendor_init))
...

Bu güncelleme, dönüştürülen tedarikçi politikası kuralının allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms; yeni sysfs_usb türüne otomatik olarak vendor_init erişim izni vermesini sağlar.

Eski vendor bölümleriyle uyumluluğu korumak için yeni bir herkese açık tür eklendiğinde bu tür, eşleme dosyasındaki system/sepolicy/private/compat/ver/ver.cil sürüm oluşturulmuş özelliklerden en az biriyle eşlenmeli veya önceki satıcı sürümlerinde eşleşen tür olmadığını belirtmek için system/sepolicy/private/compat/ver/ver.ignore.cil altında listelenmelidir.

Platform politikası, sağlayıcı politikası ve eşleme dosyasının birleşimi, sistemin sağlayıcı politikası güncellenmeden güncellenmesine olanak tanır. Ayrıca, sürüm oluşturulmuş özelliklere dönüştürme işlemi otomatik olarak gerçekleşir. Bu nedenle, satıcı politikası sürüm oluşturma işlemini ele almak zorunda kalmaz ve herkese açık türleri olduğu gibi kullanmaya devam eder.

system_ext public and product public policy

Android 11'den itibaren system_ext ve product bölümlerinin, belirlenen herkese açık türlerini vendor bölümüne aktarmasına izin verilir. Platform kamu politikası gibi, tedarikçi politikası da türleri ve kuralları otomatik olarak sürüm oluşturulmuş özelliklere çevirir. Örneğin, type, type_ver olur. Burada ver, vendor bölümünün tedarikçi API düzeyidir.

system_ext ve product bölümleri aynı platform sürümüne ver dayandığında derleme sistemi, type ile type_ver arasındaki kimlik eşlemelerini içeren system_ext/etc/selinux/mapping/ver.cil ve product/etc/selinux/mapping/ver.cil için temel eşleme dosyaları oluşturur. Tedarikçi politikası, sürüm oluşturulmuş özellik type ile type_ver öğesine erişebilir.

Yalnızca system_ext ve product bölümleri güncellenirse (ör. ver'den ver+1'e veya daha sonraki bir sürüme) ve vendor bölümü ver sürümünde kalırsa tedarikçi politikası, system_ext ve product bölüm türlerine erişimi kaybedebilir. Bozulmayı önlemek için system_ext ve product bölümleri, somut türlerden type_ver özelliklerine eşleme dosyaları sağlamalıdır. ver vendor bölümünü ver+1 (veya sonraki sürümler) system_ext ve product bölümleriyle destekleyen iş ortakları, eşleme dosyalarını korumaktan sorumludur.

Cihaz uygulayıcılarının veya satıcıların, eşleme dosyalarını system_ext ve product bölümlerine yüklemek için şunları yapması beklenir:

  1. Oluşturulan temel eşleme dosyalarını ver system_ext ve product bölümlerinden kaynak ağaçlarına kopyalayın.
  2. Eşleme dosyalarını gerektiği gibi değiştirin.
  3. ver+1 (veya sonraki) system_ext ve product bölümlerine eşleme dosyalarını yükleyin.

Örneğin, 202504 system_ext bölümünde foo_type adlı bir genel tür olduğunu varsayalım. Ardından system_ext/etc/selinux/mapping/202504.cil 202504 system_ext bölümünde şu şekilde görünür:

(typeattributeset foo_type_202504 (foo_type))
(expandtypeattribute foo_type_202504 true)
(typeattribute foo_type_202504)

bar_type, 202604 system_ext bölümüne eklenirse ve 202504 vendor bölümü için bar_type, foo_type ile eşlenmesi gerekiyorsa 202504.cil, (typeattributeset foo_type_202504 (foo_type)) değerinden (typeattributeset foo_type_202504 (foo_type bar_type)) değerine güncellenebilir ve ardından 202604 system_ext bölümüne yüklenebilir. 202504 vendor bölümü, 202604 system_ext bölümünün foo_type ve bar_type öğelerine erişmeye devam edebilir.

Android 9'daki özellik değişiklikleri

Android 9'a yükseltme yapan cihazlar aşağıdaki özellikleri kullanabilir ancak Android 9 ile kullanıma sunulan cihazlar kullanamaz.

İhlal eden kullanıcı özellikleri

Android 9, alanla ilgili şu özellikleri içerir:

  • data_between_core_and_vendor_violators. vendor ile coredomains arasında dosyaların yola göre paylaşılmaması şartını ihlal eden tüm alanlar için özellik. Platform ve sağlayıcı süreçleri, iletişim kurmak için diskteki dosyaları kullanmamalıdır (kararsız ABI). Öneri:
    • Tedarikçi kodu /data/vendor kullanmalıdır.
    • Sistem /data/vendor kullanmamalıdır.
  • system_executes_vendor_violators. Satıcı ikililerinin yürütülmemesi şartını ihlal eden tüm sistem alanları (init ve shell domains hariç) için özellik. Tedarikçi ikili dosyalarının yürütülmesinde kararsız API var. Platform, satıcı ikililerini doğrudan çalıştırmamalıdır. Öneri:
    • Satıcı ikililerine yönelik bu tür platform bağımlılıkları, HIDL HAL'lerinin arkasında olmalıdır.

      VEYA

    • coredomains bölümüne taşınmalı ve böylece coredomain olmaktan çıkmalıdır.vendor

Güvenilmeyen özellikler

Rastgele kod barındıran güvenilmeyen uygulamaların, bu tür uygulamalardan erişim için yeterince güvenli olduğu düşünülenler dışında HwBinder hizmetlerine erişimi olmamalıdır (aşağıdaki güvenli hizmetlere bakın). Bunun iki temel nedeni vardır:

  1. HwBinder sunucuları, HIDL şu anda arayan UID bilgilerini göstermediği için istemci kimlik doğrulaması yapmaz. HIDL bu tür verileri kullanıma sunsa bile birçok HwBinder hizmeti uygulamaların altında bir düzeyde çalışır (ör. HAL'ler) veya yetkilendirme için uygulama kimliğine güvenmemelidir. Bu nedenle, güvenli olması için varsayılan olarak her HwBinder hizmetinin, tüm istemcilerine hizmet tarafından sunulan işlemleri gerçekleştirmek için eşit derecede yetkiliymiş gibi davrandığı kabul edilir.
  2. HAL sunucuları (HwBinder hizmetlerinin bir alt kümesi), system/core bileşenlerine kıyasla daha yüksek güvenlik sorunu sıklığına sahip kod içerir ve yığının alt katmanlarına (donanıma kadar) erişebilir. Bu nedenle, Android güvenlik modelini atlama fırsatları artar.

Güvenli hizmetler

Güvenli hizmetler şunlardır:

  • same_process_hwservice. Bu hizmetler (tanım gereği) istemci sürecinde çalışır ve bu nedenle, sürecin çalıştığı istemci alanıyla aynı erişime sahiptir.
  • coredomain_hwservice. Bu hizmetler, 2. nedene bağlı riskler oluşturmaz.
  • hal_configstore_ISurfaceFlingerConfigs. Bu hizmet, özellikle herhangi bir alan tarafından kullanılmak üzere tasarlanmıştır.
  • hal_graphics_allocator_hwservice. Bu işlemler, uygulamaların erişmesine izin verilen surfaceflinger Binder hizmeti tarafından da sunulur.
  • hal_omx_hwservice. Bu, uygulamaların erişmesine izin verilen mediacodec Binder hizmetinin HwBinder sürümüdür.
  • hal_codec2_hwservice. Bu, hal_omx_hwservice uygulamasının daha yeni bir sürümüdür.

Kullanılabilir özellikler

Güvenli olmadığı düşünülen tüm hwservices öğelerinde untrusted_app_visible_hwservice özelliği bulunur. İlgili HAL sunucularında untrusted_app_visible_halserver özelliği bulunur. Android 9 ile kullanıma sunulan cihazlar untrusted özelliğini KULLANMAMALIDIR.

Öneri:

  • Güvenilmeyen uygulamalar bunun yerine, satıcı HIDL HAL ile iletişim kuran bir sisteme ait hizmetle iletişim kurmalıdır. Örneğin, uygulamalar binderservicedomain ile konuşabilir, ardından mediaserver (binderservicedomain olan) sırayla hal_graphics_allocator ile konuşur.

    VEYA

  • vendor HAL'lerine doğrudan erişmesi gereken uygulamaların kendi tedarikçi tanımlı sepolicy alanları olmalıdır.

Dosya özelliği testleri

Android 9, belirli konumlardaki tüm dosyaların uygun özelliklere (ör. sysfs içindeki tüm dosyaların gerekli sysfs_type özelliğine) sahip olmasını sağlayan derleme zamanı testleri içerir.

SELinux bağlamları etiketleme

Platform ve satıcı sepolicy arasındaki ayrımı desteklemek için sistem, SELinux bağlam dosyalarını ayrı tutmak üzere farklı şekilde oluşturur.

Dosya bağlamları

Android 8.0, file_contexts için aşağıdaki değişiklikleri getirmiştir:

  • Önyükleme sırasında cihazda ek derleme yükünden kaçınmak için, file_contexts ikili biçimde var olmamalıdır. Bunun yerine, {property, service}_contexts gibi okunabilir normal ifade metin dosyalarıdır (7.0'dan önceki sürümlerde olduğu gibi).
  • file_contexts iki dosyaya bölünür:
    • plat_file_contexts
      • Android platformu file_context. /vendor bölümünün, sepolicy dosyalarının düzgün çalışmasını sağlamak için hassas bir şekilde etiketlenmesi gereken kısımları hariç olmak üzere cihaza özel etiketler içermez.
      • Cihazda system bölümünde /system/etc/selinux/plat_file_contexts konumunda bulunmalı ve başlangıçta init tarafından satıcı file_context ile birlikte yüklenmelidir.
    • vendor_file_contexts
      • Cihaza özel file_context, cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS ile işaret edilen dizinlerde bulunan file_contexts birleştirilerek oluşturulur.
      • vendor bölümünde /vendor/etc/selinux/vendor_file_contexts konumuna yüklenmeli ve platform file_context ile birlikte başlangıçta init tarafından yüklenmelidir.

Mülk bağlamları

Android 8.0'da property_contexts iki dosya arasında bölünür:

  • plat_property_contexts
    • Cihaza özel etiketleri olmayan Android platformu property_context.
    • system bölümünde /system/etc/selinux/plat_property_contexts konumunda bulunmalı ve başlangıçta satıcı property_contexts ile birlikte init tarafından yüklenmelidir.
  • vendor_property_contexts
    • Cihaza özel property_context, cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS ile işaret edilen dizinlerde bulunan property_contexts birleştirilerek oluşturulur.
    • vendor bölümünde /vendor/etc/selinux/vendor_property_contexts konumunda bulunmalı ve platform property_context ile birlikte başlangıçta init tarafından yüklenmelidir.

Hizmet bağlamları

Android 8.0'da service_contexts aşağıdaki dosyalar arasında bölünmüştür:

  • plat_service_contexts
    • Android platformuna özel service_context servicemanager için. service_context öğesinin cihaza özel etiketleri yok.
    • system bölümünde /system/etc/selinux/plat_service_contexts konumunda bulunmalı ve başlangıçta satıcı service_contexts ile birlikte servicemanager tarafından yüklenmelidir.
  • vendor_service_contexts
    • Cihaza özel service_context, cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS ile işaret edilen dizinlerde bulunan service_contexts birleştirilerek oluşturulur.
    • vendor bölümünde /vendor/etc/selinux/vendor_service_contexts konumunda bulunmalı ve platform service_contexts ile birlikte başlangıçta servicemanager tarafından yüklenmelidir.
    • servicemanager, bu dosyayı başlatma sırasında arasa da TREBLE cihazının tamamen uyumlu olması için vendor_service_contexts dosyası OLMAMALIDIR. Bunun nedeni, vendor ile system arasındaki tüm etkileşimlerin hwservicemanager/hwbinder üzerinden geçmesi GEREKMESİDİR.
  • plat_hwservice_contexts
    • Android platformu hwservice_context for hwservicemanager cihazına özel etiketleri olmayan.
    • system bölümünde /system/etc/selinux/plat_hwservice_contexts konumunda bulunmalı ve vendor_hwservice_contexts ile birlikte başlangıçta hwservicemanager tarafından yüklenmelidir.
  • vendor_hwservice_contexts
    • Cihaza özel hwservice_context, cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS ile işaret edilen dizinlerde bulunan hwservice_contexts birleştirilerek oluşturulur.
    • vendor bölümünde /vendor/etc/selinux/vendor_hwservice_contexts konumunda bulunmalı ve hwservicemanager tarafından plat_service_contexts ile birlikte başlangıçta yüklenmelidir.
  • vndservice_contexts
    • Cihaza özel service_context için vndservicemanager oluşturulur. Bu işlem, cihazın Boardconfig.mk içindeki BOARD_SEPOLICY_DIRS tarafından işaret edilen dizinlerde bulunan vndservice_contexts birleştirilerek yapılır.
    • Bu dosya, vendor bölümünde /vendor/etc/selinux/vndservice_contexts konumunda bulunmalı ve başlangıçta vndservicemanager tarafından yüklenmelidir.

Seapp bağlamları

Android 8.0'da seapp_contexts iki dosya arasında bölünür:

  • plat_seapp_contexts
    • Cihaza özel değişiklikler içermeyen Android platformu seapp_context.
    • system bölümünde /system/etc/selinux/plat_seapp_contexts. konumunda bulunmalıdır.
  • vendor_seapp_contexts
    • Cihazın seapp_context platformuna özel uzantı, cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS tarafından işaret edilen dizinlerde bulunan seapp_contexts birleştirilerek oluşturulur.
    • /vendor/etc/selinux/vendor_seapp_contexts konumundaki vendor bölümünde bulunmalıdır.

MAC izinleri

Android 8.0'da mac_permissions.xml iki dosya arasında bölünür:

  • Platform mac_permissions.xml
    • Cihaza özel değişiklikler içermeyen Android platformu mac_permissions.xml.
    • system bölümünde /system/etc/selinux/. konumunda bulunmalıdır.
  • Platform Dışı mac_permissions.xml
    • Cihaza özel uzantı, platforma mac_permissions.xml oluşturuldu mac_permissions.xml cihazın Boardconfig.mk dosyalarındaki BOARD_SEPOLICY_DIRS tarafından işaret edilen dizinlerde bulundu.
    • vendor bölümünde /vendor/etc/selinux/. konumunda bulunmalıdır.

Android 17'de paylaşılan anı değişiklikleri

Android 17'den itibaren, aşağıdaki özelliklerle kullanıma sunulan cihazların memfd_class politika özelliğini etkinleştirmesi ve paylaşılan bellek ile ilgili politikalarını memfd_file sınıfı nesnelerini destekleyecek şekilde güncellemesi gerekir:

  • Tedarikçilere ve OEM'lere tedarikçi politikalarını memfd'yı destekleyecek şekilde güncellemeleri için fırsat sunmak üzere tedarikçi API düzeyi 202604 veya daha yüksek olmalıdır. Ayrıca, mevcut cihazların satıcı bölümünde güncelleme yapılmasına gerek kalmadan Android'in daha yeni sürümlerine yükseltilmesine olanak tanır.
  • android16-6.12 veya daha yüksek çekirdek sürümü gerekir. Bu çekirdekler, memfd için ayrıntılı politika uygulanması gereken memfd_class özelliğini destekler.

memfd_class politika özelliğini etkinleştirme

SELinux, yakın zamana kadar memfd öğesini, destekleyen dosya sistemiyle (tmpfs) aynı türde bir dosya olarak etiketliyordu. Bu durum, politika açısından bir memfd ile tmpfs bağlama noktasındaki başka bir dosyanın ayırt edilmesini imkansız hale getiriyordu. SELinux artık memfd öğesini, tahsis eden işlemin güvenlik bağlamıyla etiketliyor ve memfds öğeleri memfd_file sınıfı nesneler olarak değerlendiriliyor. Bu işlev, eski kullanıcı alanı ortamlarıyla geriye dönük uyumluluğu korumak için memfd_class politika özelliğiyle korunur.

memfd_class politika özelliğini etkinleştirmek için BOARD_VENDOR_SEPOLICY_DIRS altında bir policy_capabilities dosyası oluşturun. Dosya aşağıdaki girişi içermelidir:

# $BOARD_VENDOR_SEPOLICY_DIRS/*/policy_capabilities
policycap memfd_class;

Ardından, özelliği etkinleştirdiğinizi doğrulamak için görüntülerinizi yeniden oluşturun ve cihazınıza yükleyin.

memfd_class politika özelliğinin etkinleştirildiğini doğrulayın.

memfd_class politika özelliğinin durumunu kontrol etmek için aşağıdaki komutu kullanın:

adb shell 'cat /sys/fs/selinux/policy_capabilities/memfd_class'

Sonuç 1 ise memfd_class politika özelliği etkinleştirilir. Aksi takdirde etkinleştirilmez.

Mevcut politikayı memfd'ye geçirme

Belirli işlemler, tmpfs_domain() makrosunu kullanarak memfds öğelerine erişip ad alanı oluşturmak için politikalarında kullanır. Örneğin:

# foo.te
tmpfs_domain(foo)

Bu durumda:

# foo.te
type_transition foo tmpfs:file foo_tmpfs;
allow foo foo_tmpfs:file { read write getattr map };

ve bar işleminin foo işleminin memfds'sine şu şekilde erişmesine izin verir:

# bar.te
allow bar foo_tmpfs:file { read write getattr map };

memfd_class politika özelliği etkinleştirildiğinde, platform politikası herhangi bir işlemin kendi memfds'sini oluşturup kullanmasına izin verecek şekilde güncellendiğinden tmpfs_domain() makrosuna artık gerek yoktur.

# system/sepolicy/private/domain.te
allow domain self:memfd_file { create read write getattr map };

ve memfds oluşturulan foo işlemine bar işlemi şu şekilde erişebilir:

# bar.te
allow bar foo:memfd_file { read write getattr map };

Platformun politikası, memfd ile ilgili mevcut kullanımları hesaba katacak şekilde güncellendi. Ancak tmpfs etiketlerini kullanan tedarikçi ve cihaza özgü politikaların memfd_file etiketlerini kullanacak şekilde güncellenmesi gerekir. Politika, satıcı API düzeyi 202604 veya daha yüksek olmayan SoC'ler ya da cihazlar arasında paylaşılıyorsa uyumluluk için eski tmpfs politikasının yeni memfd_file politikasıyla birlikte korunması önerilir.

memfd ile ilgili AVC retlerini belirleme

Memfd ile ilgili retler aşağıdaki komut kullanılarak alınabilir:

adb shell logcat -d -b events | grep memfd

Hedef olarak tmpfs ile avc retleri

Aşağıdaki örnekte, yazma izni olmayan bir memfd öğesine yazmaya çalışan bir işlem tarafından karşılaşılan avc reddi gösterilmektedir:

audit(0.0:539): avc:  denied  { write } for  comm="binder:665_1" name="memfd:MessageQueue"
dev="tmpfs" ino=8324 scontext=u:r:mediacodec:s0 tcontext=u:object_r:tmpfs:s0 tclass=file
permissive=0

memfd_class politika özelliği etkinleştirildiğinde, memfd hedef bağlamı tmpfs değil, ayırma işleminin güvenlik bağlamı olur ve hedef sınıf file değil, memfd_file olur. Bu nedenle, söz konusu memfd, tmpfs dosyası olarak etiketlenmişse avc ile ilgili memfd retleri görüyorsanız memfd_class politika özelliği etkin değildir.

Hedef sınıf olarak memfd_file ile avc reddetmeleri

Aşağıdaki örnekte, yazma izni olmayan bir memfd öğesine yazmaya çalışan bir işlem tarafından karşılaşılan avc reddi ve memfd_class politika özelliğinin etkinleştirilmesi gösterilmektedir. Ayrıca, reddin ardından logd'nin aynı zaman damgasıyla yayınladığı ek bir satır da gösterilmektedir:

audit(0.0:86): avc: denied { read } for
path=2F6D656D66643A4D6564696142756666657247726F7570202864656C6574656429 ino=512 dev=""
scontext=u:r:mediaserver:s0 tcontext=u:object_r:mediaextractor:s0 tclass=memfd_file

auditd  : Decoded path for audit(0.0:86): /memfd:MediaBufferGroup (deleted)

Eşleşen zaman damgası, Decoded path for … log öğesinin 0.0.86 zaman damgalı avc ret işlemiyle ilişkili olduğunu gösterir. Bu günlük, avc reddetme işlemindeki yol değerinden onaltılık dizeyi çözer ve hangi arabelleğin paylaşıldığını anlamak için yararlı olabilecek memfd bellek bölgesinin adını sağlar. Kaynak bağlam ve hedef bağlam, hangi işlemlerin belleği paylaşması gerektiğini anlamak için yararlıdır. Önceki örnekten, mediaserver işleminin mediaextractor'nin memfds'sine erişebilmesi gerektiği anlaşılmaktadır. Bu nedenle, uygun politika şudur:

# mediaserver.te
allow mediaserver mediaextractor:memfd_file { getattr read write map };

Android 17'deki güvenlik alanı güncellemeleri

Android 17'deki ASharedMemory_create() API, paylaşılan bellek ayırmaları için eski ashmem sürücüsü ile memfd çerçevesi arasında seçim yapmak üzere koşullu mantık uygular.

memfd şartlarını karşılayan cihazlarda (sağlayıcı API düzeyi 202604 veya daha yüksek ve çekirdek android16-6.12 veya daha yeni) API, arayan uygulamanın targetSdkVersion değerini değerlendirir. Hedef SDK sürümü 37 veya daha yüksekse memfd ayrılır. Bu sayede geliştiriciler, hedef SDK sürümlerini yükseltirken karşılaştıkları sorunları düzeltebilir.

Cihaz memfd's ön koşullarını karşılamıyorsa ASharedMemory ashmem'e geri döner. Bu sayede, yükseltilmiş cihazlar eski sağlayıcı bölümleri veya çekirdekleriyle uyumlu kalır.

Bu geçişi zorunlu kılmak için platform SELinux politikası, platform_app, priv_app ve untrusted_app güvenlik alanlarında SDK sürümü 37 veya sonraki sürümleri hedefleyen uygulamaların /dev/ashmem açmasını ve memfd üzerinde ashmem ioctl komutlarını çağırmasını engeller. Bu, söz konusu uygulama alanlarının hedef SDK sürümüne göre bölünmesiyle sağlanır. Bu işlem, platform_app_36, priv_app_36 ve untrusted_app_34 güvenlik alanlarını kullanıma sunar. Bu alanlar, diğer uygulama alanlarıyla birlikte ashmem açık izinlerini ve memfds üzerinde ashmem ioctl komutlarını çağırma özelliğini korur.

Gelecekteki bir Android sürümünde, ashmem cihazını açma ve memfds üzerinde ashmem ioctl komutlarını çağırma izinlerini koruyan uygulamaların sayısı yalnızca platform_app_36, priv_app_36 ve untrusted_app_34 ile eski SDK sürümleri için güvenilmeyen uygulama alanlarıyla sınırlı olacak.

Hedef SDK sürümünü sabitleyen uygulamalar için özel tedarikçi veya OEM SELinux politikaları, aşağıdaki bölümlerde ayrıntılı olarak açıklandığı gibi bu alan değişiklikleriyle uyumlu olacak şekilde güncellenmelidir.

platform_app SELinux alan güncellemeleri

platform_app alanı, uygulamanın targetSdkVersion değerine göre bölünür. SDK sürümü 37 veya sonraki sürümleri hedefleyen platform uygulamalarına platform_app alanı atanırken SDK sürümü 36 veya önceki sürümleri hedefleyen uygulamalar platform_app_36 alanını kullanır. platform_app_36 alanı, geriye dönük uyumluluk için /dev/ashmem açma özelliğini korur. Her iki alanda da politika yönetimini basitleştirmek için platform_app_all özelliğini kullanın.

Platform uygulamasının sample-plat-app, /dev/foo_device konumundan okuma ve yazma işlemleri yapması gerektiğini düşünelim. Mevcut tedarikçi SELinux politikası şu şekilde görünebilir:

# This will only allow sample-plat-app to access the device if it
# is placed in the platform_app domain (i.e. target SDK version is 37 or higher).
allow platform_app foo_device:chr_file rw_file_perms;

Ancak sample-plat-app hedef SDK sürümü 36'ya sabitlenirse platform_app_36 alanına yerleştirilir ve daha önceki SELinux politikası uygulanmaz. Ayrıca aşağıdaki AVC reddi gözlemlenir:

auditd  : type=1400 audit(0.0:11): avc:  denied  { read write } for  comm="sample-plat-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:platform_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0

Bu sorunu düzeltmek için uygulama her zaman cihaz düğümüne erişebileceğinden politika aşağıdaki gibi güncellenebilir:

# This allows sample-plat-app to access the device independent of
# target SDK version.
allow platform_app_all foo_device:chr_file rw_file_perms;

platform_app_all simgesinin çalışmadığı durumlar olabilir. Örneğin, hal_client_domain() makrosu platform_app_all ile kullanılırsa politika derlenemez. Bunun nedeni, platform_app_all bir özellik olduğundan hal_client_domain()'nin buna başka bir özellik eklemeye çalışmasıdır. Bu mümkün değildir:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

Bu senaryolarda, platform_app_36 türünün doğrudan kullanılması gerekir. Bu nedenle, politikanızda aşağıdaki içerik yer alır:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

# platform_app_36.te
hal_client_domain(platform_app_36, hal_foo)

priv_app SELinux alan güncellemeleri

priv_app alanı, uygulamanın targetSdkVersion değerine göre bölünür. SDK sürümü 37 veya sonraki sürümleri hedefleyen ayrıcalıklı uygulamalara priv_app alanı atanırken SDK sürümü 36 veya önceki sürümleri hedefleyen uygulamalar priv_app_36 alanını kullanır. priv_app_36 alanı, geriye dönük uyumluluk için /dev/ashmem açma özelliğini korur. Her iki alanda da politika yönetimini basitleştirmek için priv_app_all özelliğini kullanın.

Platform uygulamasının sample-priv-app, /dev/foo_device konumundan okuma ve yazma işlemleri yapması gerektiğini düşünelim. Mevcut tedarikçi SELinux politikası şu şekilde görünebilir:

# This will only allow sample-priv-app to access the device if it
# is placed in the priv_app domain (i.e. target SDK version is 37 or higher).
allow priv_app foo_device:chr_file rw_file_perms;

Ancak sample-priv-app hedef SDK sürümü 36'ya sabitlenirse priv_app_36 alanına yerleştirilir ve daha önceki SELinux politikası uygulanmaz. Ayrıca aşağıdaki AVC reddi gözlemlenir:

auditd  : type=1400 audit(0.0:11): avc:  denied  { read write } for  comm="sample-priv-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:priv_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0

Bu sorunu düzeltmek için uygulama her zaman cihaz düğümüne erişebileceğinden politika aşağıdaki gibi güncellenebilir:

# This allows sample-priv-app to access the device independent of
# target SDK version.
allow priv_app_all foo_device:chr_file rw_file_perms;

priv_app_all simgesinin çalışmadığı durumlar olabilir. Örneğin, hal_client_domain() makrosu priv_app_all ile birlikte kullanılırsa politika derlenemez. Bunun nedeni, priv_app_all bir özellik olduğundan hal_client_domain()'nin buna başka bir özellik eklemeye çalışmasıdır. Bu mümkün değildir:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

Bu gibi durumlarda, priv_app_36 türünün doğrudan kullanılması gerekir. Bu nedenle, politika dosyalarınız aşağıdaki gibi görünür:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

# priv_app_36.te
hal_client_domain(priv_app_36, hal_foo)

untrusted_app SELinux alanı güncellemeleri

untrusted_app alanı, uygulamanın targetSdkVersion değerine göre bölünür. SDK 37 sürümünü veya sonraki sürümleri hedefleyen güvenilmeyen uygulamalara untrusted_app alanı, SDK 34-36 sürümlerini hedefleyenlere ise yeni untrusted_app_34 alanı atanır. untrusted_app_34 alanının yanı sıra untrusted_app_X alanları (burada "X" eski bir hedef SDK sürümüdür) geriye dönük uyumluluk için `/dev/ashmem` dosyasını açma özelliğini korur.