İsteğe bağlı erişim denetimi (DAC)

Derlemeye eklenen dosya sistemi nesneleri ve hizmetlerinin genellikle Android kimlikleri (AID'ler) olarak bilinen ayrı ve benzersiz kimliklere ihtiyacı vardır. Şu anda dosya ve hizmetler gibi birçok kaynak, temel (Android tarafından tanımlanan) AID'leri gereksiz yere kullanıyor. Birçok durumda bunun yerine OEM (OEM tarafından tanımlanan) AID'leri kullanabilirsiniz.

Android'in önceki sürümleri (Android 7.x ve önceki sürümler), dosya sistemi özelliklerini ve/veya özel OEM AID'lerini belirtmek için cihaza özgü bir android_filesystem_config.h dosyası kullanarak AID mekanizmasını genişletti. Ancak OEM AID'leri için güzel adların kullanılmasını desteklemediğinden bu sistem sezgisel değildi. Bu sistem, kullanıcı ve grup alanları için ham sayıları belirtmenizi gerektiriyordu. Bu sayıları, sayısal AID ile ilişkilendirmenin bir yolu yoktu.

Android'in daha yeni sürümleri (Android 8.0 ve sonraki sürümler), dosya sistemi özelliklerini genişletmek için yeni bir yöntemi destekler. Bu yeni yöntemde aşağıdakiler desteklenir:

  • Yapılandırma dosyaları için birden fazla kaynak konumu (genişletilebilir derleme yapılandırmalarını etkinleştirir).
  • OEM AID değerlerinin derleme zamanında doğruluk kontrolü.
  • Gerektiği gibi kaynak dosyalarda kullanılabilecek özel bir OEM AID başlığı oluşturma.
  • Kullanıcı dostu bir adın gerçek OEM AID değeriyle ilişkilendirilmesi. Kullanıcı ve grup için sayı olmayan dize bağımsız değişkenlerini destekler (ör. "2901" yerine "foo").

Ek iyileştirmeler arasında android_ids[] dizisinin system/core/libcutils/include/private/android_filesystem_config.h üzerinden kaldırılması yer alır. Bu dizi artık Bionic'te getpwnam() ve getgrnam() içeren erişim sağlayıcılarla birlikte tamamen özel olarak oluşturulmuş bir dizi olarak mevcuttur. (Bu, temel AID'ler değiştirildikçe kararlı ikili dosyalar oluşturmanın yan etkisine sahiptir.) Araçlar ve daha ayrıntılı bilgi içeren bir README dosyası için build/make/tools/fs_config adresine bakın.

Android kimlikleri (AID'ler) ekleme

Android 8.0, android_ids[] dizisini Android Açık Kaynak Projesi'nden (AOSP) kaldırdı. Bunun yerine, Bionic android_ids[] dizisi oluşturulurken tüm AID uyumlu adlar system/core/libcutils/include/private/android_filesystem_config.h başlığı dosyasından oluşturulur. define ile eşleşen tüm AID_*, araç tarafından alınır ve * küçük harfli ad olur.

Örneğin, private/android_filesystem_config.h dosyasında:

#define AID_SYSTEM 1000

Şu olur:

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

Yeni bir AOSP çekirdek AID'si eklemek için #define dosyasını android_filesystem_config.h başlık dosyasına eklemeniz yeterlidir. AID, derleme sırasında oluşturulur ve kullanıcı ile grup bağımsız değişkenlerini kullanan arayüzlere sunulur. Araç, yeni AID'nin APP veya OEM aralıkları içinde olmadığını doğrular. Ayrıca bu aralıklardaki değişikliklere de uyar ve değişiklikler veya yeni OEM tarafından ayrılmış aralıklar için otomatik olarak yeniden yapılandırmalıdır.

AID'leri yapılandırın

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

Kural olarak, yapılandırma dosyaları config.fs adını kullanır, ancak pratikte herhangi bir adı kullanabilirsiniz. config.fs dosyaları, Python ConfigParser ini biçiminde olup büyük harf bölümü (dosya sistemi özelliklerini yapılandırmak için) ve AID'ler bölümü (OEM AID'lerini yapılandırmak için) içerir.

Büyük harfleri büyük harflerle yazma bölümünü yapılandırma

Büyük harf bölümü, derlemedeki dosya sistemi nesnelerinde dosya sistemi özelliklerinin 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) hatasına neden olduğundan, bir işlemi veya hizmeti çalıştırırken özelliği korumaya yönelik önceki gereksinimler, özelliklerin ayarlanmasını ve ardından çalıştırılacak uygun bir AID için setuid/setgid kullanılmasını gerektiriyordu. Büyük harfleri kullanarak bu koşulları atlayabilir ve çekirdeğin sizin için yapmasını sağlayabilirsiniz. Kontrol main()'e devredildiğinde, süreciniz zaten ihtiyaç duyduğu özelliklere sahip olur. Böylece, hizmetiniz kök olmayan bir kullanıcı ve grup kullanabilir (imtiyazlı hizmetleri başlatmak için tercih edilen yöntem budur).

Sınırlar bölümünde aşağıdaki söz dizimi kullanılır:

Bölüm Değer Tanım
[path] Yapılandırılacak dosya sistemi yolu. / ile biten bir yol dizin olarak kabul edilir, aksi takdirde dosya olarak kabul edilir.

Farklı dosyalarda aynı [path] ile birden fazla bölüm belirtmek hatalıdır. Python'un <= 3.2 ve sonraki sürümlerinde aynı dosya, önceki bölümü geçersiz kılan bölümler içerebilir. Python 3.2'de ise bu dosya katı moda ayarlanmıştır.
mode Sekizli dosya modu En az 3 haneli geçerli bir sekizlik dosya modu. 3 belirtilirse önünde 0 eklenir. Aksi takdirde mod olduğu gibi kullanılır.
user AID_<kullanıcı> Geçerli bir AID için C define veya kolay ad (ör. hem AID_RADIO hem de radio kabul edilir). Özel AID tanımlamak için AID bölümünü yapılandırma başlıklı makaleyi inceleyin.
group AID_<group> Kullanıcıyla aynı.
caps cap* Başında CAP_ olmadan bionic/libc/kernel/uapi/linux/capability.h içinde belirtilen ad. Büyük/küçük harf kullanımına izin verilir. Caps'ler işlenmemiş de olabilir:
  • ikili (0b0101)
  • sekizlik (0455)
  • int (42)
  • onaltılık (0xFF)
Birden fazla büyük harf eklerseniz bunları boşluklarla ayırın.

Kullanım örneği için Dosya sistemi özelliklerini kullanma bölümüne bakın.

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

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

Bölüm Değer Tanım
[AID_<name>] <name>, büyük harf, sayı ve alt çizgi içerebilir. Dostluk adı olarak küçük harfli sürüm kullanılır. Kod eklemek için oluşturulan üst bilgi dosyası, tam AID_<name> öğesini kullanır.

Aynı AID_<name> ile birden fazla bölüm belirtmek hatalıdır ([path] ile aynı kısıtlamalara sahiptir ve büyük/küçük harf ayırımı yoktur).

<name>, farklı kaynaklarla çakışmadığından emin olmak için bir bölüm adıyla başlamalıdır.
value <number> Geçerli bir C stili sayı dizesi (onaltılık, sekizlik, ikilik ve ondalık).

Aynı değer seçeneğine sahip birden fazla bölüm belirtmek hatalıdır.

Değer seçenekleri, <name> öğesinde kullanılan bölümlendirmeye 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 içinde tanımlanır. Seçenekler şunlardır:
  • Tedarikçi 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 OEM AID adlarını tanımlama ve OEM AID'leri kullanma başlıklı makaleleri inceleyin.

Kullanım örnekleri

Aşağıdaki örneklerde, OEM AID'nin nasıl tanımlanacağı ve kullanılacağı, ayrıca dosya sistemi özelliklerinin nasıl etkinleştirileceği ayrıntılı olarak açıklanmıştır. OEM AID adları ([AID_name]), gelecekteki AOSP adları veya diğer bölümlerle çakışmaması için "vendor_" gibi bir bölüm adıyla başlamalıdır.

OEM AID adlarını tanımlayın

OEM AID'yi tanımlamak için bir config.fs dosyası oluşturun ve AID değerini ayarlayın. Örneğin, device/x/y/config.fs için 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 bu değişkene işaret edin. Örneğin, device/x/y/BoardConfig.mk bölümünde aşağıdakileri ayarlayın:

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

Özel AID'iniz artık yeni bir derlemede sistem tarafından geniş çapta kullanılabilir.

OEM AID'leri kullanma

OEM AID'i kullanmak için C kodunuzda ilişkili Makefile'inize oemaids_headers ekleyin ve #include "generated_oem_aid.h" ekleyin, ardından tanımlanan tanımlayıcıları kullanmaya başlayın. Örneğin, my_file.c alanına 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"],

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

LOCAL_HEADER_LIBRARIES := oemaids_headers

Kolay anlaşılır adlar kullanın

Android 9'da, AID adlarını destekleyen tüm arayüzlerde kolay ad kullanabilirsiniz. Örnek:

  • some/init.rc içindeki bir chown komutunda:
    chown vendor_foo /vendor/some/vendor_foo/file
    
  • some/init.rc içindeki bir service'te:
    service vendor_foo /vendor/bin/foo_service
        user vendor_foo
        group vendor_foo
    

Dostluk adı ile uid arasındaki dahili eşleme /vendor/etc/passwd ve /vendor/etc/group tarafından gerçekleştirildiğinden tedarikçi bölümü monte edilmelidir.

Kolay adları ilişkilendirme

Android 9, kullanıcı dostu bir adı gerçek OEM AID değeriyle ilişkilendirme desteği içerir. Kullanıcı ve grup için sayı olmayan dize bağımsız değişkenleri kullanabilirsiniz. Örneğin, "2901" yerine "vendor_foo".

AID'den kullanıcı dostu adlara dönüştürme

OEM AID'leri için Android 8.x, getpwnam ile aramaları işleyen yerlerde (init komut dosyaları gibi) getpwnam ve benzer işlevlerle birlikte oem_#### kullanılmasını gerektiriyordu. Android 9'da, Android kimliklerinden (AID'ler) uyumlu adlara (veya tam tersi) dönüştürme için Bionic'teki getpwnam ve getgrnam arkadaşlarınızı kullanabilirsiniz.

Dosya sistemi özelliklerini kullanma

Dosya sistemi özelliklerini 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 dosyasına 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 dosyasını BoardConfig.mk içindeki bu dosyaya işaret edecek şekilde ayarlayın. Örneğin, device/x/y/BoardConfig.mk bölümünde aşağıdakileri ayarlayın:

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

vendor_foo hizmeti yürütüldüğünde setuid ve setgid çağrıları olmadan CAP_SYS_ADMIN ve CAP_SYS_NICE özellikleriyle başlar. Ayrıca, vendor_foo hizmetinin SELinux politikası artık setuid ve setgid yeteneğine ihtiyaç duymadığından silinebilir.

Geçersiz kılma işlemlerini 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/etc/fs_config_dirs ve /system/etc/fs_config_files'e yüklenen ikili dosyalar tarafından güncellenebilmeleri veya geçersiz kılınabilmeleri için system/core/libcutils/fs_config.c'ye taşıdı. Dizinler ve dosyalar için ayrı eşleme ve ayrıştırma kuralları kullanmak (ek glob ifadeleri kullanabilir), Android'in dizinleri ve dosyaları iki farklı tabloda işlemesine olanak tanıdı. system/core/libcutils/fs_config.c'teki yapı tanımları, yalnızca dizinlerin ve dosyaların çalışma zamanında okunmasına izin vermedi. Ayrıca ana makine, ${OUT}/system/etc/fs_config_dirs ve ${OUT}/system/etc/fs_config_files gibi dosya sistemi görüntüleri oluşturmak için derleme sırasında aynı dosyaları kullanabilir.

Dosya sistemini genişletme için kullanılan geçersiz kılma yöntemi, Android 8.0'de kullanıma sunulan modüler yapılandırma sistemiyle değiştirilmiş olsa da dilerseniz eski yöntemi kullanmaya devam edebilirsiniz. Geçersiz kılma dosyalarının nasıl oluşturulacağı ve dahil edileceği ile dosya sisteminin nasıl yapılandırılacağı aşağıdaki bölümlerde ayrıntılı olarak açıklanmıştır.

Geçersiz kılma dosyaları oluşturma

build/tools/fs_config'daki fs_config_generate aracını kullanarak hizalanmış ikili dosyaları /system/etc/fs_config_dirs ve /system/etc/fs_config_files oluşturabilirsiniz. Araç, DAC şartlarını bir arabellekte 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 dahil etme dosyası kuralları tanımlar.

Kullanmak için device/vendor/device/android_filesystem_config.h bölümünde, geçersiz kılma işlevi gören bir dahil etme dosyası oluşturun. Dosya, dizin ve dosya simgeleri için aşağıdaki yapılandırma ilklendirmeleriyle birlikte 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[] simgesini kullanın.
  • Dosyalar için android_device_files[] simgesini kullanın.

android_device_dirs[] ve android_device_files[] kullanmıyorsanız NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS ve NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES'i tanımlayabilirsiniz (aşağıdaki örneğe bakın). Geçersiz kılma dosyasını, kart yapılandırmasında TARGET_ANDROID_FILESYSTEM_CONFIG_H temel adını kullanarak android_filesystem_config.h şeklinde de belirtebilirsiniz.

Geçersiz kılma dosyalarını dahil etme

Dosyaları dahil etmek için PRODUCT_PACKAGES'ün /system/etc/fs_config_dirs ve /system/etc/fs_config_files'e yükleyebilmesi amacıyla fs_config_dirs ve/veya fs_config_files'yi içerdiğinden emin olun. Derleme sistemi, BoardConfig.mk'nin bulunduğu $(TARGET_DEVICE_DIR) içinde özel android_filesystem_config.h'yi arar. Bu dosya başka bir yerdeyse pano yapılandırması değişkenini TARGET_ANDROID_FILESYSTEM_CONFIG_H ilgili konuma işaret edecek şekilde ayarlayın.

Dosya sistemini yapılandırma

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

  1. $(TARGET_DEVICE_DIR)/android_filesystem_config.h dosyasını oluşturun.
  2. Jamboard yapılandırma dosyasındaki PRODUCT_PACKAGES öğesine fs_config_dirs ve/veya fs_config_files ekleyin (ör. $(TARGET_DEVICE_DIR)/device.mk) bilgileri gösterilir.

Geçersiz kılma örneği

Bu örnekte, device/vendor/device dizininde uyanma kilidi desteği eklemek için system/bin/glgps iblisinin geçersiz kılınmasına yönelik bir yama gösterilmektedir. Aşağıdakileri göz önünde bulundurun:

  • Her yapı girişi; mod, uid, gid, özellikler ve addan oluşur. system/core/include/private/android_filesystem_config.h, manifest #defines öğesini (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND) sağlamak için otomatik olarak eklenir.
  • android_device_files[] bölümünde, belirtilmediği takdirde system/etc/fs_config_dirs'a erişimi engelleyen bir işlem bulunur. Bu işlem, dizin geçersiz kılma işlemleri için içerik eksikliği nedeniyle ek bir DAC koruması görevi görür. Ancak bu koruma yöntemi zayıftır. /system üzerinde kontrol sahibi olan bir kullanıcı genellikle istediği 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 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)

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

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

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