Kompatibilitas kebijakan

Halaman ini menjelaskan cara Android menangani masalah kompatibilitas kebijakan dengan update over-the-air (OTA) platform, yang mana setelan SELinux platform baru mungkin berbeda dengan setelan SELinux vendor lama.

Kepemilikan dan pelabelan objek

Kepemilikan harus ditentukan dengan jelas untuk setiap objek agar kebijakan platform dan vendor tetap terpisah. Misalnya, jika label kebijakan vendor /dev/foo dan label kebijakan platform /dev/foo dalam OTA berikutnya, akan ada perilaku yang tidak ditentukan seperti penolakan yang tidak terduga, atau lebih parah lagi, kegagalan booting. Untuk SELinux, hal ini muncul sebagai konflik pemberian label. Node perangkat hanya dapat memiliki satu label yang diselesaikan ke label mana pun yang diterapkan terakhir. Akibatnya:

  • Proses yang memerlukan akses ke label yang gagal diterapkan akan kehilangan akses ke resource.
  • Proses yang mendapatkan akses ke file dapat terganggu karena node perangkat yang salah dibuat.

Konflik antara label platform dan vendor dapat terjadi untuk objek apa pun yang memiliki label SELinux, termasuk properti, layanan, proses, file, dan soket. Untuk menghindari masalah ini, tentukan kepemilikan objek ini dengan jelas.

Namespace jenis/atribut

Selain konflik label, nama atribut dan jenis SELinux juga dapat berkonflik. SELinux tidak mengizinkan beberapa deklarasi jenis dan atribut yang sama. Kebijakan dengan pernyataan duplikat gagal dikompilasi. Untuk menghindari bentrokan nama atribut dan jenis, sebaiknya semua deklarasi vendor dimulai dengan awalan vendor_. Misalnya, vendor harus menggunakan type vendor_foo, domain;, bukan type foo, domain;.

Kepemilikan file

Mencegah tabrakan untuk file merupakan tantangan karena kebijakan platform dan vendor umumnya memberikan label untuk semua sistem file. Tidak seperti penamaan jenis, pemberian namespace pada file tidak praktis karena banyak di antaranya dibuat oleh kernel. Untuk mencegah tabrakan ini, ikuti panduan penamaan untuk sistem file di bagian ini. Untuk Android 8.0, berikut adalah rekomendasi tanpa penerapan teknis. Pada masa mendatang, rekomendasi ini akan diterapkan oleh Vendor Test Suite (VTS).

Sistem (/system)

Hanya image sistem yang harus memberikan label untuk komponen /system melalui file_contexts, service_contexts, dll. Jika label untuk komponen /system ditambahkan dalam kebijakan vendor, update OTA khusus framework mungkin tidak dapat dilakukan.

Vendor (/vendor)

Kebijakan SELinux AOSP telah memberi label pada bagian partisi vendor yang berinteraksi dengan platform, sehingga memungkinkan penulisan aturan SELinux untuk proses platform agar dapat berkomunikasi atau mengakses bagian partisi vendor. Contoh:

/vendor path Label yang disediakan platform Proses platform bergantung pada label
/vendor(/.*)? vendor_file Semua klien HAL dalam framework, ueventd, dll.
/vendor/framework(/.*)? vendor_framework_file dex2oat, appdomain, dll.
/vendor/app(/.*)? vendor_app_file dex2oat, installd, idmap, dll.
/vendor/overlay(/.*) vendor_overlay_file system_server, zygote, idmap, dll.

Oleh karena itu, aturan khusus harus diikuti (diterapkan melalui neverallows) saat memberi label pada file tambahan di partisi vendor:

  • vendor_file harus menjadi label default untuk semua file di partisi vendor. Kebijakan platform mewajibkan hal ini untuk mengakses implementasi HAL teruskan.
  • Semua exec_types baru yang ditambahkan di partisi vendor melalui kebijakan vendor harus memiliki atribut vendor_file_type. Hal ini diterapkan melalui neverallows.
  • Untuk menghindari konflik dengan update platform/framework pada masa mendatang, hindari memberi label pada file selain exec_types di partisi vendor.
  • Semua dependensi library untuk HAL proses yang sama yang diidentifikasi AOSP harus diberi label sebagai same_process_hal_file.

Procfs (/proc)

File dalam /proc hanya dapat diberi label menggunakan label genfscon. Di Android 7.0, kebijakan platform dan vendor menggunakan genfscon untuk memberi label pada file di procfs.

Rekomendasi: Hanya label kebijakan platform /proc. Jika proses vendor memerlukan akses ke file di /proc yang saat ini diberi label default (proc), kebijakan vendor tidak boleh memberi label secara eksplisit dan harus menggunakan jenis proc generik untuk menambahkan aturan bagi domain vendor. Hal ini memungkinkan update platform mengakomodasi antarmuka kernel mendatang yang diekspos melalui procfs dan melabelinya secara eksplisit sesuai kebutuhan.

Debugfs (/sys/kernel/debug)

Debugfs dapat diberi label di file_contexts dan genfscon. Di Android 7.0 hingga Android 10, label platform dan vendor debugfs.

Di Android 11, debugfs tidak dapat diakses atau di-mount di perangkat produksi. Produsen perangkat harus menghapus debugfs.

Tracefs (/sys/kernel/debug/tracing)

Tracefs dapat diberi label di file_contexts dan genfscon. Di Android 7.0, hanya label platform tracefs.

Rekomendasi: Hanya platform yang dapat memberi label tracefs.

Sysfs (/sys)

File di /sys dapat diberi label menggunakan file_contexts dan genfscon. Di Android 7.0, platform dan vendor menggunakan genfscon untuk memberi label pada file di sysfs.

Rekomendasi: Platform dapat memberi label pada node sysfs yang tidak spesifik untuk perangkat. Jika tidak, hanya vendor yang dapat memberi label pada file.

tmpfs (/dev)

File di /dev dapat diberi label di file_contexts. Di Android 7.0, file label platform dan vendor berada di sini.

Rekomendasi: Vendor hanya dapat memberi label pada file di /dev/vendor (misalnya, /dev/vendor/foo, /dev/vendor/socket/bar).

Rootfs (/)

File di / dapat diberi label di file_contexts. Di Android 7.0, file label platform dan vendor ada di sini.

Rekomendasi: Hanya sistem yang dapat memberi label pada file di /.

Data (/data)

Data diberi label melalui kombinasi file_contexts dan seapp_contexts.

Rekomendasi: Jangan izinkan pemberian label vendor di luar /data/vendor. Hanya platform yang dapat memberi label pada bagian lain dari /data.

Versi label Genfs

Mulai dari level API vendor 202504, label SELinux baru yang ditetapkan dengan genfscon di system/sepolicy/compat/plat_sepolicy_genfs_ver.cil bersifat opsional untuk partisi vendor yang lebih lama. Hal ini memungkinkan partisi vendor yang lebih lama mempertahankan implementasi SEPolicy yang ada. Hal ini dikontrol oleh variabel Makefile BOARD_GENFS_LABELS_VERSION yang disimpan di /vendor/etc/selinux/genfs_labels_version.txt.

Contoh:

  • Di level API vendor 202404, node /sys/class/udc diberi label sysfs secara default.
  • Mulai dari level API vendor 202504, /sys/class/udc diberi label sysfs_udc.

Namun, /sys/class/udc mungkin digunakan oleh partisi vendor yang menggunakan level API 202404, baik dengan label sysfs default maupun label khusus vendor. Memberi label /sys/class/udc sebagai sysfs_udc tanpa syarat dapat merusak kompatibilitas dengan partisi vendor ini. Dengan mencentang BOARD_GENFS_LABELS_VERSION, platform akan terus menggunakan label dan izin sebelumnya untuk partisi vendor yang lebih lama.

BOARD_GENFS_LABELS_VERSION dapat lebih besar dari atau sama dengan level API vendor. Misalnya, partisi vendor yang menggunakan level API 202404 dapat menetapkan BOARD_GENFS_LABELS_VERSION ke 202504 untuk menerapkan label baru yang diperkenalkan pada 202504. Lihat daftar label genfs khusus 202504.

Saat memberi label pada node genfscon, platform harus mempertimbangkan partisi vendor yang lebih lama dan menerapkan mekanisme penggantian untuk kompatibilitas jika diperlukan. Platform dapat menggunakan library khusus platform untuk membuat kueri versi label genfs.

Kebijakan publik platform

Kebijakan SELinux platform dibagi menjadi pribadi dan publik. Kebijakan platform-public terdiri dari jenis dan atribut yang selalu tersedia untuk level API vendor, yang bertindak sebagai API antara platform dan vendor. Kebijakan ini diekspos ke penulis kebijakan vendor agar vendor dapat membuat file kebijakan vendor, yang jika digabungkan dengan kebijakan khusus platform, akan menghasilkan kebijakan yang berfungsi penuh untuk perangkat. Kebijakan publik platform ditentukan dalam system/sepolicy/public.

Misalnya, jenis vendor_init, yang merepresentasikan proses init dalam konteks vendor, ditentukan di bagian system/sepolicy/public/vendor_init.te:

type vendor_init, domain;

Vendor dapat merujuk ke jenis vendor_init untuk menulis aturan kebijakan kustom:

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

Atribut kompatibilitas

Kebijakan SELinux adalah interaksi antara jenis sumber dan target untuk izin dan class objek tertentu. Setiap objek (misalnya, proses, file) yang terpengaruh oleh kebijakan SELinux hanya dapat memiliki satu jenis, tetapi jenis tersebut mungkin memiliki beberapa atribut.

Kebijakan ini sebagian besar ditulis dalam hal jenis yang ada. Di sini, vendor_init dan debugfs adalah jenis:

allow vendor_init debugfs:dir { mounton };

Hal ini berfungsi karena kebijakan ditulis dengan pengetahuan tentang semua jenis. Namun, jika kebijakan vendor dan kebijakan platform menggunakan jenis tertentu, dan label objek tertentu berubah hanya dalam salah satu kebijakan tersebut, kebijakan lainnya mungkin berisi kebijakan yang sebelumnya memperoleh atau kehilangan akses yang diandalkan. Misalnya, anggaplah bahwa kebijakan platform melabeli node sysfs sebagai sysfs:

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

Kebijakan vendor memberikan akses ke /sys/usb, yang diberi label sebagai sysfs:

allow vendor_init sysfs:chr_file rw_file_perms;

Jika kebijakan platform diubah untuk memberi label /sys/usb sebagai sysfs_usb, kebijakan vendor tetap sama, tetapi vendor_init kehilangan akses ke /sys/usb karena tidak adanya kebijakan untuk jenis sysfs_usb baru:

/sys/usb u:object_r:sysfs_usb:s0

Untuk mengatasi masalah ini, Android memperkenalkan konsep atribut berversi. Pada waktu kompilasi, sistem build secara otomatis menerjemahkan jenis publik platform yang digunakan dalam kebijakan vendor ke atribut berversi ini. Terjemahan ini diaktifkan oleh file pemetaan yang mengaitkan atribut berversi dengan satu atau beberapa jenis publik dari platform.

Misalnya, anggap /sys/usb diberi label sebagai sysfs dalam kebijakan platform 202504, dan kebijakan vendor 202504 memberikan vendor_init akses ke /sys/usb. Dalam hal ini:

  • Kebijakan vendor menulis aturan allow vendor_init sysfs:chr_file rw_file_perms;, karena /sys/usb diberi label sebagai sysfs dalam kebijakan platform 202504. Saat sistem build mengompilasi kebijakan vendor, sistem akan otomatis menerjemahkan aturan ke allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms;. Atribut vendor_init_202504 dan sysfs_202504 sesuai dengan jenis vendor_init dan sysfs, yang merupakan jenis yang ditentukan oleh platform.
  • Sistem build menghasilkan file pemetaan identitas /system/etc/selinux/mapping/202504.cil. Karena partisi system dan vendor menggunakan versi 202504 yang sama, file pemetaan berisi pemetaan identitas dari type_202504 ke type. Misalnya, vendor_init_202504 dipetakan ke vendor_init, dan sysfs_202504 dipetakan ke sysfs:
    (typeattributeset sysfs_202504 (sysfs))
    (typeattributeset vendor_init_202504 (vendor_init))
    ...

Saat versi diubah dari 202504 menjadi 202604, file pemetaan baru untuk partisi vendor 202504 dibuat di system/sepolicy/private/compat/202504/202504.cil, yang diinstal ke /system/etc/selinux/mapping/202504.cil untuk partisi system 202604 atau yang lebih baru. Awalnya, file pemetaan ini berisi pemetaan identitas, seperti yang dijelaskan sebelumnya. Jika label baru sysfs_usb untuk /sys/usb ditambahkan ke kebijakan platform 202604, file pemetaan diperbarui untuk memetakan sysfs_202504 ke sysfs_usb:

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

Pembaruan ini memungkinkan aturan kebijakan vendor yang dikonversi allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms; untuk otomatis memberikan akses vendor_init ke jenis sysfs_usb baru.

Untuk mempertahankan kompatibilitas dengan partisi vendor yang lebih lama, setiap kali jenis publik baru ditambahkan, jenis tersebut harus dipetakan ke setidaknya salah satu atribut berversi dalam file pemetaan system/sepolicy/private/compat/ver/ver.cil, atau dicantumkan di bagian system/sepolicy/private/compat/ver/ver.ignore.cil untuk menyatakan bahwa tidak ada jenis yang cocok dalam versi vendor sebelumnya.

Kombinasi kebijakan platform, kebijakan vendor, dan file pemetaan memungkinkan sistem melakukan update tanpa mengupdate kebijakan vendor. Selain itu, konversi ke atribut berversi terjadi secara otomatis, sehingga kebijakan vendor tidak perlu menangani pembuatan versi, tetap menggunakan jenis publik apa adanya.

Kebijakan publik produk dan publik system_ext

Mulai Android 11, partisi system_ext dan product diizinkan untuk mengekspor jenis publik yang ditetapkan ke partisi vendor. Seperti kebijakan publik platform, kebijakan vendor menggunakan jenis dan aturan yang otomatis diterjemahkan ke dalam atribut versi, misalnya, dari type menjadi type_ver, dengan ver adalah tingkat API vendor partisi vendor.

Jika partisi system_ext dan product didasarkan pada versi platform ver yang sama, sistem build akan membuat file pemetaan dasar ke system_ext/etc/selinux/mapping/ver.cil dan product/etc/selinux/mapping/ver.cil, yang berisi pemetaan identitas dari type ke type_ver. Kebijakan vendor dapat mengakses type dengan atribut berversi type_ver.

Jika hanya partisi system_ext dan product yang diupdate, misalnya ver ke ver+1 (atau yang lebih baru), sementara partisi vendor tetap di ver, kebijakan vendor mungkin kehilangan akses ke jenis partisi system_ext dan product. Untuk mencegah kerusakan, partisi system_ext dan product harus menyediakan file pemetaan dari jenis konkret ke atribut type_ver. Setiap partner bertanggung jawab untuk memelihara file pemetaan, jika mereka mendukung partisi ver vendor dengan partisi ver+1 (atau yang lebih baru) system_ext dan product.

Untuk menginstal file pemetaan ke partisi system_ext dan product, pelaksana atau vendor perangkat diharapkan untuk:

  1. Salin file pemetaan dasar yang dihasilkan dari partisi ver system_ext dan product ke pohon sumbernya.
  2. Ubah file pemetaan sesuai kebutuhan.
  3. Instal file pemetaan ke partisi ver+1 (atau yang lebih baru) system_ext dan product.

Misalnya, partisi 202504 system_ext memiliki satu jenis publik bernama foo_type. Kemudian system_ext/etc/selinux/mapping/202504.cil di partisi 202504 system_ext akan terlihat seperti ini:

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

Jika bar_type ditambahkan ke system_ext 202604, dan jika bar_type harus dipetakan ke foo_type untuk partisi vendor 202504, 202504.cil dapat diupdate dari (typeattributeset foo_type_202504 (foo_type)) ke (typeattributeset foo_type_202504 (foo_type bar_type)) lalu diinstal ke partisi system_ext 202604. Partisi 202504 vendor dapat terus mengakses foo_type dan bar_type 202604 system_ext.

Perubahan atribut untuk Android 9

Perangkat yang diupgrade ke Android 9 dapat menggunakan atribut berikut, tetapi perangkat yang diluncurkan dengan Android 9 tidak boleh.

Atribut pelanggar

Android 9 menyertakan atribut terkait domain berikut:

  • data_between_core_and_vendor_violators. Atribut untuk semua domain yang melanggar persyaratan untuk tidak membagikan file menurut jalur antara vendor dan coredomains. Proses platform dan vendor tidak boleh menggunakan file di disk untuk berkomunikasi (ABI tidak stabil). Rekomendasi:
    • Kode vendor harus menggunakan /data/vendor.
    • Sistem tidak boleh menggunakan /data/vendor.
  • Atribut system_executes_vendor_violators. untuk semua domain sistem (kecuali init dan shell domains) yang melanggar persyaratan untuk tidak mengeksekusi biner vendor. Eksekusi biner vendor memiliki API yang tidak stabil. Platform tidak boleh menjalankan biner vendor secara langsung. Rekomendasi:
    • Dependensi platform tersebut pada biner vendor harus berada di belakang HAL HIDL.

      ATAU

    • coredomains yang memerlukan akses ke biner vendor harus dipindahkan ke partisi vendor dan dengan demikian, berhenti menjadi coredomain.

Atribut tidak tepercaya

Aplikasi tidak tepercaya yang menghosting kode arbitrer tidak boleh memiliki akses ke layanan HwBinder, kecuali yang dianggap cukup aman untuk diakses dari aplikasi tersebut (lihat layanan aman di bawah). Dua alasan utama untuk hal ini adalah:

  1. Server HwBinder tidak melakukan autentikasi klien karena saat ini HIDL tidak mengekspos informasi UID pemanggil. Meskipun HIDL mengekspos data tersebut, banyak layanan HwBinder beroperasi pada tingkat di bawah aplikasi (seperti, HAL) atau tidak boleh mengandalkan identitas aplikasi untuk otorisasi. Oleh karena itu, agar aman, asumsi defaultnya adalah bahwa setiap layanan HwBinder memperlakukan semua kliennya sebagai sama-sama berwenang untuk melakukan operasi yang ditawarkan oleh layanan.
  2. Server HAL (subset layanan HwBinder) berisi kode dengan tingkat insiden masalah keamanan yang lebih tinggi daripada komponen system/core dan memiliki akses ke lapisan bawah stack (hingga ke hardware), sehingga meningkatkan peluang untuk melewati model keamanan Android.

Layanan yang aman

Layanan yang aman meliputi:

  • same_process_hwservice. Layanan ini (menurut definisi) berjalan dalam proses klien dan dengan demikian memiliki akses yang sama dengan domain klien tempat proses berjalan.
  • coredomain_hwservice. Layanan ini tidak menimbulkan risiko yang terkait dengan alasan #2.
  • hal_configstore_ISurfaceFlingerConfigs. Layanan ini dirancang khusus untuk digunakan oleh domain apa pun.
  • hal_graphics_allocator_hwservice. Operasi ini juga ditawarkan oleh layanan Binder surfaceflinger, yang aksesnya diizinkan untuk aplikasi.
  • hal_omx_hwservice. Ini adalah layanan Binder mediacodec versi HwBinder, yang diizinkan untuk diakses oleh aplikasi.
  • hal_codec2_hwservice. Ini adalah versi yang lebih baru dari hal_omx_hwservice.

Atribut yang dapat digunakan

Semua hwservices yang tidak dianggap aman memiliki atribut untrusted_app_visible_hwservice. Server HAL yang sesuai memiliki atribut untrusted_app_visible_halserver. Perangkat yang diluncurkan dengan Android 9 TIDAK BOLEH menggunakan atribut untrusted.

Rekomendasi:

  • Aplikasi yang tidak tepercaya harus berkomunikasi dengan layanan sistem yang berkomunikasi dengan HAL HIDL vendor. Misalnya, aplikasi dapat berkomunikasi dengan binderservicedomain, lalu mediaserver (yang merupakan binderservicedomain) pada gilirannya berkomunikasi dengan hal_graphics_allocator.

    ATAU

  • Aplikasi yang memerlukan akses langsung ke HAL vendor harus memiliki domain sepolicy yang ditentukan vendor sendiri.

Pengujian atribut file

Android 9 menyertakan pengujian waktu build yang memastikan semua file di lokasi tertentu memiliki atribut yang sesuai (misalnya, semua file di sysfs memiliki atribut sysfs_type yang diperlukan).

Pelabelan konteks SELinux

Untuk mendukung perbedaan antara sepolicy platform dan vendor, sistem membangun file konteks SELinux secara berbeda agar tetap terpisah.

Konteks file

Android 8.0 memperkenalkan perubahan berikut untuk file_contexts:

  • Untuk menghindari overhead kompilasi tambahan di perangkat selama booting, file_contexts tidak ada lagi dalam bentuk biner. Sebagai gantinya, file tersebut dapat dibaca, file teks ekspresi reguler seperti {property, service}_contexts (seperti pada versi sebelum 7.0).
  • file_contexts dibagi menjadi dua file:
    • plat_file_contexts
      • Platform Android file_context yang tidak memiliki label khusus perangkat, kecuali untuk memberi label pada bagian partisi /vendor yang harus diberi label secara tepat untuk memastikan file sepolicy berfungsi dengan baik.
      • Harus berada di partisi system di /system/etc/selinux/plat_file_contexts pada perangkat dan dimuat oleh init di awal bersama dengan file_context vendor.
    • vendor_file_contexts
      • file_context spesifik per perangkat yang dibuat dengan menggabungkan file_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
      • Harus diinstal di /vendor/etc/selinux/vendor_file_contexts dalam partisi vendor dan dimuat oleh init di awal bersama dengan file_context platform.

Konteks properti

Di Android 8.0, property_contexts dibagi menjadi dua file:

  • plat_property_contexts
    • Platform Android property_context yang tidak memiliki label khusus perangkat.
    • Harus berada di partisi system di /system/etc/selinux/plat_property_contexts dan dimuat oleh init di awal bersama dengan property_contexts vendor.
  • vendor_property_contexts
    • property_context khusus perangkat yang dibuat dengan menggabungkan property_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
    • Harus berada di partisi vendor di /vendor/etc/selinux/vendor_property_contexts dan dimuat oleh init di awal bersama dengan property_context platform

Konteks layanan

Di Android 8.0, service_contexts dibagi antara file berikut:

  • plat_service_contexts
    • service_context khusus platform Android untuk servicemanager. service_context tidak memiliki label khusus perangkat.
    • Harus berada di partisi system di /system/etc/selinux/plat_service_contexts dan dimuat oleh servicemanager di awal bersama dengan service_contexts vendor.
  • vendor_service_contexts
    • service_context spesifik per perangkat yang dibuat dengan menggabungkan service_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
    • Harus berada di partisi vendor di /vendor/etc/selinux/vendor_service_contexts dan dimuat oleh servicemanager di awal bersama dengan service_contexts platform.
    • Meskipun servicemanager mencari file ini saat waktu booting, untuk perangkat TREBLE yang sepenuhnya mematuhi, maka vendor_service_contexts TIDAK BOLEH ada. Hal ini karena semua interaksi antara vendor dan system harus melalui hwservicemanager/hwbinder.
  • plat_hwservice_contexts
    • Platform Android hwservice_context untuk hwservicemanager yang tidak memiliki label khusus perangkat.
    • Harus berada di partisi system di /system/etc/selinux/plat_hwservice_contexts dan dimuat oleh hwservicemanager di awal bersama dengan vendor_hwservice_contexts.
  • vendor_hwservice_contexts
    • hwservice_context spesifik per perangkat yang dibuat dengan menggabungkan hwservice_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
    • Harus berada di partisi vendor di /vendor/etc/selinux/vendor_hwservice_contexts dan dimuat oleh hwservicemanager di awal bersama dengan plat_service_contexts.
  • vndservice_contexts
    • service_context khusus perangkat untuk vndservicemanager yang dibuat dengan menggabungkan vndservice_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS di Boardconfig.mk perangkat.
    • File ini harus berada di partisi vendor di /vendor/etc/selinux/vndservice_contexts dan dimuat oleh vndservicemanager saat memulai.

Konteks Seapp

Di Android 8.0, seapp_contexts dibagi menjadi dua file:

  • plat_seapp_contexts
    • seapp_context platform Android yang tidak memiliki perubahan khusus perangkat.
    • Harus berada di partisi system pada /system/etc/selinux/plat_seapp_contexts.
  • vendor_seapp_contexts
    • Ekstensi khusus perangkat ke platform seapp_context yang dibuat dengan menggabungkan seapp_contexts yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
    • Harus berada di partisi vendor pada /vendor/etc/selinux/vendor_seapp_contexts.

Izin MAC

Di Android 8.0, mac_permissions.xml dibagi menjadi dua file:

  • Platform mac_permissions.xml
    • mac_permissions.xml platform Android yang tidak memiliki perubahan khusus perangkat.
    • Harus berada di partisi system pada /system/etc/selinux/.
  • Non-Platform mac_permissions.xml
    • Ekstensi khusus perangkat ke platform mac_permissions.xml yang dibuat dari mac_permissions.xml yang ditemukan di direktori yang ditunjukkan oleh BOARD_SEPOLICY_DIRS dalam file Boardconfig.mk perangkat.
    • Harus berada di partisi vendor pada /vendor/etc/selinux/.

Perubahan memori bersama untuk Android 17

Mulai Android 17, perangkat yang diluncurkan dengan properti berikut harus mengaktifkan kemampuan kebijakan memfd_class, dan memperbarui kebijakan terkait memori bersama untuk mendukung objek class memfd_file:

  • Level API vendor 202604 atau yang lebih tinggi untuk memberi vendor dan OEM kesempatan memperbarui kebijakan vendor mereka guna mendukung memfd. Hal ini juga memungkinkan perangkat yang ada diupgrade ke versi Android yang lebih tinggi tanpa memerlukan update pada partisi vendornya.
  • android16-6.12 atau kernel yang lebih tinggi, karena kernel tersebut mendukung fitur memfd_class, yang diperlukan untuk menerapkan kebijakan terperinci untuk memfd.

Mengaktifkan kemampuan kebijakan memfd_class

Hingga saat ini, SELinux memberi label memfd sebagai file dengan jenis yang sama seperti sistem file pendukungnya, yaitu tmpfs. Hal ini membuat memfd tidak dapat dibedakan dari file lain pada pemasangan tmpfs dari perspektif kebijakan. Sekarang, SELinux memberi label memfd dengan konteks keamanan proses alokasi dan memfds diperlakukan sebagai objek class memfd_file. Fungsi ini dilindungi oleh kemampuan kebijakan memfd_class untuk mempertahankan kompatibilitas mundur dengan lingkungan ruang pengguna yang lebih lama.

Untuk mengaktifkan kemampuan kebijakan memfd_class, buat file policy_capabilities di bagian BOARD_VENDOR_SEPOLICY_DIRS. File harus berisi entri berikut:

# $BOARD_VENDOR_SEPOLICY_DIRS/*/policy_capabilities
policycap memfd_class;

Kemudian, bangun kembali image Anda dan flash ke perangkat Anda untuk memverifikasi bahwa kemampuan tersebut diaktifkan.

Pastikan kemampuan kebijakan memfd_class diaktifkan

Gunakan perintah berikut untuk memeriksa status kemampuan kebijakan memfd_class:

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

Jika hasilnya adalah 1, maka kemampuan kebijakan memfd_class diaktifkan. Jika tidak, fitur ini tidak diaktifkan.

Mentransisikan kebijakan yang ada ke memfd

Proses tertentu menggunakan makro tmpfs_domain() dalam kebijakan mereka untuk mengakses dan memberi namespace pada memfds mereka, misalnya:

# foo.te
tmpfs_domain(foo)

Hal ini berarti:

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

dan memungkinkan proses bar mengakses memfds proses foo sebagai berikut:

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

Dengan kemampuan kebijakan memfd_class yang diaktifkan, makro tmpfs_domain() tidak lagi diperlukan, karena kebijakan platform telah diperbarui untuk memungkinkan proses apa pun membuat dan menggunakan memfds-nya sendiri, seperti yang terlihat di sini:

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

dan memfds yang dibuat oleh proses foo dapat diakses oleh proses bar sebagai berikut:

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

Kebijakan platform telah diperbarui untuk memperhitungkan penggunaan memfd yang ada. Namun, kebijakan khusus perangkat dan vendor yang menggunakan label tmpfs harus diperbarui untuk menggunakan memfd_file. Jika kebijakan dibagikan di antara SoC atau perangkat yang tidak memiliki level API vendor 202604 atau yang lebih tinggi, sebaiknya kebijakan tmpfs lama dipertahankan bersama dengan kebijakan memfd_file baru untuk kompatibilitas.

Mengidentifikasi penolakan AVC terkait memfd

Penolakan terkait Memfd dapat diambil menggunakan perintah berikut:

adb shell logcat -d -b events | grep memfd

penolakan avc dengan tmpfs sebagai target

Contoh berikut menunjukkan penolakan avc yang dialami oleh proses yang mencoba menulis ke memfd yang tidak memiliki izin untuk menulis:

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

Jika kemampuan kebijakan memfd_class diaktifkan, konteks target memfd adalah konteks keamanan proses alokasi, bukan tmpfs, dan class targetnya adalah memfd_file, bukan file. Oleh karena itu, jika Anda melihat penolakan avc yang terkait dengan memfd, dan memfd yang dimaksud diberi label sebagai file tmpfs, kemampuan kebijakan memfd_class tidak diaktifkan.

penolakan avc dengan memfd_file sebagai class target

Contoh berikut menunjukkan penolakan avc yang dialami oleh proses yang mencoba menulis ke memfd yang tidak memiliki izin untuk menulis, dan kemampuan kebijakan memfd_class diaktifkan, serta baris tambahan yang dipancarkan logd setelah penolakan dengan stempel waktu yang sama:

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)

Stempel waktu yang cocok menunjukkan bahwa Decoded path for … log terkait dengan penolakan avc dengan stempel waktu 0.0.86. Log ini mendekode string heksadesimal dari nilai jalur dalam penolakan avc, dan memberikan nama region memori memfd, yang dapat berguna untuk memahami buffer mana yang sedang dibagikan. Konteks sumber dan konteks target berguna untuk memahami proses apa yang perlu berbagi memori. Dari contoh sebelumnya, jelas bahwa proses mediaserver harus dapat mengakses memfds mediaextractor. Oleh karena itu, kebijakan yang sesuai adalah:

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

Update domain keamanan di Android 17

ASharedMemory_create() API di Android 17 menerapkan logika bersyarat untuk memilih antara driver ashmem lama dan framework memfd untuk alokasi memori bersama.

Untuk perangkat yang memenuhi persyaratan memfd (level API vendor 202604 atau yang lebih tinggi dan kernel android16-6.12 atau yang lebih baru), API akan mengevaluasi targetSdkVersion aplikasi yang memanggil. Jika versi SDK target adalah 37 atau yang lebih tinggi, memfd akan dialokasikan. Hal ini memungkinkan developer memperbaiki masalah yang mereka temui saat mengupgrade versi SDK target.

Jika perangkat tidak memenuhi prasyarat memfd's, ASharedMemory akan melakukan fallback ke ashmem. Hal ini mempertahankan kompatibilitas untuk perangkat yang diupgrade dengan partisi atau kernel vendor yang lebih lama.

Untuk menerapkan transisi ini, kebijakan SELinux platform memblokir aplikasi yang menargetkan SDK versi 37 atau yang lebih tinggi di domain keamanan platform_app, priv_app, dan untrusted_app agar tidak membuka /dev/ashmem dan memanggil perintah ashmem ioctl di memfd. Hal ini dicapai dengan membagi domain aplikasi tersebut berdasarkan versi SDK target. Hal ini memperkenalkan domain keamanan platform_app_36, priv_app_36, dan untrusted_app_34, yang bersama dengan domain aplikasi lainnya mempertahankan izin terbuka ashmem dan kemampuan untuk memanggil perintah ioctl ashmem di memfds.

Pada rilis Android mendatang, kumpulan aplikasi yang mempertahankan izin untuk membuka perangkat ashmem dan memanggil perintah ashmem ioctl di memfds akan dikurangi menjadi hanya platform_app_36, priv_app_36, dan untrusted_app_34 serta domain aplikasi yang tidak tepercaya untuk versi SDK yang lebih lama.

Kebijakan SELinux vendor atau OEM kustom untuk aplikasi yang menyematkan versi SDK targetnya harus diupdate agar sesuai dengan perubahan domain ini, seperti yang dijelaskan di bagian berikut.

Update domain SELinux platform_app

Domain platform_app dibagi berdasarkan targetSdkVersion aplikasi. Aplikasi platform yang menargetkan SDK versi 37 atau yang lebih tinggi diberi domain platform_app, sedangkan aplikasi yang menargetkan SDK versi 36 atau yang lebih rendah menggunakan platform_app_36. Domain platform_app_36 tetap dapat membuka /dev/ashmem untuk kompatibilitas mundur. Untuk menyederhanakan pengelolaan kebijakan di kedua domain, gunakan atribut platform_app_all.

Pertimbangkan kasus saat aplikasi platform sample-plat-app perlu membaca dan menulis dari dan ke /dev/foo_device. Kebijakan SELinux vendor yang ada mungkin terlihat seperti ini:

# 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;

Namun, jika sample-plat-app disematkan pada SDK target versi 36, sample-plat-app akan ditempatkan di domain platform_app_36, dan kebijakan SELinux dari sebelumnya tidak akan berlaku, serta penolakan AVC berikut akan diamati:

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

Untuk memperbaikinya, kebijakan dapat diupdate seperti ini karena aplikasi harus selalu memiliki akses ke node perangkat:

# 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;

Mungkin ada situasi saat platform_app_all tidak berfungsi. Misalnya, jika makro hal_client_domain() digunakan dengan platform_app_all, kebijakan akan gagal dikompilasi. Hal ini karena platform_app_all adalah atribut, dan hal_client_domain() akan mencoba melampirkan atribut lain ke atribut tersebut, yang tidak mungkin dilakukan:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

Dalam skenario tersebut, Anda harus menggunakan jenis platform_app_36 secara langsung, sehingga kebijakan Anda memiliki konten berikut:

# platform_app.te
hal_client_domain(platform_app, hal_foo)

# platform_app_36.te
hal_client_domain(platform_app_36, hal_foo)

Update domain SELinux priv_app

Domain priv_app dibagi berdasarkan targetSdkVersion aplikasi. Aplikasi istimewa yang menargetkan SDK versi 37 atau yang lebih tinggi diberi domain priv_app, sedangkan aplikasi yang menargetkan SDK versi 36 atau yang lebih rendah menggunakan priv_app_36. Domain priv_app_36 tetap dapat membuka /dev/ashmem untuk kompatibilitas mundur. Untuk menyederhanakan pengelolaan kebijakan di kedua domain, gunakan atribut priv_app_all.

Pertimbangkan kasus saat aplikasi platform sample-priv-app perlu membaca dan menulis dari dan ke /dev/foo_device. Kebijakan SELinux vendor yang ada mungkin terlihat seperti ini:

# 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;

Namun, jika sample-priv-app disematkan pada SDK target versi 36, sample-priv-app akan ditempatkan di domain priv_app_36, dan kebijakan SELinux dari sebelumnya tidak akan berlaku, serta penolakan AVC berikut akan diamati:

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

Untuk memperbaikinya, kebijakan dapat diupdate seperti ini karena aplikasi harus selalu memiliki akses ke node perangkat:

# 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;

Mungkin ada situasi saat priv_app_all tidak berfungsi. Misalnya, jika makro hal_client_domain() digunakan dengan priv_app_all, kebijakan tidak akan dikompilasi. Hal ini karena priv_app_all adalah atribut, dan hal_client_domain() akan mencoba melampirkan atribut lain ke atribut tersebut, yang tidak mungkin dilakukan:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

Dalam skenario tersebut, Anda harus menggunakan jenis priv_app_36 secara langsung, sehingga file kebijakan Anda akan terlihat seperti ini:

# priv_app.te
hal_client_domain(priv_app, hal_foo)

# priv_app_36.te
hal_client_domain(priv_app_36, hal_foo)

Pembaruan domain SELinux untrusted_app

Domain untrusted_app dibagi berdasarkan targetSdkVersion aplikasi. Aplikasi yang tidak tepercaya yang menargetkan versi SDK 37 atau yang lebih tinggi diberi domain untrusted_app, sedangkan aplikasi yang menargetkan versi SDK 34-36 inklusif diberi domain untrusted_app_34 baru. Domain untrusted_app_34, serta domain untrusted_app_X, dengan `X` adalah versi SDK target yang lebih lama, tetap dapat membuka `/dev/ashmem` untuk kompatibilitas mundur.