Kontrol akses diskresional (DAC)

Objek dan layanan sistem file yang ditambahkan ke build sering kali memerlukan ID unik yang 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).

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 Anda harus menentukan numerik mentah untuk kolom pengguna dan grup tanpa cara untuk mengaitkan nama yang mudah diingat dengan AID numerik.

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

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

Peningkatan tambahan mencakup penghapusan array android_ids[] dari system/core/libcutils/include/private/android_filesystem_config.h. Array ini kini ada di Bionic sebagai array yang dibuat sepenuhnya secara pribadi, dengan pengakses dengan getpwnam() dan getgrnam(). (Hal ini memiliki efek samping berupa 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 Android Open Source Project (AOSP). 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. define yang cocok dengan AID_* akan diambil oleh alat dan * akan menjadi nama huruf kecil.

Misalnya, di private/android_filesystem_config.h:

#define AID_SYSTEM 1000

Menjadi:

  • Nama sapaan: sistem
  • uid: 1000
  • gid: 1000

Untuk menambahkan AID inti AOSP baru, cukup tambahkan #define ke file header android_filesystem_config.h. AID dibuat saat build dan tersedia untuk antarmuka yang menggunakan argumen pengguna dan grup. Alat ini memvalidasi bahwa AID baru tidak berada dalam rentang APP atau OEM; alat ini juga mematuhi perubahan pada rentang tersebut dan akan otomatis dikonfigurasi ulang saat ada 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, sehingga Anda dapat 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 di Python ConfigParser ini format dan menyertakan bagian caps (untuk mengonfigurasi kemampuan sistem file) dan bagian AIDs (untuk mengonfigurasi AIDs OEM).

Mengonfigurasi bagian huruf kapital

Bagian caps mendukung penetapan file kemampuan sistem 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 penyiapan kemampuan, lalu menggunakan setuid/setgid ke AID yang tepat untuk dijalankan. Dengan batasan, 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 yang memiliki hak istimewa).

Bagian batas penggunaan menggunakan sintaksis berikut:

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

Menentukan beberapa bagian dengan [path] yang sama dalam file yang berbeda adalah suatu kesalahan. Di Python versi <= 3.2, file yang sama dapat berisi bagian yang menggantikan bagian sebelumnya; di Python 3.2, file ini disetel ke mode ketat.
mode Mode file oktal Mode file oktal yang valid dengan minimal 3 digit. Jika 3 ditentukan, maka akan diawali dengan 0, atau mode digunakan apa adanya.
user AID_<user> C define untuk AID yang valid atau nama singkat (misalnya, AID_RADIO dan radio dapat diterima). Untuk menentukan AID kustom, lihat bagian Mengonfigurasi AID.
group AID_<group> Sama seperti pengguna.
caps cap* Nama seperti yang dideklarasikan di bionic/libc/kernel/uapi/linux/capability.h tanpa CAP_ di depannya. Huruf besar/kecil diizinkan. Caps juga dapat berupa raw:
  • biner (0b0101)
  • oktal (0455)
  • int (42)
  • hex (0xFF)
Pisahkan beberapa huruf kapital 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 set 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.

Error terjadi jika Anda 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 tidak bertentangan dengan sumber yang berbeda.
value <number> String angka gaya C yang valid (hex, oktal, biner, dan desimal).

Error jika menentukan beberapa bagian dengan opsi nilai yang sama.

Opsi nilai harus ditentukan dalam rentang yang sesuai dengan partisi yang digunakan dalam <name>. Daftar partisi yang valid dan rentang yang sesuai ditentukan dalam system/core/libcutils/include/private/android_filesystem_config.h. Opsinya 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 AID OEM dan Menggunakan AID OEM.

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 tidak bertentangan dengan nama AOSP atau partisi lainnya di masa mendatang.

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, di device/x/y/BoardConfig.mk, tetapkan hal berikut:

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

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

Menggunakan AID OEM

Untuk menggunakan AID OEM, dalam kode C Anda, sertakan oemaids_headers dalam Makefile terkait, lalu tambahkan #include "generated_oem_aid.h", kemudian 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

Menggunakan nama yang mudah diingat

Di Android 9, Anda dapat menggunakan nama yang mudah diingat 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 yang mudah diingat ke uid dilakukan oleh /vendor/etc/passwd dan /vendor/etc/group, partisi vendor harus di-mount.

Mengaitkan nama sapaan

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

Mengonversi dari AID ke nama yang mudah digunakan

Untuk AID OEM, 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 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, tetapkan TARGET_FS_CONFIG_GEN untuk mengarah ke file tersebut di BoardConfig.mk. Misalnya, di device/x/y/BoardConfig.mk, tetapkan hal berikut:

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

Saat layanan vendor_foo dieksekusi, layanan 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 tempat definisi tersebut 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 parsing 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 memungkinkan pembacaan direktori dan file saat runtime, tetapi host 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 digantikan oleh sistem konfigurasi modular yang diperkenalkan di Android 8.0, Anda masih dapat menggunakan metode lama jika diinginkan. Bagian berikut menjelaskan secara mendetail cara membuat dan menyertakan file penggantian dan mengonfigurasi sistem file.

Membuat file penggantian

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 library libcutils (fs_config_generate()) untuk mengelola persyaratan DAC ke dalam buffer 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 penggantian menggunakan TARGET_ANDROID_FILESYSTEM_CONFIG_H dalam konfigurasi papan, dengan nama dasar yang diterapkan android_filesystem_config.h.

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 papan TARGET_ANDROID_FILESYSTEM_CONFIG_H untuk 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 di file konfigurasi papan (misalnya, $(TARGET_DEVICE_DIR)/device.mk).

Contoh penggantian

Contoh ini menunjukkan patch untuk mengganti daemon system/bin/glgps guna menambahkan dukungan kunci tetap 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 #define manifes (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND).
  • Bagian android_device_files[] mencakup tindakan untuk menekan akses ke system/etc/fs_config_dirs jika tidak ditentukan, yang berfungsi sebagai perlindungan DAC tambahan karena tidak adanya konten untuk penggantian direktori. Namun, ini adalah perlindungan yang lemah; jika seseorang memiliki kontrol atas /system, biasanya dia dapat melakukan apa pun yang diinginkannya.
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 include, struktur, dan definisi inline.
  • Memerlukan referensi ke libcutils, bukan dijalankan langsung dari system/core/include/private/android_filesystem_config.h. File executable pribadi 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 berpindah ke device/vendor/device/android_filesystem_config.h.
  • Mencadangkan hak untuk menerapkan Kontrol Akses Wajib (MAC) SELinux ke file konfigurasi pada sistem target, penerapan yang mencakup file yang dapat dieksekusi target kustom menggunakan fs_config() harus memastikan akses.