Kontrol Akses Diskresioner (DAC)

Objek dan layanan sistem file yang ditambahkan ke build sering kali memerlukan ID unik dan terpisah, yang dikenal sebagai ID Android (AID). Saat ini, banyak sumber daya seperti file dan layanan menggunakan AID inti (yang ditentukan Android) secara tidak perlu; dalam banyak kasus, Anda dapat menggunakan AID OEM (yang 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 AID OEM khusus. Namun, sistem ini tidak intuitif karena tidak mendukung penggunaan nama bagus untuk OEM AID, sehingga mengharuskan Anda menentukan numerik mentah untuk bidang pengguna dan grup tanpa cara mengaitkan nama yang mudah dipahami 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 mendukung hal-hal berikut:

  • Beberapa lokasi sumber untuk file konfigurasi (mengaktifkan konfigurasi build yang dapat diperluas).
  • Pemeriksaan kewarasan waktu pembuatan nilai-nilai OEM AID.
  • Pembuatan header OEM AID khusus 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" dan bukan "2901".

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

Menambahkan ID Android (AID)

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

Misalnya, di private/android_filesystem_config.h :

#define AID_SYSTEM 1000

Menjadi:

  • Nama ramah: sistem
  • cairan: 1000
  • petunjuk: 1000

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

Mengonfigurasi AID

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

Berdasarkan konvensi, file konfigurasi menggunakan nama config.fs , namun 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 AIDs (untuk mengonfigurasi OEM AID).

Mengonfigurasi 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 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 pembatasan, 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 dengan hak istimewa).

Bagian caps menggunakan sintaks berikut:

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

Merupakan kesalahan untuk menentukan beberapa bagian dengan [path] yang sama di file berbeda. Dalam versi Python <= 3.2, file yang sama mungkin berisi bagian yang menggantikan bagian sebelumnya; di Python 3.2, ini disetel ke mode ketat.
mode Mode file oktal Mode file oktal yang valid minimal 3 digit. Jika 3 ditentukan, maka diawali dengan 0, mode lain digunakan apa adanya.
user AID_<pengguna> Entah define C untuk AID yang valid atau nama yang mudah dikenali (misalnya AID_RADIO dan radio dapat diterima). Untuk menentukan AID khusus, lihat bagian Mengonfigurasi AID .
group AID_<grup> Sama seperti pengguna.
caps topi* Nama seperti yang dinyatakan dalam bionic/libc/kernel/uapi/linux/capability.h tanpa awalan CAP_ . Kasus campuran diperbolehkan. Topi juga bisa mentah:
  • biner (0b0101)
  • oktal (0455)
  • ke dalam (42)
  • heksa (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 kumpulan huruf besar, angka, dan garis bawah. Versi huruf kecil digunakan sebagai nama bersahabat. 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 diawali dengan nama partisi untuk memastikan tidak bertentangan dengan sumber lain.
value <angka> String nomor gaya C yang valid (hex, oktal, biner, dan desimal).

Merupakan 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 terkaitnya 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 mendefinisikan dan menggunakan OEM AID dan cara mengaktifkan kemampuan sistem file. Nama OEM AID ( [AID_ name ] ) harus diawali dengan nama partisi seperti " vendor_ " untuk memastikan nama tersebut tidak bertentangan dengan nama AOSP di masa mendatang atau partisi lainnya.

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 ini:

[AID_VENDOR_FOO]
value: 2900

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

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

AID khusus Anda sekarang dapat digunakan oleh sistem secara luas pada versi 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 dinyatakan. Misalnya, di my_file.c , tambahkan yang berikut:

#include "generated_oem_aid.h"
…

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

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

header_libs: ["oemaids_headers"],

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

LOCAL_HEADER_LIBRARIES := oemaids_headers

Menggunakan nama yang bersahabat

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

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

Karena pemetaan internal dari nama ramah ke uid dilakukan oleh /vendor/etc/passwd dan /vendor/etc/group , partisi vendor harus dipasang.

Mengaitkan nama yang bersahabat

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

Mengubah dari AID menjadi nama yang bersahabat

Untuk OEM AID , Android 8.x memerlukan 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 teman di Bionic untuk mengonversi dari ID Android (AID) ke nama ramah dan sebaliknya.

Menggunakan kemampuan sistem file

Untuk mengaktifkan kemampuan sistem file, buat bagian caps 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, atur TARGET_FS_CONFIG_GEN agar menunjuk 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 layanan 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 yang dapat diperbarui atau diganti dengan file biner yang dipasang 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, namun host dapat menggunakan file yang sama selama waktu pembuatan untuk membuat image sistem file sebagai ${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 override

Anda dapat membuat file biner yang 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 perpustakaan libcutils ( fs_config_generate() ) untuk mengelola persyaratan DAC ke dalam buffer dan mendefinisikan aturan untuk file penyertaan guna melembagakan aturan DAC.

Untuk menggunakannya, buat file penyertaan 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[] .

Jika 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 board, dengan nama dasar android_filesystem_config.h yang diterapkan.

Termasuk menimpa file

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

Mengonfigurasi sistem file

Untuk mengonfigurasi sistem file di Android 6.0 dan lebih tinggi:

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

Contoh timpa

Contoh ini menunjukkan patch untuk mengganti daemon system/bin/glgps untuk menambahkan dukungan wake lock di direktori device/ vendor / device . Ingatlah hal berikut:

  • Setiap entri struktur adalah mode, uid, gid, kemampuan, dan namanya. 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 jika 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)

Memigrasi 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.
  • Membutuhkan referensi ke libcutils daripada dijalankan 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 perpustakaan 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 .
  • Berhak menerapkan Kontrol Akses Wajib SELinux (MAC) ke file konfigurasi pada sistem target, implementasi yang menyertakan target khusus yang dapat dieksekusi menggunakan fs_config() harus memastikan akses.