İsteğe Bağlı Erişim Kontrolü (DAC)

Derlemeye eklenen dosya sistemi nesneleri ve hizmetleri sıklıkla Android Kimlikleri (AID'ler) olarak bilinen ayrı, benzersiz kimliklere ihtiyaç duyar. Şu anda, dosyalar ve hizmetler gibi birçok kaynak, çekirdek (Android tanımlı) AID'leri gereksiz yere kullanmaktadır; çoğu durumda bunun yerine OEM (OEM tanımlı) AID'leri kullanabilirsiniz.

Android'in önceki sürümleri (Android 7.x ve daha düşük), dosya sistemi yeteneklerini ve / veya özel OEM AID'leri belirtmek için cihaza özgü bir android_filesystem_config.h dosyası kullanarak AID mekanizmasını genişletti. Bununla birlikte, bu sistem OEM AID'ler için güzel adların kullanılmasını desteklemediğinden, kullanıcı ve grup alanları için sayısal AID ile kolay bir ad ilişkilendirme yolu olmadan ham rakamı belirtmenizi gerektirdiğinden sezgisel değildi.

Android'in daha yeni sürümleri (Android 8.0 ve üstü), dosya sistemi yeteneklerini genişletmek için yeni bir yöntemi destekler. Bu yeni yöntem aşağıdakileri destekler:

  • Yapılandırma dosyaları için birden çok kaynak konumu (genişletilebilir yapı yapılandırmalarını etkinleştirir).
  • OEM AID değerlerinin derleme zamanı mantıklı denetimi.
  • Gerektiğinde kaynak dosyalarda kullanılabilecek özel bir OEM AID başlığının oluşturulması.
  • Gerçek OEM AID değeri ile kolay anlaşılır bir adın ilişkilendirilmesi. Kullanıcı ve grup için sayısal olmayan dize argümanlarını destekler, yani "2901" yerine "foo".

Ek iyileştirmeler, android_ids[] dizisinin system/core/libcutils/include/private/android_filesystem_config.h . Bu dizi artık getpwnam() ve getgrnam() aracılığıyla erişimcilerle tamamen özel üretilmiş bir dizi olarak var. (Bu, temel AID'ler değiştirildiği için kararlı ikili dosyalar üretme yan etkisine sahiptir.) Takım oluşturma ve daha fazla ayrıntı içeren bir README dosyası için, build/make/tools/fs_config .

Android Kimlikleri (AID'ler) Ekleme

Android 8.0, android_ids[] dizisini Android Açık Kaynak Projesi'nden (AOSP) kaldırdı. Bunun yerine tüm AID uyumlu adlar, Bionic android_ids[] dizisi oluşturulurken system/core/libcutils/include/private/android_filesystem_config.h başlık dosyasından system/core/libcutils/include/private/android_filesystem_config.h . Herhangi define eşleşen AID_* kalıp tarafından yakalandı ve * küçük adı haline gelir.

Örneğin, private/android_filesystem_config.h :

#define AID_SYSTEM 1000

Oluyor:

  • Kolay ad: sistem
  • uid: 1000
  • gid: 1000

Yeni bir AOSP çekirdek AID'si eklemek için, #define android_filesystem_config.h başlık dosyasına eklemeniz yeterlidir. AID, derleme sırasında üretilecek ve kullanıcı ve grup bağımsız değişkenlerini kullanan arabirimler için kullanılabilir hale getirilecektir. Araç, yeni AID'nin APP veya OEM aralıkları içinde olmadığını doğrular; aynı zamanda bu aralıklardaki değişikliklere saygı duyar ve değişikliklerde veya yeni OEM tarafından ayrılmış aralıklarda otomatik olarak yeniden yapılandırılmalıdır.

AID'leri Yapılandırma

Yeni BoardConfig.mk mekanizmasını etkinleştirmek için, BoardConfig.mk dosyasında TARGET_FS_CONFIG_GEN ayarlayın. Bu değişken, gerektiğinde dosyaları eklemenize olanak tanıyan yapılandırma dosyalarının bir listesini tutar.

config.fs , yapılandırma dosyaları config.fs adını config.fs , ancak pratikte herhangi bir adı kullanabilirsiniz. config.fs dosyaları Python ConfigParser ini formatındadır ve bir büyük harf bölümü (dosya sistemi yeteneklerini yapılandırmak için) ve bir AID bölümü (OEM AID'leri yapılandırmak için) içerir.

Büyük harf bölümünü yapılandırma

Kapaklar bölümü, yapı içindeki dosya sistemi nesneleri üzerinde dosya sistemi yeteneklerinin ayarlanmasını destekler (dosya sisteminin kendisi de bu işlevi desteklemelidir).

Android'de kök olarak kararlı bir hizmet çalıştırmak Uyumluluk Test Paketi (CTS) arızasına neden olduğundan, bir işlemi veya hizmeti çalıştırırken bir yeteneği korumaya yönelik önceki gereksinimler, yeteneklerin kurulmasını ve ardından çalıştırmak için uygun bir setgid setuid / setgid kullanmayı gerektiriyordu. Büyük harflerle bu gereksinimleri atlayabilir ve çekirdeğin sizin için yapmasını sağlayabilirsiniz. Kontrol main() verildiğinde, işleminiz ihtiyaç duyduğu yeteneklere zaten sahiptir, böylece hizmetiniz kök olmayan bir kullanıcı ve grubu kullanabilir (bu, ayrıcalıklı hizmetleri başlatmak için tercih edilen yoldur).

Büyük harf bölümü aşağıdaki sözdizimini kullanır:

Bölüm Değer Tanım
[path] Yapılandırılacak dosya sistemi yolu. / İle biten bir yol bir dir, aksi takdirde bir dosyadır.

Farklı dosyalarda aynı [path] ile birden çok bölüm belirtmek bir hatadır. Python sürümleri <= 3.2'de, aynı dosya önceki bölümü geçersiz kılan bölümler içerebilir; Python 3.2'de katı moda ayarlanmıştır.
mode Sekizli dosya modu En az 3 basamaklı geçerli bir sekizlik dosya modu. 3 belirtilirse, 0 ile başlar, aksi takdirde mod olduğu gibi kullanılır.
user AID_ <kullanıcı> Ya C geçerli bir AID ya da kolay ad için define (örneğin hem AID_RADIO hem de radio kabul edilebilir). Özel bir AID tanımlamak için , AID'yi Yapılandırma bölümüne bakın .
group AID_ <group> Kullanıcı ile aynı.
caps şapka * Başta bionic/libc/kernel/uapi/linux/capability.h olmadan bionic/libc/kernel/uapi/linux/capability.h CAP_ . Karışık duruma izin verilir. Kapaklar ayrıca ham olabilir:
  • ikili (0b0101)
  • sekizlik (0455)
  • int (42)
  • onaltılık (0xFF)
Beyaz boşlukları kullanarak birden çok büyük harf ayırın.

Kullanım örneği için bkz . Dosya sistemi yeteneklerini kullanma .

AID bölümünü yapılandırma

AID bölümü OEM AID'leri içerir ve aşağıdaki sözdizimini kullanır:

Bölüm Değer Tanım
[AID_<name>] <name> , büyük harf, sayılar ve alt çizgilerdeki karakterleri içerebilir. Küçük harfli sürüm kolay ad olarak kullanılır. Kod dahil etmek için oluşturulan üstbilgi dosyası tam AID_<name> kullanır.

Aynı AID_<name> ile birden çok bölüm belirtmek bir hatadır ( [path] ile aynı kısıtlamalara sahip büyük / küçük harfe duyarlı değildir).

<name> , farklı kaynaklarla çakışmamasını sağlamak için bir bölüm adıyla başlamalıdır.
value <sayı> Geçerli bir C stili sayı dizesi (onaltılık, sekizlik, ikili ve ondalık).

Aynı değer seçeneğiyle birden çok bölüm belirtmek bir hatadır.

Değer seçenekleri, <name> kullanılan bölüme karşılık gelen aralıkta belirtilmelidir. Geçerli bölümlerin listesi ve bunlara karşılık gelen aralıklar system/core/libcutils/include/private/android_filesystem_config.h . Seçenekler şunlardır:
  • Satıcı Bölümü
    • AID_OEM_RESERVED_START (2900) - AID_OEM_RESERVED_END (2999)
    • AID_OEM_RESERVED_2_START (5000) - AID_OEM_RESERVED_2_END (5999)
  • Sistem Bölümü
    • AID_SYSTEM_RESERVED_START (6000) - AID_SYSTEM_RESERVED_END (6499)
  • ODM Bölümü
    • AID_ODM_RESERVED_START (6500) - AID_ODM_RESERVED_END (6999)
  • Ürün Bölümü
    • AID_PRODUCT_RESERVED_START (7000) - AID_PRODUCT_RESERVED_END (7499)
  • System_ext Bölümü
    • AID_SYSTEM_EXT_RESERVED_START (7500) - AID_SYSTEM_EXT_RESERVED_END (7999)

Kullanım örnekleri için bkz. OEM AID adlarını tanımlama ve OEM AID'leri Kullanma .

Kullanım örnekleri

Aşağıdaki örnekler, bir OEM AID'nin nasıl tanımlanıp kullanılacağını ve dosya sistemi yeteneklerinin nasıl etkinleştirileceğini ayrıntılarıyla anlatmaktadır. OEM AID adları ( [AID_ adı ] ) gelecekteki AOSP adları veya diğer bölümlerle çakışmamalarını sağlamak için " vendor_ " gibi bir bölüm adıyla başlamalıdır.

OEM AID adlarını tanımlama

Bir OEM AID tanımlamak için, bir config.fs dosyası oluşturun ve AID değerini ayarlayın. Örneğin, device/x/y/config.fs aşağıdakileri ayarlayın:

[AID_VENDOR_FOO]
value: 2900

Dosyayı oluşturduktan sonra TARGET_FS_CONFIG_GEN değişkenini ayarlayın ve BoardConfig.mk içinde BoardConfig.mk . Örneğin, device/x/y/BoardConfig.mk içinde aşağıdakileri ayarlayın:

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

Özel AID'niz artık sistem tarafından yeni bir yapıda tüketilebilir.

OEM AID'leri kullanma

Bir OEM AID kullanmak için, C kodunuzda, oemaids_headers ilişkili Makefile dosyanıza ekleyin ve #include "generated_oem_aid.h" ekleyin, ardından bildirilen tanımlayıcıları kullanmaya başlayın. Örneğin, my_file.c aşağıdakileri ekleyin:

#include "generated_oem_aid.h"
…

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

İlişkili Android.bp dosyanıza aşağıdakileri ekleyin:

header_libs: ["oemaids_headers"],

Bir Android.mk dosyası kullanıyorsanız, aşağıdakileri ekleyin:

LOCAL_HEADER_LIBRARIES := oemaids_headers

Kolay isimler kullanmak

Android 9'da, AID adlarını destekleyen herhangi bir arayüz için kolay anlaşılır adı kullanabilirsiniz. Örneğin:

  • some/init.rc chown komutunda:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • Bir de service içinde some/init.rc
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    
    :

Kolay addan kullanıcı kimliğine dahili eşleme /vendor/etc/passwd ve /vendor/etc/group yapıldığından, satıcı bölümü bağlanmalıdır.

Kolay isimleri ilişkilendirme

Android 9, gerçek OEM AID değeriyle kolay bir ad ilişkilendirme desteği içerir. Kullanıcı ve grup için sayısal olmayan dize argümanları kullanabilirsiniz, yani "2901" yerine " vendor_ foo".

AID'den kolay isimlere dönüştürme

OEM AID'ler için Android 8.x, getpwnam ve benzeri işlevler ile oem_#### kullanımının yanı sıra getpwnam aracılığıyla aramaları gerçekleştiren yerlerde ( init betikleri gibi) kullanılmasını gerektiriyordu. Android 9'da, Android ID'lerinden (AID'ler) kolay adlara veya tam tersi şekilde dönüştürmek için getpwnam ve getgrnam arkadaşlarını kullanabilirsiniz.

Dosya sistemi yeteneklerini kullanma

Dosya sistemi yeteneklerini etkinleştirmek için config.fs dosyasında bir büyük harf bölümü oluşturun. Örneğin, device/x/y/config.fs içinde aşağıdaki bölümü ekleyin:

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

Dosyayı oluşturduktan sonra, TARGET_FS_CONFIG_GEN BoardConfig.mk o dosyaya işaret edecek şekilde BoardConfig.mk . Örneğin, device/x/y/BoardConfig.mk içinde aşağıdakileri ayarlayın:

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

Service vendor_ foo çalıştırıldığında, setuid ve setgid çağrıları olmaksızın CAP_SYS_ADMIN ve CAP_SYS_NICE yetenekleriyle başlar. Ek olarak, vendor_ foo hizmetinin SELinux ilkesi artık yetenek setuid ve setgid ve silinebilir.

Geçersiz kılmaları yapılandırma (Android 6.x-7.x)

Android 6.0 fs_config ve ilişkili yapı tanımlarını ( system/core/include/private/android_filesystem_config.h ) system/core/libcutils/fs_config.c ; burada bunlar /system/etc/fs_config_dirs yüklenen ikili dosyalar tarafından güncellenebilir veya geçersiz kılınabilir ve /system/etc/fs_config_files . Dizinler ve dosyalar için ayrı eşleştirme ve ayrıştırma kuralları kullanmak (ek glob ifadeleri kullanabilir), Android'in dizinleri ve dosyaları iki farklı tablodaki işlemesini sağladı. system/core/libcutils/fs_config.c yapı tanımları yalnızca dizinlerin ve dosyaların çalışma zamanı okumasına izin system/core/libcutils/fs_config.c kalmaz, aynı zamanda ana bilgisayar, derleme süresi boyunca dosya sistemi görüntülerini ${OUT}/system/etc/fs_config_dirs ve ${OUT}/system/etc/fs_config_files olarak oluşturmak için aynı dosyaları kullanabilir. ${OUT}/system/etc/fs_config_files .

Dosya sistemini genişletmenin geçersiz kılma yönteminin yerini Android 8.0'da sunulan modüler yapılandırma sistemi almış olsa da, yine de isterseniz eski yöntemi kullanabilirsiniz. Aşağıdaki bölümlerde, geçersiz kılma dosyalarının nasıl oluşturulup dahil edileceği ve dosya sisteminin nasıl yapılandırılacağı anlatılmaktadır.

Geçersiz kılma dosyaları oluşturma

/system/etc/fs_config_dirs ikili dosyaları /system/etc/fs_config_dirs ve /system/etc/fs_config_files , build/tools/fs_config içindeki fs_config_generate aracını kullanarak build/tools/fs_config . Araç, DAC gereksinimlerini bir arabelleğe yönetmek için bir libcutils kitaplık işlevi ( fs_config_generate() ) kullanır ve DAC kurallarını kurumsallaştırmak için bir içerme dosyası için kurallar tanımlar.

Kullanmak için device/ vendor / device /android_filesystem_config.h geçersiz kılma görevi gören bir dahil etme dosyası oluşturun. Dosya, dizin ve dosya sembolleri için aşağıdaki yapı başlatmalarıyla system/core/include/private/android_filesystem_config.h içinde tanımlanan structure fs_path_config biçimini kullanmalıdır:

  • Dizinler için android _device _dirs[] .
  • Dosyalar için android _device _files[] .

android_device_dirs[] ve android_device_files[] , NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS ve NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES tanımlayabilirsiniz (aşağıdaki örneğe bakın). Ayrıca, android_filesystem_config.h zorunlu bir taban adı ile kart yapılandırmasında TARGET_ANDROID_FILESYSTEM_CONFIG_H kullanarak geçersiz kılma dosyasını da belirtebilirsiniz.

Geçersiz kılma dosyaları dahil

Dosyaları dahil etmek için, PRODUCT_PACKAGES fs_config_dirs ve / veya fs_config_files içerdiğinden emin olun, böylece dosyaları fs_config_dirs /system/etc/fs_config_dirs ve /system/etc/fs_config_files . Derleme sistemi, BoardConfig.mk bulunduğu $(TARGET_DEVICE_DIR) BoardConfig.mk $(TARGET_DEVICE_DIR) içinde özel android_filesystem_config.h arar. Bu dosya başka bir yerde mevcutsa, tahta yapılandırma değişkenini TARGET_ANDROID_FILESYSTEM_CONFIG_H bu konumu TARGET_ANDROID_FILESYSTEM_CONFIG_H şekilde ayarlayın.

Dosya sistemini yapılandırma

Dosya sistemini Android 6.0 ve sonraki sürümlerde yapılandırmak için:

  1. $(TARGET_DEVICE_DIR)/android_filesystem_config.h dosyasını oluşturun.
  2. fs_config_dirs ve / veya fs_config_files dosyalarını pano yapılandırma dosyasındaki PRODUCT_PACKAGES fs_config_files (örneğin, $(TARGET_DEVICE_DIR)/device.mk ) $(TARGET_DEVICE_DIR)/device.mk ).

Örneği geçersiz kıl

Bu örnek, device/ vendor / device dizinine wake lock desteği eklemek için system/bin/glgps arka plan programının geçersiz system/bin/glgps yönelik bir yamayı gösterir. Aşağıdakileri aklınızda bulundurun:

  • Her yapı girişi mod, uid, gid, yetenekler ve addır. system/core/include/private/android_filesystem_config.h , bildirim # tanımlarını ( AID_ROOT , AID_SHELL , CAP_BLOCK_SUSPEND ) sağlamak için otomatik olarak CAP_BLOCK_SUSPEND .
  • android_device_files[] bölümü, belirtilmediğinde system/etc/fs_config_dirs erişimi engellemek için bir eylem içerir ve bu, dizin geçersiz kılmalar için içerik eksikliği için ek bir DAC koruması görevi görür. Ancak bu zayıf korumadır; Birinin /system üzerinde kontrolü varsa, genellikle istedikleri her şeyi yapabilir.
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)

Önceki sürümlerden dosya sistemlerini taşıma

Android 5.x ve önceki sürümlerden dosya sistemlerini taşırken, Android 6.x'in

  • Bazı dahil etme, yapı ve satır içi tanımları kaldırır.
  • Doğrudan system/core/include/private/android_filesystem_config.h çalıştırmak yerine libcutils referansı gerektirir. Dosya veya dizin yapıları veya fs_config için system/code/include/private_filesystem_config.h bağlı olan aygıt üreticisinin özel yürütülebilir dosyaları, libcutils kitaplık bağımlılıkları eklemelidir.
  • device/ vendor / device /android_filesystem_config.h taşımak için, mevcut hedeflerde ekstra içerik bulunan system/core/include/private/android_filesystem_config.h cihaz üreticisinin özel şube kopyalarını gerektirir.
  • SELinux Zorunlu Erişim Kontrollerini (MAC) hedef sistemdeki yapılandırma dosyalarına uygulama fs_config() kullanan özel hedef yürütülebilir dosyalar içeren uygulamalar erişim sağlamalıdır.