{i>Discretionary access control

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

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

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

  • Beberapa lokasi sumber untuk file konfigurasi (memungkinkan konfigurasi build yang dapat diperluas).
  • Pemeriksaan keandalan waktu build untuk nilai AID OEM.
  • Pembuatan header AID OEM kustom yang dapat digunakan dalam file sumber sesuai kebutuhan.
  • Pengaitan nama sebutan dengan nilai AID OEM yang sebenarnya. Mendukung argumen string nonnumerik untuk pengguna dan grup, yaitu "foo", 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 dibuat sepenuhnya pribadi, dengan pengakses dengan getpwnam() dan getgrnam(). (Tindakan ini memiliki efek samping menghasilkan biner yang stabil saat AID inti diubah.) Untuk alat dan file README dengan detail selengkapnya, lihat build/make/tools/fs_config.

Menambahkan ID Android (AID)

Android 8.0 menghapus array android_ids[] dari Project Open Source Android (AOSP). Sebagai gantinya, semua nama yang kompatibel dengan AID dibuat dari file header system/core/libcutils/include/private/android_filesystem_config.h saat membuat array android_ids[] Bionic. Setiap define yang cocok dengan AID_* akan diambil oleh alat dan * menjadi nama huruf kecil.

Misalnya, dalam private/android_filesystem_config.h:

#define AID_SYSTEM 1000

Menjadi:

  • Nama yang mudah digunakan: sistem
  • uid: 1000
  • gid: 1000

Untuk menambahkan AID inti AOSP baru, cukup tambahkan #define ke file header android_filesystem_config.h. AID dibuat pada saat build dan tersedia untuk antarmuka yang menggunakan argumen pengguna dan grup. Alat ini memvalidasi AID baru tidak berada dalam rentang APP atau OEM; alat ini juga mengikuti perubahan pada rentang tersebut dan harus otomatis mengonfigurasi ulang pada perubahan atau rentang baru yang dicadangkan OEM.

Konfigurasi AID

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

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

Mengonfigurasi bagian huruf besar

Bagian caps mendukung penetapan 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 penyiapan kemampuan, lalu menggunakan setuid/setgid ke AID yang tepat untuk dijalankan. Dengan batas, Anda dapat melewati persyaratan ini dan meminta kernel melakukannya untuk Anda. Saat kontrol diserahkan ke main(), proses Anda sudah memiliki kemampuan yang diperlukan sehingga layanan Anda dapat menggunakan pengguna dan grup non-root (ini adalah cara yang lebih disukai untuk memulai layanan dengan hak istimewa).

Bagian huruf besar menggunakan sintaksis berikut:

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

Menentukan beberapa bagian dengan [path] yang sama dalam file yang berbeda adalah error. Dalam Python versi <= 3.2, file yang sama dapat berisi bagian yang menggantikan bagian sebelumnya. Dalam Python 3.2, file ini disetel ke mode ketat.
mode Mode file oktal Mode file oktal yang valid minimal 3 digit. Jika 3 ditentukan, mode ini akan diawali dengan 0, atau mode lain akan digunakan sebagaimana adanya.
user AID_<user> C define untuk AID yang valid atau nama sebutan (misalnya, AID_RADIO dan radio dapat diterima). Untuk menentukan AID kustom, lihat Mengonfigurasi bagian AID.
group AID_<group> Sama seperti pengguna.
caps cap* Nama seperti yang dideklarasikan dalam bionic/libc/kernel/uapi/linux/capability.h tanpa CAP_ di awal. Huruf besar/kecil diizinkan. Caps juga dapat berupa data mentah:
  • biner (0b0101)
  • oktal (0455)
  • int (42)
  • heksadesimal (0xFF)
Pisahkan beberapa huruf besar menggunakan spasi kosong.

Untuk contoh penggunaan, lihat Menggunakan kemampuan sistem file.

Mengonfigurasi bagian AID

Bagian AID berisi AID OEM dan menggunakan sintaksis berikut:

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

Menentukan beberapa bagian dengan AID_<name> yang sama (tidak peka huruf besar/kecil dengan batasan yang sama seperti [path]) adalah error.

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

Menentukan beberapa bagian dengan opsi nilai yang sama akan menyebabkan error.

Opsi nilai harus ditentukan dalam rentang yang sesuai dengan partisi yang digunakan di <name>. Daftar partisi yang valid dan rentangnya yang sesuai ditentukan di system/core/libcutils/include/private/android_filesystem_config.h. Opsi yang tersedia 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)
  • Pemisahan 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 AID.

Contoh penggunaan

Contoh berikut menjelaskan cara menentukan dan menggunakan AID OEM serta cara mengaktifkan kemampuan sistem file. Nama AID OEM ([AID_name]) harus diawali dengan nama partisi seperti "vendor_" untuk memastikan nama tersebut tidak bertentangan dengan nama AOSP mendatang atau partisi lainnya.

Menentukan nama AID OEM

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

[AID_VENDOR_FOO]
value: 2900

Setelah membuat file, tetapkan variabel TARGET_FS_CONFIG_GEN dan arahkan ke variabel tersebut di BoardConfig.mk. Misalnya, dalam device/x/y/BoardConfig.mk, tetapkan berikut ini:

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

AID kustom Anda kini dapat digunakan oleh sistem secara keseluruhan pada build baru.

Menggunakan AID OEM

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

#include "generated_oem_aid.h"


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

Di file Android.bp terkait, tambahkan kode berikut:

header_libs: ["oemaids_headers"],

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

LOCAL_HEADER_LIBRARIES := oemaids_headers

Gunakan nama yang mudah dikenali

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

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

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

Mengaitkan nama yang simpel

Android 9 menyertakan dukungan untuk mengaitkan nama mudah dengan nilai AID OEM yang sebenarnya. Anda dapat menggunakan argumen string nonnumerik untuk pengguna dan grup, yaitu, "vendor_foo", bukan "2901".

Mengonversi dari AID ke nama yang mudah diingat

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

Menggunakan kemampuan sistem file

Untuk mengaktifkan kemampuan sistem file, buat bagian huruf besar di file config.fs. Misalnya, dalam 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, tetapkan TARGET_FS_CONFIG_GEN untuk mengarah ke file tersebut di BoardConfig.mk. Misalnya, dalam device/x/y/BoardConfig.mk, tetapkan berikut ini:

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

Saat dijalankan, layanan vendor_foo akan 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 tempatnya dapat diperbarui atau diganti oleh file biner yang diinstal di /system/etc/fs_config_dirs dan /system/etc/fs_config_files. Penggunaan aturan pencocokan dan penguraian terpisah untuk direktori dan file (yang dapat menggunakan ekspresi glob tambahan) memungkinkan Android menangani direktori dan file dalam dua tabel yang berbeda. Definisi struktur di system/core/libcutils/fs_config.c tidak hanya mengizinkan pembacaan runtime direktori dan file, tetapi host juga dapat menggunakan file yang sama selama waktu build untuk membuat image sistem file sebagai ${OUT}/system/etc/fs_config_dirs dan ${OUT}/system/etc/fs_config_files.

Meskipun metode penggantian untuk memperluas sistem file telah diganti dengan sistem konfigurasi modular yang diperkenalkan di Android 8.0, Anda masih dapat menggunakan metode lama jika diinginkan. Bagian berikut menjelaskan cara membuat dan menyertakan file penggantian serta mengonfigurasi sistem file.

Membuat file penggantian

Anda dapat membuat file biner yang sejajar /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 library libcutils (fs_config_generate()) untuk mengelola persyaratan DAC ke dalam buffering dan menentukan aturan untuk file include guna melembagakan aturan DAC.

Untuk menggunakannya, buat file include di device/vendor/device/android_filesystem_config.h yang berfungsi sebagai penggantian. File harus menggunakan format structure fs_path_config yang ditentukan dalam system/core/include/private/android_filesystem_config.h dengan inisialisasi struktur berikut untuk simbol direktori dan 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 menentukan NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS dan NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES (lihat contoh di bawah). Anda juga dapat menentukan file pengganti menggunakan TARGET_ANDROID_FILESYSTEM_CONFIG_H dalam konfigurasi board, dengan nama dasar android_filesystem_config.h yang diterapkan.

Menyertakan file penggantian

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 kustom di $(TARGET_DEVICE_DIR), tempat BoardConfig.mk berada. Jika file ini ada di tempat lain, tetapkan variabel konfigurasi board TARGET_ANDROID_FILESYSTEM_CONFIG_H agar mengarah ke lokasi tersebut.

Mengonfigurasi sistem file

Untuk mengonfigurasi sistem file di Android 6.0 dan yang 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 dalam file konfigurasi board (misalnya, $(TARGET_DEVICE_DIR)/device.mk).

Contoh penggantian

Contoh ini menunjukkan patch untuk mengganti daemon system/bin/glgps guna menambahkan dukungan kunci layar aktif di direktori device/vendor/device. Perhatikan hal-hal berikut:

  • Setiap entri struktur adalah mode, UID, gid, kemampuan, dan nama. system/core/include/private/android_filesystem_config.h disertakan secara otomatis untuk menyediakan manifes #define (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND).
  • Bagian android_device_files[] menyertakan tindakan untuk menyembunyikan 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 kontrol 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 file system
+** 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)

Memigrasikan sistem file dari rilis sebelumnya

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

  • Menghapus beberapa penyertaan, struktur, dan definisi inline.
  • Memerlukan referensi ke libcutils, bukan berjalan langsung dari system/core/include/private/android_filesystem_config.h. File yang dapat dieksekusi secara pribadi oleh produsen perangkat yang bergantung pada system/code/include/private_filesystem_config.h untuk struktur file atau direktori atau fs_config harus menambahkan dependensi library 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.
  • Mempertahankan hak untuk menerapkan Kontrol Akses Wajib (MAC) SELinux ke file konfigurasi di sistem target, implementasi yang menyertakan file yang dapat dijalankan target kustom menggunakan fs_config() harus memastikan akses.