Kontrol Akses Diskresi (DAC)

Objek dan layanan sistem file yang ditambahkan ke build sering kali memerlukan ID unik yang terpisah, yang dikenal sebagai Android ID (AID). Saat ini, banyak sumber daya seperti file dan layanan menggunakan AID inti (ditentukan Android) secara tidak perlu; dalam banyak kasus, Anda dapat menggunakan AID OEM (ditentukan OEM).

Versi Android sebelumnya (Android 7.x dan yang lebih rendah) memperluas mekanisme AID menggunakan file android_filesystem_config.h khusus perangkat untuk menentukan kemampuan sistem file dan/atau OEM AID kustom. Namun, sistem ini tidak intuitif karena tidak mendukung penggunaan nama yang bagus untuk OEM AID, yang mengharuskan Anda untuk menentukan numerik mentah untuk bidang pengguna dan grup tanpa cara untuk mengaitkan nama ramah dengan AID numerik.

Versi Android yang lebih baru (Android 8.0 dan lebih tinggi) mendukung metode baru untuk memperluas kemampuan sistem file. Metode baru ini memiliki dukungan untuk hal-hal berikut:

  • Beberapa lokasi sumber untuk file konfigurasi (mengaktifkan konfigurasi build yang dapat diperluas).
  • Pemeriksaan kewarasan waktu build dari nilai OEM AID.
  • Pembuatan header OEM AID kustom yang dapat digunakan dalam file sumber sesuai kebutuhan.
  • Asosiasi nama yang bersahabat dengan nilai OEM AID yang sebenarnya. Mendukung argumen string non-numerik untuk pengguna dan grup, yaitu "foo" alih-alih "2901".

Perbaikan tambahan termasuk penghapusan android_ids[] dari system/core/libcutils/include/private/android_filesystem_config.h . Array ini sekarang ada di Bionic sebagai array yang dihasilkan sepenuhnya pribadi, dengan pengakses melalui getpwnam() dan getgrnam() . (Ini memiliki efek samping menghasilkan binari stabil saat AID inti dimodifikasi.) Untuk perkakas dan file README dengan lebih detail, lihat build/make/tools/fs_config .

Menambahkan ID Android (AID)

Android 8.0 menghapus android_ids[] dari Android Open Source Project (AOSP). Semua nama ramah-AID dihasilkan dari file header system/core/libcutils/include/private/android_filesystem_config.h saat membuat larik Bionic android_ids[] . AID_* yang cocok dengan define apa pun diambil oleh perkakas dan * menjadi nama huruf kecil.

Misalnya, di private/android_filesystem_config.h :

#define AID_SYSTEM 1000

Menjadi:

  • Nama ramah: sistem
  • Uid: 1000
  • gid: 1000

Untuk menambahkan AID inti AOSP baru, cukup tambahkan #define ke file header android_filesystem_config.h . AID akan dibuat saat pembuatan dan tersedia untuk antarmuka yang menggunakan argumen pengguna dan grup. Perkakas memvalidasi bahwa AID baru tidak berada dalam rentang APP atau OEM; itu juga menghormati perubahan pada rentang tersebut dan harus secara otomatis mengonfigurasi ulang pada perubahan atau rentang baru yang dicadangkan OEM.

Mengonfigurasi AID

Untuk mengaktifkan mekanisme AIDs baru, setel TARGET_FS_CONFIG_GEN di file BoardConfig.mk . Variabel ini menyimpan daftar file konfigurasi, memungkinkan Anda untuk menambahkan file sesuai kebutuhan.

Berdasarkan konvensi, file konfigurasi menggunakan nama config.fs , tetapi dalam praktiknya Anda dapat menggunakan nama apa pun. File config.fs berada dalam format Python ConfigParser ini dan menyertakan bagian caps (untuk mengonfigurasi kemampuan sistem file) dan bagian AID (untuk mengonfigurasi OEM AID).

Mengkonfigurasi bagian caps

Bagian caps mendukung pengaturan kemampuan sistem file pada objek sistem file dalam build (sistem file itu sendiri juga harus mendukung fungsi ini).

Karena menjalankan layanan yang stabil sebagai root di Android menyebabkan kegagalan Compatibility Test Suite (CTS) , persyaratan sebelumnya untuk mempertahankan kemampuan saat menjalankan proses atau layanan melibatkan pengaturan kemampuan kemudian menggunakan setuid / setgid ke AID yang tepat untuk dijalankan. Dengan huruf besar, Anda dapat melewati persyaratan ini dan meminta kernel melakukannya untuk Anda. Saat kontrol diserahkan ke main() , proses Anda sudah memiliki kemampuan yang dibutuhkan sehingga layanan Anda dapat menggunakan pengguna dan grup non-root (ini adalah cara yang lebih disukai untuk memulai layanan istimewa).

Bagian caps menggunakan sintaks berikut:

Bagian Nilai Definisi
[path] Jalur sistem file untuk dikonfigurasi. Jalur yang diakhiri dengan / dianggap sebagai dir, jika tidak, itu adalah file.

Ini adalah kesalahan untuk menentukan beberapa bagian dengan [path] yang sama di file yang berbeda. Dalam versi Python <= 3.2, file yang sama mungkin berisi bagian yang menimpa bagian sebelumnya; di Python 3.2, disetel ke mode ketat.
mode Modus berkas oktal Mode file oktal yang valid minimal 3 digit. Jika 3 ditentukan, itu diawali dengan 0, mode lain digunakan apa adanya.
user AID_<pengguna> Entah C define untuk AID yang valid atau nama yang ramah (mis AID_RADIO dan radio dapat diterima). Untuk menentukan AID khusus, lihat Mengonfigurasi bagian AID .
group AID_<grup> Sama dengan pengguna.
caps topi* Nama seperti yang dideklarasikan dalam bionic/libc/kernel/uapi/linux/capability.h tanpa awalan CAP_ . Kasus campuran diperbolehkan. Topi juga bisa mentah:
  • biner (0b0101)
  • oktal (0455)
  • int (42)
  • heksagonal (0xFF)
Pisahkan beberapa huruf besar menggunakan spasi putih.

Untuk contoh penggunaan, lihat Menggunakan kemampuan sistem file .

Mengonfigurasi bagian AID

Bagian AID berisi OEM AID dan menggunakan sintaks berikut:

Bagian Nilai Definisi
[AID_<name>] <name> dapat berisi karakter dalam set huruf besar, angka, dan garis bawah. Versi huruf kecil digunakan sebagai nama yang ramah. File header yang dihasilkan untuk penyertaan kode menggunakan AID_<name> yang tepat.

Merupakan kesalahan untuk menentukan beberapa bagian dengan AID_<name> yang sama (tidak peka huruf besar/kecil dengan batasan yang sama seperti [path] ).

<name> harus dimulai dengan nama partisi untuk memastikan bahwa itu tidak bertentangan dengan sumber yang berbeda.
value <angka> String nomor gaya C yang valid (hex, oktal, biner, dan desimal).

Ini adalah kesalahan untuk menentukan beberapa bagian dengan opsi nilai yang sama.

Opsi nilai harus ditentukan dalam rentang yang sesuai dengan partisi yang digunakan di <name> . Daftar partisi yang valid dan rentang yang sesuai ditentukan di system/core/libcutils/include/private/android_filesystem_config.h . Pilihannya adalah:
  • Partisi Vendor
    • AID_OEM_RESERVED_START(2900) - AID_OEM_RESERVED_END(2999)
    • AID_OEM_RESERVED_2_START(5000) - AID_OEM_RESERVED_2_END(5999)
  • Partisi Sistem
    • AID_SYSTEM_RESERVED_START(6000) - AID_SYSTEM_RESERVED_END(6499)
  • Partisi ODM
    • AID_ODM_RESERVED_START(6500) - AID_ODM_RESERVED_END(6999)
  • Partisi Produk
    • AID_PRODUCT_RESERVED_START(7000) - AID_PRODUCT_RESERVED_END(7499)
  • Partisi System_ext
    • AID_SYSTEM_EXT_RESERVED_START(7500) - AID_SYSTEM_EXT_RESERVED_END(7999)

Untuk contoh penggunaan, lihat Menentukan nama OEM AID dan Menggunakan OEM AIDs .

Contoh penggunaan

Contoh berikut merinci cara menentukan dan menggunakan OEM AID dan cara mengaktifkan kemampuan sistem file. Nama AID OEM ( [AID_ name ] ) harus dimulai dengan nama partisi seperti " vendor_ " untuk memastikan mereka tidak bertentangan dengan nama AOSP mendatang atau partisi lain.

Mendefinisikan nama OEM AID

Untuk menentukan OEM AID, buat file config.fs dan atur nilai AID. Misalnya, di device/x/y/config.fs , atur yang berikut:

[AID_VENDOR_FOO]
value: 2900

Setelah membuat file, setel variabel TARGET_FS_CONFIG_GEN dan arahkan ke sana di BoardConfig.mk . Misalnya, di device/x/y/BoardConfig.mk , atur yang berikut:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

AID kustom Anda sekarang dapat digunakan oleh sistem secara luas pada build baru.

Menggunakan OEM AID

Untuk menggunakan OEM AID, dalam kode C Anda, sertakan oemaids_headers di Makefile terkait Anda, dan tambahkan #include "generated_oem_aid.h" , lalu mulai gunakan pengidentifikasi yang dideklarasikan. Misalnya, di my_file.c , tambahkan berikut ini:

#include "generated_oem_aid.h"
…

If (ipc->uid == AID_VENDOR_FOO) {
  // Do something
...

Di file Android.bp terkait Anda, tambahkan yang berikut ini:

header_libs: ["oemaids_headers"],

Jika Anda menggunakan file Android.mk , tambahkan berikut ini:

LOCAL_HEADER_LIBRARIES := oemaids_headers

Menggunakan nama yang ramah

Di Android 9, Anda dapat menggunakan nama ramah untuk antarmuka apa pun yang mendukung nama AID. Sebagai contoh:

  • Dalam perintah chown di some/init.rc : l10n
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • Dalam service di some/init.rc : l10n
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Karena pemetaan internal dari friendly name ke uid dilakukan oleh /vendor/etc/passwd dan /vendor/etc/group , partisi vendor harus di-mount.

Mengaitkan nama-nama ramah

Android 9 menyertakan dukungan untuk mengaitkan nama yang ramah dengan nilai OEM AID yang sebenarnya. Anda dapat menggunakan argumen string non-numerik untuk pengguna dan grup, yaitu " vendor_ foo" alih-alih "2901".

Mengubah dari AID menjadi nama yang ramah

Untuk OEM AIDs , Android 8.x mengharuskan penggunaan oem_#### dengan getpwnam dan fungsi serupa, serta di tempat yang menangani pencarian melalui getpwnam (seperti skrip init ). Di Android 9, Anda dapat menggunakan getpwnam dan getgrnam friends di Bionic untuk mengonversi dari Android ID (AID) ke nama ramah dan sebaliknya.

Menggunakan kemampuan sistem file

Untuk mengaktifkan kemampuan sistem file, buat bagian huruf besar di file config.fs . Misalnya, di device/x/y/config.fs , tambahkan bagian berikut:

[system/bin/foo_service]
mode: 0555
user: AID_VENDOR_FOO
group: AID_SYSTEM
caps: SYS_ADMIN | SYS_NICE

Setelah membuat file, setel TARGET_FS_CONFIG_GEN agar mengarah ke file tersebut di BoardConfig.mk . Misalnya, di device/x/y/BoardConfig.mk , atur yang berikut:

TARGET_FS_CONFIG_GEN += device/x/y/config.fs

Ketika service vendor_ foo dijalankan, itu dimulai dengan kemampuan CAP_SYS_ADMIN dan CAP_SYS_NICE tanpa panggilan setuid dan setgid . Selain itu, kebijakan SELinux layanan vendor_ foo tidak lagi memerlukan kemampuan setuid dan setgid dan dapat dihapus.

Mengonfigurasi penggantian (Android 6.x-7.x)

Android 6.0 memindahkan fs_config dan definisi struktur terkait ( system/core/include/private/android_filesystem_config.h ) ke system/core/libcutils/fs_config.c di mana mereka dapat diperbarui atau diganti oleh file biner yang diinstal di /system/etc/fs_config_dirs dan /system/etc/fs_config_files . Menggunakan aturan pencocokan dan penguraian terpisah untuk direktori dan file (yang dapat menggunakan ekspresi glob tambahan) memungkinkan Android menangani direktori dan file dalam dua tabel berbeda. Definisi struktur di system/core/libcutils/fs_config.c tidak hanya mengizinkan pembacaan runtime direktori dan file, tetapi tuan rumah dapat menggunakan file yang sama selama waktu pembuatan untuk membuat image sistem file seperti ${OUT}/system/etc/fs_config_dirs dan ${OUT}/system/etc/fs_config_files .

Meskipun metode override untuk memperluas sistem file telah digantikan oleh sistem konfigurasi modular yang diperkenalkan di Android 8.0, Anda masih dapat menggunakan metode lama jika diinginkan. Bagian berikut merinci cara membuat dan menyertakan file override dan mengonfigurasi sistem file.

Menghasilkan file penimpaan

Anda dapat membuat file biner selaras /system/etc/fs_config_dirs dan /system/etc/fs_config_files menggunakan alat fs_config_generate di build/tools/fs_config . Alat ini menggunakan fungsi pustaka libcutils ( fs_config_generate() ) untuk mengelola persyaratan DAC ke dalam buffer dan mendefinisikan aturan untuk file yang disertakan guna melembagakan aturan DAC.

Untuk menggunakannya, buat file include di device/ vendor / device /android_filesystem_config.h yang bertindak sebagai override. File harus menggunakan structure fs_path_config yang ditentukan dalam system/core/include/private/android_filesystem_config.h dengan inisialisasi struktur berikut untuk direktori dan simbol file:

  • Untuk direktori, gunakan android _device _dirs[] .
  • Untuk file, gunakan android _device _files[] .

Saat tidak menggunakan android_device_dirs[] dan android_device_files[] , Anda dapat mendefinisikan NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS dan NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (lihat contoh di bawah). Anda juga dapat menentukan file override menggunakan TARGET_ANDROID_FILESYSTEM_CONFIG_H dalam konfigurasi papan, dengan nama dasar yang diberlakukan android_filesystem_config.h .

Termasuk menimpa file

Untuk menyertakan file, pastikan bahwa PRODUCT_PACKAGES menyertakan fs_config_dirs dan/atau fs_config_files sehingga dapat menginstalnya masing-masing ke /system/etc/fs_config_dirs dan /system/etc/fs_config_files . Sistem pembangunan mencari android_filesystem_config.h khusus di $(TARGET_DEVICE_DIR) , tempat BoardConfig.mk ada. Jika file ini ada di tempat lain, setel variabel konfigurasi papan TARGET_ANDROID_FILESYSTEM_CONFIG_H untuk menunjuk ke lokasi itu.

Mengkonfigurasi sistem file

Untuk mengonfigurasi sistem file di Android 6.0 dan lebih tinggi:

  1. Buat file $(TARGET_DEVICE_DIR)/android_filesystem_config.h .
  2. Tambahkan fs_config_dirs dan/atau fs_config_files ke PRODUCT_PACKAGES di file konfigurasi papan (misalnya, $(TARGET_DEVICE_DIR)/device.mk ).

Ganti contoh

Contoh ini menunjukkan tambalan untuk mengganti daemon system/bin/glgps untuk menambahkan dukungan penguncian layar saat aktif di direktori device/ vendor / device . Ingatlah hal berikut:

  • Setiap entri struktur adalah mode, uid, gid, kemampuan, dan nama. system/core/include/private/android_filesystem_config.h disertakan secara otomatis untuk memberikan manifes #defines ( AID_ROOT , AID_SHELL , CAP_BLOCK_SUSPEND ).
  • Bagian android_device_files[] menyertakan tindakan untuk menekan akses ke system/etc/fs_config_dirs saat tidak ditentukan, yang berfungsi sebagai perlindungan DAC tambahan karena kurangnya konten untuk penggantian direktori. Namun, ini adalah perlindungan yang lemah; jika seseorang memiliki kendali atas /system , mereka biasanya dapat melakukan apa pun yang mereka inginkan.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h
new file mode 100644
index 0000000..874195f
--- /dev/null
+++ b/android_filesystem_config.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/* This file is used to define the properties of the filesystem
+** images generated by build tools (eg: mkbootfs) and
+** by the device side of adb.
+*/
+
+#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+/* static const struct fs_path_config android_device_dirs[] = { }; */
+
+/* Rules for files.
+** These rules are applied based on "first match", so they
+** should start with the most specific path and work their
+** way up to the root. Prefixes ending in * denotes wildcard
+** and will allow partial matches.
+*/
+static const struct fs_path_config android_device_files[] = {
+  { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND),
"system/bin/glgps" },
+#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
+  { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" },
+#endif
+};


diff --git a/device.mk b/device.mk
index 0c71d21..235c1a7 100644
--- a/device.mk
+++ b/device.mk
@@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \
     libwpa_client \
     hostapd \
     wpa_supplicant \
-    wpa_supplicant.conf
+    wpa_supplicant.conf \
+    fs_config_files

 ifeq ($(TARGET_PREBUILT_KERNEL),)
 ifeq ($(USE_SVELTE_KERNEL), true)

Migrasi sistem file dari rilis sebelumnya

Saat memigrasikan sistem file dari Android 5.x dan versi lebih lama, perlu diingat bahwa Android 6.x

  • Menghapus beberapa penyertaan, struktur, dan definisi sebaris.
  • Memerlukan referensi ke libcutils alih-alih menjalankan langsung dari system/core/include/private/android_filesystem_config.h . Eksekusi pribadi produsen perangkat yang bergantung pada system/code/include/private_filesystem_config.h untuk struktur file atau direktori atau fs_config harus menambahkan dependensi pustaka libcutils .
  • Memerlukan salinan cabang pribadi produsen perangkat dari system/core/include/private/android_filesystem_config.h dengan konten tambahan pada target yang ada untuk dipindahkan ke device/ vendor / device /android_filesystem_config.h .
  • Memiliki hak untuk menerapkan SELinux Mandatory Access Controls (MAC) ke file konfigurasi pada sistem target, implementasi yang menyertakan executable target kustom menggunakan fs_config() harus memastikan akses.