Artikel ini menjelaskan cara Android menangani masalah kompatibilitas kebijakan dengan OTA platform, dengan setelan SELinux platform baru mungkin berbeda dari setelan SELinux vendor lama.
Desain kebijakan SELinux berbasis Treble mempertimbangkan perbedaan biner
antara kebijakan platform dan vendor; skema menjadi
lebih rumit jika partisi vendor menghasilkan dependensi, seperti
platform
< vendor
< oem
.
Di Android 8.0 dan yang lebih baru, kebijakan global SELinux dibagi menjadi komponen pribadi dan publik. Komponen publik terdiri dari kebijakan dan infrastruktur terkait, yang dijamin tersedia untuk versi platform. Kebijakan ini akan diekspos ke penulis kebijakan vendor untuk memungkinkan vendor mem-build file kebijakan vendor, yang jika digabungkan dengan kebijakan yang disediakan platform, akan menghasilkan kebijakan yang berfungsi penuh untuk perangkat.
- Untuk pembuatan versi, kebijakan publik platform yang diekspor akan ditulis sebagai atribut.
- Untuk memudahkan penulisan kebijakan, jenis yang diekspor akan diubah menjadi atribut berversi sebagai bagian dari proses build kebijakan. Jenis publik juga dapat digunakan langsung dalam keputusan pelabelan yang disediakan oleh file konteks vendor.
Android mempertahankan pemetaan antara jenis konkret yang diekspor dalam kebijakan platform dan atribut berversi yang sesuai untuk setiap versi platform. Hal ini memastikan bahwa saat objek diberi label dengan jenis, objek tersebut tidak melanggar perilaku yang dijamin oleh kebijakan publik platform dalam versi sebelumnya. Pemetaan ini dipertahankan dengan terus memperbarui file pemetaan untuk setiap versi platform, yang menyimpan informasi keanggotaan atribut untuk setiap jenis yang diekspor dalam kebijakan publik.
Kepemilikan dan pelabelan objek
Saat menyesuaikan kebijakan di Android 8.0 dan yang lebih tinggi, kepemilikan harus ditentukan dengan jelas
untuk setiap objek agar kebijakan platform dan vendor tetap terpisah. Misalnya, jika
vendor memberi label /dev/foo
dan platform kemudian memberi label
/dev/foo
dalam OTA berikutnya, akan ada perilaku yang tidak ditentukan. Untuk
SELinux, hal ini ditunjukkan sebagai tabrakan pemberian label. Node perangkat hanya dapat memiliki
satu label yang me-resolve ke label mana pun yang diterapkan terakhir. Akibatnya:
- Proses yang memerlukan akses ke label yang tidak berhasil diterapkan akan kehilangan akses ke resource.
- Proses yang mendapatkan akses ke file dapat rusak karena node perangkat yang salah dibuat.
Properti sistem juga berpotensi menyebabkan konflik penamaan yang dapat mengakibatkan perilaku yang tidak ditentukan pada sistem (serta untuk pemberian label SELinux). Tabrakan 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.
Selain konflik label, nama jenis/atribut SELinux juga dapat mengalami konflik. Konflik nama jenis/atribut akan selalu menyebabkan error compiler kebijakan.
Pemisahan nama jenis/atribut
SELinux tidak mengizinkan beberapa deklarasi dari jenis/atribut yang sama. Kebijakan
dengan deklarasi duplikat akan gagal dikompilasi. Untuk menghindari konflik nama jenis dan
atribut, semua deklarasi vendor harus diberi namespace
yang dimulai dengan vendor_
.
type foo, domain; → type vendor_foo, domain;
Kepemilikan pemberian label properti dan proses sistem
Menghindari konflik pemberian label sebaiknya diselesaikan menggunakan namespace properti. Untuk mengidentifikasi properti platform dengan mudah dan menghindari konflik nama saat mengganti nama atau menambahkan properti platform yang diekspor, pastikan semua properti vendor memiliki awalannya sendiri:
Jenis properti | Awalan yang dapat diterima |
---|---|
properti kontrol | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor.
|
read-writable | vendor. |
hanya baca | ro.vendor. ro.boot. ro.hardware.
|
persisten | persist.vendor. |
Vendor dapat terus menggunakan ro.boot.*
(yang berasal dari cmdline kernel) dan ro.hardware.*
(properti terkait hardware yang jelas).
Semua layanan vendor dalam file init rc harus memiliki vendor.
untuk layanan dalam file init rc dari partisi non-sistem. Aturan serupa
diterapkan ke label SELinux untuk properti vendor (vendor_
untuk properti vendor).
Kepemilikan file
Mencegah konflik untuk file merupakan tantangan karena kebijakan platform dan vendor biasanya memberikan label untuk semua sistem file. Tidak seperti penamaan jenis, namespace file tidak praktis karena banyak di antaranya dibuat oleh kernel. Untuk mencegah konflik ini, ikuti panduan penamaan untuk sistem file di bagian ini. Untuk Android 8.0, ini adalah rekomendasi tanpa penerapan teknis. Ke depannya, 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 sudah memberi label pada bagian partisi vendor
yang berinteraksi dengan platform, yang memungkinkan penulisan aturan SELinux untuk proses
platform agar dapat berkomunikasi dan/atau mengakses bagian partisi
vendor
. Contoh:
Jalur /vendor |
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.
|
Akibatnya, aturan tertentu harus diikuti (diterapkan melalui
neverallows
) saat memberi label pada file tambahan di partisi
vendor
:
vendor_file
harus berupa label default untuk semua file dalam partisivendor
. Kebijakan platform mewajibkan hal ini untuk mengakses penerapan HAL passthrough.- Semua
exec_types
baru yang ditambahkan di partisivendor
melalui SEPolicy vendor harus memiliki atributvendor_file_type
. Hal ini diterapkan melalui neverallows. - Untuk menghindari konflik dengan update platform/framework mendatang, hindari pemberian label
pada file selain
exec_types
di partisivendor
. - 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 dengan label default (proc
), kebijakan vendor
tidak boleh memberi label secara eksplisit dan harus menggunakan jenis
proc
generik untuk menambahkan aturan untuk domain vendor. Hal ini memungkinkan update
platform untuk 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 dipasang 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 pada 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 khusus 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 ada di sini.
Rekomendasi: Vendor hanya boleh 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 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
/data
.
Versi label genfs
Mulai API level vendor 202504, label SELinux
yang lebih baru yang ditetapkan dengan genfscon
di
system/sepolicy/compat/plat_sepolicy_genfs_{ver}.cil
bersifat opsional untuk partisi
vendor lama. Hal ini memungkinkan partisi vendor 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 API level vendor 202404, node
/sys/class/udc
diberi labelsysfs
secara default. -
Mulai dari API level vendor 202504,
/sys/class/udc
diberi labelsysfs_udc
.
Namun, /sys/class/udc
mungkin digunakan oleh partisi vendor yang menggunakan API level 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 memeriksa BOARD_GENFS_LABELS_VERSION
, platform akan terus menggunakan
label dan izin sebelumnya untuk partisi vendor lama.
BOARD_GENFS_LABELS_VERSION
dapat lebih besar dari atau sama dengan API level vendor. Misalnya, partisi vendor yang menggunakan API level 202404 dapat menetapkan BOARD_GENFS_LABELS_VERSION
ke 202504 untuk mengadopsi label baru yang diperkenalkan pada 202504. Lihat daftar
label genfs khusus 202504.
Saat memberi label pada node genfscon
, platform harus mempertimbangkan partisi vendor lama dan
menerapkan mekanisme penggantian untuk kompatibilitas jika diperlukan. Platform ini dapat menggunakan library khusus
platform untuk membuat kueri versi label genfs.
-
Pada native, gunakan
libgenfslabelsversion
. Lihatgenfslabelsversion.h
untuk file headerlibgenfslabelsversion
. -
Di Java, gunakan
android.os.SELinux.getGenfsLabelsVersion()
.
Atribut kompatibilitas
Kebijakan SELinux adalah interaksi antara jenis sumber dan target untuk izin dan class objek tertentu. Setiap objek (proses, file, dll.) yang terpengaruh oleh kebijakan SELinux mungkin hanya memiliki satu jenis, tetapi jenis tersebut mungkin memiliki beberapa atribut.
Kebijakan sebagian besar ditulis dalam hal jenis yang ada:
allow source_type target_type:target_class permission(s);
Hal ini berhasil karena kebijakan ditulis dengan pengetahuan tentang semua jenis. Namun, jika kebijakan vendor dan kebijakan platform menggunakan jenis tertentu, dan label objek tertentu hanya berubah di salah satu kebijakan tersebut, kebijakan lainnya mungkin berisi kebijakan yang memperoleh atau kehilangan akses yang sebelumnya diandalkan. Contoh:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Dapat diubah menjadi:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Meskipun kebijakan vendor akan tetap sama, v_domain
akan kehilangan akses karena tidak adanya kebijakan untuk jenis sysfs_A
baru.
Dengan menentukan kebijakan dalam hal atribut, kita dapat memberikan jenis objek yang mendasarinya yang memiliki atribut yang sesuai dengan kebijakan untuk kode platform dan vendor. Hal ini dapat dilakukan untuk semua jenis guna membuat kebijakan atribut secara efektif, dengan jenis konkret yang tidak pernah digunakan. Dalam praktiknya, hal ini hanya diperlukan untuk bagian kebijakan yang tumpang-tindih antara platform dan vendor, yang ditentukan dan diberikan sebagai kebijakan publik platform yang dibuat sebagai bagian dari kebijakan vendor.
Menentukan kebijakan publik sebagai atribut berversi memenuhi dua tujuan kompatibilitas kebijakan:
- Memastikan kode vendor tetap berfungsi setelah update platform. Dicapai dengan menambahkan atribut ke jenis konkret untuk objek yang sesuai dengan objek yang menjadi dasar kode vendor, sehingga mempertahankan akses.
- Kemampuan untuk menghentikan penggunaan kebijakan. Dicapai dengan menentukan kumpulan kebijakan secara jelas menjadi atribut yang dapat dihapus segera setelah versi yang sesuai tidak lagi didukung. Pengembangan dapat dilanjutkan di platform, dengan mengetahui bahwa kebijakan lama masih ada di kebijakan vendor dan akan otomatis dihapus saat/jika diupgrade.
Kemampuan tulis kebijakan
Untuk memenuhi sasaran tidak memerlukan pengetahuan tentang perubahan versi tertentu untuk
pengembangan kebijakan, Android 8.0 menyertakan pemetaan antara jenis kebijakan publik
platform dan atributnya. Jenis foo
dipetakan
ke atribut foo_vN
, dengan N
adalah
versi yang ditargetkan. vN
sesuai dengan
variabel build PLATFORM_SEPOLICY_VERSION
dan berbentuk
MM.NN
, dengan MM
sesuai dengan nomor SDK platform
dan NN
adalah versi khusus sepolicy platform.
Atribut dalam kebijakan publik tidak memiliki versi, tetapi ada sebagai API tempat kebijakan platform dan vendor dapat dibuat untuk menjaga antarmuka antara kedua partisi tetap stabil. Penulis kebijakan platform dan vendor dapat terus menulis kebijakan seperti yang ditulis saat ini.
Kebijakan publik platform yang diekspor sebagai allow source_foo target_bar:class
perm;
disertakan sebagai bagian dari kebijakan vendor. Selama
kompilasi (yang menyertakan
versi yang sesuai), kode ini diubah menjadi kebijakan yang akan masuk ke
bagian vendor perangkat (ditampilkan dalam Common Intermediate
Language (CIL) yang diubah):
(allow source_foo_vN target_bar_vN (class (perm)))
Karena kebijakan vendor tidak pernah lebih maju dari platform, kebijakan tersebut tidak boleh terkait dengan versi sebelumnya. Namun, kebijakan platform perlu mengetahui sejauh mana kebijakan vendor, menyertakan atribut ke jenisnya, dan menetapkan kebijakan yang sesuai dengan atribut berversi.
Perbedaan kebijakan
Membuat atribut secara otomatis dengan menambahkan _vN
ke akhir
setiap jenis tidak akan melakukan apa pun tanpa pemetaan atribut ke jenis di seluruh perbedaan
versi. Android mempertahankan pemetaan antara versi untuk atribut dan
pemetaan jenis ke atribut tersebut. Hal ini dilakukan dalam file pemetaan
yang disebutkan di atas dengan pernyataan, seperti (CIL):
(typeattributeset foo_vN (foo))
Upgrade platform
Bagian berikut menjelaskan skenario untuk upgrade platform.
Jenis yang sama
Skenario ini terjadi saat objek tidak mengubah label dalam versi kebijakan.
Hal ini sama untuk jenis sumber dan target dan dapat dilihat dengan
/dev/binder
, yang diberi label binder_device
di semua
rilis. Ini direpresentasikan dalam kebijakan yang ditransformasi sebagai:
binder_device_v1 … binder_device_vN
Saat mengupgrade dari v1
→ v2
, kebijakan platform harus
berisi:
type binder_device; -> (type binder_device) (in CIL)
Dalam file pemetaan v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
Dalam file pemetaan v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
Dalam kebijakan vendor v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
Dalam kebijakan vendor v2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Jenis baru
Skenario ini terjadi saat platform telah menambahkan jenis baru, yang dapat terjadi saat menambahkan fitur baru atau selama hardening kebijakan.
- Fitur baru. Saat jenis melabeli objek yang sebelumnya tidak ada (seperti proses layanan baru), kode vendor sebelumnya tidak berinteraksi langsung dengannya sehingga tidak ada kebijakan yang sesuai. Atribut baru yang sesuai dengan jenis tidak memiliki atribut dalam versi sebelumnya, sehingga tidak memerlukan entri dalam file pemetaan yang menargetkan versi tersebut.
- Hardening kebijakan. Jika jenis mewakili hardening kebijakan, atribut jenis baru harus ditautkan kembali ke rantai atribut yang sesuai dengan atribut sebelumnya (mirip dengan contoh sebelumnya yang mengubah
/sys/A
darisysfs
menjadisysfs_A
). Kode vendor bergantung pada aturan yang memungkinkan akses kesysfs
, dan perlu menyertakan aturan tersebut sebagai atribut jenis baru.
Saat mengupgrade dari v1
→ v2
, kebijakan platform harus
berisi:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
Dalam file pemetaan v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
Dalam file pemetaan v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
Dalam kebijakan vendor v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Dalam kebijakan vendor v2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Jenis yang dihapus
Skenario (jarang) ini terjadi saat jenis dihapus, yang dapat terjadi saat objek pokok:
- Tetap ada, tetapi mendapatkan label yang berbeda.
- Dihapus oleh platform.
Selama pelonggaran kebijakan, jenis akan dihapus dan objek yang diberi label dengan jenis tersebut akan diberi label lain yang sudah ada. Hal ini mewakili penggabungan pemetaan atribut: Kode vendor harus tetap dapat mengakses objek yang mendasarinya dengan atribut yang biasa dimilikinya, tetapi sistem lainnya kini harus dapat mengaksesnya dengan atribut barunya.
Jika atribut yang telah dialihkan adalah baru, pemberian label ulang akan sama seperti dalam kasus jenis baru, kecuali jika label yang ada digunakan, penambahan jenis baru atribut lama akan menyebabkan objek lain yang juga diberi label dengan jenis ini baru dapat diakses. Pada dasarnya, inilah yang dilakukan oleh platform dan dianggap sebagai kompromi yang dapat diterima untuk mempertahankan kompatibilitas.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Contoh Versi 1: Jenis penyingkatan (menghapus sysfs_A)
Saat mengupgrade dari v1
→ v2
, kebijakan platform harus
berisi:
type sysfs; (type sysfs) (in CIL)
Dalam file pemetaan v1 (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
Dalam file pemetaan v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
Dalam kebijakan vendor v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
Dalam kebijakan vendor v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Contoh Versi 2: Menghapus sepenuhnya (jenis foo)
Saat mengupgrade dari v1
→ v2
, kebijakan platform harus
berisi:
# nothing - we got rid of the type
Dalam file pemetaan v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
Dalam file pemetaan v2 (CIL):
# nothing - get rid of it
Dalam kebijakan vendor v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
Dalam kebijakan vendor v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Class/izin baru
Skenario ini terjadi saat upgrade platform memperkenalkan komponen kebijakan baru
yang tidak ada di versi sebelumnya. Misalnya, saat Android menambahkan
pengelola objek servicemanager
yang membuat izin tambahkan, temukan, dan daftar, daemon vendor yang ingin mendaftar dengan
izin servicemanager
yang diperlukan tidak
tersedia. Di Android 8.0, hanya kebijakan platform yang dapat menambahkan class dan
izin baru.
Untuk mengizinkan semua domain yang dapat dibuat atau diperluas oleh kebijakan vendor untuk menggunakan class baru tanpa hambatan, kebijakan platform harus menyertakan aturan yang mirip dengan:
allow {domain -coredomain} *:new_class perm;
Hal ini bahkan mungkin memerlukan kebijakan yang mengizinkan akses untuk semua jenis antarmuka (kebijakan publik), untuk memastikan image vendor mendapatkan akses. Jika hal ini menghasilkan kebijakan keamanan yang tidak dapat diterima (seperti yang mungkin terjadi dengan perubahan servicemanager), upgrade vendor berpotensi dipaksakan.
Menghapus class/izin
Skenario ini terjadi saat pengelola objek dihapus (seperti
pengelola objek ZygoteConnection
) dan tidak akan menyebabkan masalah. Class
dan izin pengelola objek dapat tetap ditentukan dalam kebijakan hingga
versi vendor tidak lagi menggunakannya. Hal ini dilakukan dengan menambahkan definisi
ke file pemetaan yang sesuai.
Penyesuaian vendor untuk jenis baru/yang diberi label baru
Jenis vendor baru adalah inti dari pengembangan kebijakan vendor karena diperlukan untuk mendeskripsikan proses, biner, perangkat, subsistem, dan data yang disimpan baru. Oleh karena itu, Anda harus mengizinkan pembuatan jenis yang ditentukan vendor.
Karena kebijakan vendor selalu yang paling lama di perangkat, Anda tidak perlu
mengonversi semua jenis vendor menjadi atribut dalam kebijakan secara otomatis. Platform
tidak mengandalkan apa pun yang diberi label dalam kebijakan vendor karena platform tidak
mengetahuinya; namun, platform akan menyediakan atribut dan jenis publik
yang digunakan untuk berinteraksi dengan objek yang diberi label dengan jenis ini (seperti
domain
, sysfs_type
, dll.). Agar platform dapat
terus berinteraksi dengan benar dengan objek ini, atribut dan jenis
harus diterapkan dengan tepat dan aturan tertentu mungkin perlu ditambahkan ke
domain yang dapat disesuaikan (seperti init
).
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 berdasarkan jalur antaravendor
dancoredomains
. 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
.
- Kode vendor harus menggunakan
system_executes_vendor_violators
. Atribut untuk semua domain sistem (kecualiinit
danshell domains
) yang melanggar persyaratan untuk tidak mengeksekusi biner vendor. Eksekusi biner vendor memiliki API yang tidak stabil. Platform tidak boleh mengeksekusi 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 sehingga berhenti menjadicoredomain
.
- Dependensi platform tersebut pada biner vendor harus berada di belakang HAL HIDL.
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). Ada dua alasan utama untuk hal ini:
- Server HwBinder tidak melakukan autentikasi klien karena HIDL saat ini 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. Jadi, agar aman, asumsi defaultnya adalah setiap layanan HwBinder memperlakukan semua kliennya sebagai sama-sama diberi otorisasi untuk melakukan operasi yang ditawarkan oleh layanan.
- Server HAL (subkumpulan layanan HwBinder) berisi kode dengan tingkat insiden masalah keamanan yang lebih tinggi daripada komponen
system/core
dan memiliki akses ke lapisan stack yang lebih rendah (hingga ke hardware), sehingga meningkatkan peluang untuk mengabaikan model keamanan Android.
Layanan aman
Layanan aman meliputi:
same_process_hwservice
. Layanan ini (menurut definisi) berjalan dalam proses klien sehingga 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 mana pun.hal_graphics_allocator_hwservice
. Operasi ini juga ditawarkan oleh layanan Bindersurfaceflinger
, yang diizinkan untuk diakses oleh aplikasi.hal_omx_hwservice
. Ini adalah versi HwBinder dari layanan Bindermediacodec
, yang diizinkan untuk diakses oleh aplikasi.hal_codec2_hwservice
. Ini adalah versi yang lebih baru darihal_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
, lalumediaserver
(yang merupakanbinderservicedomain
) pada gilirannya berkomunikasi denganhal_graphics_allocator
.ATAU
- Aplikasi yang memerlukan akses langsung ke HAL
vendor
harus memiliki domain sepolicy yang ditentukan vendornya sendiri.
Pengujian atribut file
Android 9 menyertakan pengujian waktu build yang memastikan semua file di lokasi
tertentu memiliki atribut yang sesuai (seperti, semua file di
sysfs
memiliki atribut sysfs_type
yang diperlukan).
Kebijakan publik platform
Kebijakan publik platform adalah inti dari kepatuhan terhadap model arsitektur
Android 8.0 tanpa hanya mempertahankan penggabungan kebijakan platform
dari v1 dan v2. Vendor terekspos ke subset kebijakan platform yang
berisi jenis dan atribut yang dapat digunakan serta aturan pada jenis dan atribut tersebut
yang kemudian menjadi bagian dari kebijakan vendor (yaitu,
vendor_sepolicy.cil
).
Jenis dan aturan secara otomatis diterjemahkan dalam kebijakan yang dibuat vendor
menjadi attribute_vN
sehingga semua jenis yang disediakan platform
adalah atribut yang memiliki versi (tetapi atribut tidak memiliki versi). Platform ini
bertanggung jawab untuk memetakan jenis konkret yang disediakan ke dalam atribut
yang sesuai untuk memastikan bahwa kebijakan vendor terus berfungsi dan aturan
yang disediakan untuk versi tertentu disertakan. Kombinasi
kebijakan publik platform dan kebijakan vendor memenuhi sasaran model
arsitektur Android 8.0 untuk mengizinkan build platform dan vendor independen.
Pemetaan ke rantai atribut
Saat menggunakan atribut untuk dipetakan ke versi kebijakan, jenis akan dipetakan ke satu atau beberapa atribut, sehingga memastikan objek yang diberi label dengan jenis tersebut dapat diakses melalui atribut yang sesuai dengan jenis sebelumnya.
Mempertahankan sasaran untuk menyembunyikan informasi versi dari penulis kebijakan berarti
otomatis membuat atribut berversi dan menetapkannya ke
jenis yang sesuai. Dalam kasus umum jenis statis, ini mudah:
type_foo
dipetakan ke type_foo_v1
.
Untuk perubahan label objek seperti sysfs
→ sysfs_A
atau
mediaserver
→ audioserver
, pembuatan pemetaan ini
tidak mudah (dan dijelaskan dalam contoh di atas). Pemelihara kebijakan platform
harus menentukan cara membuat pemetaan di titik transisi untuk objek, yang
memerlukan pemahaman tentang hubungan antara objek dan label
yang ditetapkan dan menentukan kapan hal ini terjadi. Untuk kompatibilitas mundur, kompleksitas
ini perlu dikelola di sisi platform, yang merupakan satu-satunya partisi
yang dapat diupdate.
Update versi
Untuk mempermudah, platform Android merilis versi sepolicy saat cabang
rilis baru dipotong. Seperti yang dijelaskan di atas, nomor versi terdapat dalam
PLATFORM_SEPOLICY_VERSION
dan berbentuk MM.nn
,
dengan MM
sesuai dengan nilai SDK dan nn
adalah
nilai pribadi yang dikelola di /platform/system/sepolicy.
Misalnya, 19.0
untuk Kitkat, 21.0
untuk Lollipop,
22.0
untuk Lollipop-MR1 23.0
untuk Marshmallow,
24.0
untuk Nougat, 25.0
untuk Nougat-MR1,
26.0
untuk Oreo, 27.0
untuk Oreo-MR1, dan
28.0
untuk Android 9.
Uprev tidak selalu berupa bilangan bulat. Misalnya,
jika peningkatan MR ke versi memerlukan perubahan yang tidak kompatibel di
system/sepolicy/public
, tetapi bukan peningkatan API, versi sepolicy
tersebut dapat berupa: vN.1
. Versi yang ada di cabang
pengembangan adalah 10000.0
yang tidak akan pernah digunakan di perangkat pengiriman.
Android dapat menghentikan penggunaan versi terlama saat mengupgrade. Untuk input tentang kapan harus menghentikan penggunaan versi, Android dapat mengumpulkan jumlah perangkat dengan kebijakan vendor yang menjalankan versi Android tersebut dan masih menerima update platform utama. Jika jumlahnya kurang dari nilai minimum tertentu, versi tersebut tidak digunakan lagi.
Dampak performa dari beberapa atribut
Seperti yang dijelaskan di https://github.com/SELinuxProject/cil/issues/9, sejumlah besar atribut yang ditetapkan ke jenis akan menyebabkan masalah performa jika cache kebijakan tidak ditemukan.
Hal ini dikonfirmasi sebagai masalah di Android, sehingga perubahan dilakukan pada Android 8.0 untuk menghapus atribut yang ditambahkan ke kebijakan oleh compiler kebijakan, serta untuk menghapus atribut yang tidak digunakan. Perubahan ini menyelesaikan regresi performa.
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, vendor menggunakan jenis dan aturan yang otomatis diterjemahkan ke dalam
atribut berversi, misalnya, dari type
menjadi
type_N
, dengan N
adalah versi
platform tempat partisi vendor dibuat.
Jika partisi system_ext
dan product
didasarkan pada versi platform yang sama
N
, sistem build akan menghasilkan file pemetaan dasar ke
system_ext/etc/selinux/mapping/N.cil
dan
product/etc/selinux/mapping/N.cil
, yang berisi pemetaan
identitas dari type
ke type_N
. Vendor dapat
mengakses type
dengan atribut type_N
yang memiliki versi.
Jika hanya partisi system_ext
dan product
yang diupdate, misalnya
N
ke N+1
(atau yang lebih baru), sementara
vendor tetap menggunakan N
, vendor tersebut dapat kehilangan akses ke
jenis partisi system_ext
dan product
. Untuk mencegah kerusakan, partisi system_ext
dan product
harus menyediakan file pemetaan dari jenis
konkrit ke dalam atribut type_N
. Setiap partner
bertanggung jawab untuk mengelola file pemetaan, jika mereka akan mendukung
vendor N
dengan partisi system_ext
dan product
N+1
(atau yang lebih baru).
Untuk melakukannya, partner diharapkan untuk:
- Salin file pemetaan dasar yang dihasilkan dari partisi
N
system_ext
danproduct
ke hierarki sumbernya. - Perbarui file pemetaan sesuai kebutuhan.
-
Instal
file pemetaan ke partisi
N+1
(atau yang lebih baru)system_ext
danproduct
.
Misalnya, N
system_ext
memiliki satu jenis publik
bernama foo_type
. Kemudian, system_ext/etc/selinux/mapping/N.cil
di partisi N
system_ext
akan terlihat seperti:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
Jika bar_type
ditambahkan ke N+1
system_ext, dan
jika bar_type
harus dipetakan ke foo_type
untuk
vendor N
, N.cil
dapat diperbarui dari
(typeattributeset foo_type_N (foo_type))
to
(typeattributeset foo_type_N (foo_type bar_type))
lalu diinstal ke partisi system_ext N+1
.
Vendor N
dapat terus mengakses N+1
foo_type
dan bar_type
system_ext.
Pelabelan konteks SELinux
Untuk mendukung perbedaan antara sepolicy platform dan vendor, sistem mem-build file konteks SELinux secara berbeda agar tetap terpisah.
Konteks file
Android 8.0 memperkenalkan perubahan berikut untuk file_contexts
:
- Untuk menghindari overhead kompilasi tambahan pada perangkat selama booting,
file_contexts
tidak ada lagi dalam bentuk biner. Sebagai gantinya, file tersebut adalah file teks ekspresi reguler yang dapat dibaca seperti{property, service}_contexts
(seperti sebelum versi 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 dengan tepat untuk memastikan file sepolicy berfungsi dengan benar. - Harus berada di partisi
system
di/system/etc/selinux/plat_file_contexts
pada perangkat dan dimuat olehinit
di awal bersama denganfile_context
vendor.
- Platform Android
vendor_file_contexts
file_context
khusus perangkat yang dibuat dengan menggabungkanfile_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat.- Harus diinstal di
/vendor/etc/selinux/vendor_file_contexts
dalam partisivendor
dan dimuat olehinit
di awal bersama dengan platformfile_context
.
Konteks properti
Di Android 8.0, property_contexts
dibagi menjadi dua file:
plat_property_contexts
property_context
platform Android yang tidak memiliki label khusus perangkat.- Harus berada di partisi
system
di/system/etc/selinux/plat_property_contexts
dan dimuat olehinit
di awal bersama denganproperty_contexts
vendor.
vendor_property_contexts
property_context
khusus perangkat yang dibuat dengan menggabungkanproperty_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat.- Harus berada di partisi
vendor
di/vendor/etc/selinux/vendor_property_contexts
dan dimuat olehinit
di awal bersama dengan platformproperty_context
Konteks layanan
Di Android 8.0, service_contexts
dibagi menjadi beberapa file
berikut:
plat_service_contexts
service_context
khusus platform Android untukservicemanager
.service_context
tidak memiliki label khusus perangkat.- Harus berada di partisi
system
di/system/etc/selinux/plat_service_contexts
dan dimuat olehservicemanager
di awal bersama denganservice_contexts
vendor.
vendor_service_contexts
service_context
khusus perangkat yang dibuat dengan menggabungkanservice_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat.- Harus berada di partisi
vendor
di/vendor/etc/selinux/vendor_service_contexts
dan dimuat olehservicemanager
di awal bersama dengan platformservice_contexts
. - Meskipun
servicemanager
mencari file ini pada waktu booting, untuk perangkatTREBLE
yang sepenuhnya mematuhi,vendor_service_contexts
TIDAK BOLEH ada. Hal ini karena semua interaksi antara prosesvendor
dansystem
HARUS melaluihwservicemanager
/hwbinder
.
plat_hwservice_contexts
- Platform Android
hwservice_context
untukhwservicemanager
yang tidak memiliki label khusus perangkat. - Harus berada di partisi
system
di/system/etc/selinux/plat_hwservice_contexts
dan dimuat olehhwservicemanager
di awal bersama denganvendor_hwservice_contexts
.
- Platform Android
vendor_hwservice_contexts
hwservice_context
khusus perangkat yang dibuat dengan menggabungkanhwservice_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat.- Harus berada di partisi
vendor
di/vendor/etc/selinux/vendor_hwservice_contexts
dan dimuat olehhwservicemanager
di awal bersama denganplat_service_contexts
.
vndservice_contexts
service_context
khusus perangkat untukvndservicemanager
yang dibuat dengan menggabungkanvndservice_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
diBoardconfig.mk
perangkat.- File ini harus berada di partisi
vendor
di/vendor/etc/selinux/vndservice_contexts
dan dimuat olehvndservicemanager
di awal.
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
di/system/etc/selinux/plat_seapp_contexts.
vendor_seapp_contexts
- Ekstensi khusus perangkat ke platform
seapp_context
yang di-build dengan menggabungkanseapp_contexts
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat. - Harus berada di partisi
vendor
di/vendor/etc/selinux/vendor_seapp_contexts
.
- Ekstensi khusus perangkat ke platform
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
di/system/etc/selinux/.
mac_permissions.xml
Non-Platform- Ekstensi khusus perangkat ke platform
mac_permissions.xml
yang dibuat darimac_permissions.xml
yang ditemukan di direktori yang ditunjuk olehBOARD_SEPOLICY_DIRS
dalam fileBoardconfig.mk
perangkat. - Harus berada di partisi
vendor
di/vendor/etc/selinux/.
- Ekstensi khusus perangkat ke platform