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

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

Android'in önceki sürümlerinde (Android 7.x ve daha eski sürümler) dosya sistemi özelliklerini ve/veya özel OEM AID'lerini belirtmek için cihaza özel bir android_filesystem_config.h dosyası kullanılarak AID mekanizması genişletilmişti. Ancak bu sistem, OEM AID'leri için kolay adların kullanılmasını desteklemediğinden sezgisel değildi. Kullanıcı ve grup alanları için sayısal AID ile kolay ad ilişkilendirme yolu olmadan ham sayısal değeri belirtmeniz gerekiyordu.

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öntem aşağıdakileri destekler:

  • 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 uygunluk kontrolü.
  • Kaynak dosyalarında gerektiği gibi kullanılabilecek özel bir OEM AID başlığı oluşturma.
  • Kolay adın gerçek OEM AID değeriyle ilişkilendirilmesi. Kullanıcı ve grup için sayısal olmayan dize bağımsız değişkenlerini destekler. Örneğin, "2901" yerine "foo".

Ek iyileştirmeler arasında android_ids[] dizisinin system/core/libcutils/include/private/android_filesystem_config.h öğesinden kaldırılması yer alır. Bu dizi artık Bionic'te tamamen özel olarak oluşturulmuş bir dizi olarak bulunuyor ve getpwnam() ile getgrnam() erişimcileri içeriyor. (Bu, temel AID'ler değiştirildiği için kararlı ikili dosyalar üretme yan etkisine sahiptir.) Araçlar ve daha ayrıntılı bilgi içeren bir BENİOKU dosyası için build/make/tools/fs_config bölümüne 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 dostu adlar system/core/libcutils/include/private/android_filesystem_config.h başlık dosyasından oluşturulur. Herhangi bir define eşleşme AID_* araç tarafından alınır ve * küçük harfli ad olur.

Örneğin, private/android_filesystem_config.h:

#define AID_SYSTEM 1000

Şu olur:

  • Kolay ad: system
  • uid: 1000
  • gid: 1000

Yeni bir AOSP çekirdek AID'si eklemek için #define öğesini android_filesystem_config.h üstbilgi dosyasına eklemeniz yeterlidir. AID, derleme sırasında oluşturulur ve kullanıcı ile grup bağımsız değişkenlerini kullanan arayüzlerde kullanılabilir. Araç, yeni AID'nin APP veya OEM aralıklarında olmadığını doğrular. Ayrıca bu aralıklarda yapılan değişikliklere uyar ve değişiklikler veya yeni OEM'ye ayrılmış aralıklar olduğunda otomatik olarak yeniden yapılandırılmalıdır.

AID'leri yapılandırma

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

Yapılandırma dosyaları, kural olarak config.fs adını kullanır ancak pratikte istediğiniz adı kullanabilirsiniz. config.fs dosyaları Python ConfigParser ini biçimindedir ve dosya sistemi yeteneklerini yapılandırmak için bir üst karakter bölümü, OEM AID'lerini yapılandırmak için ise bir AID bölümü içerir.

Sınırlar bölümünü yapılandırma

Caps bölümü, derleme içindeki dosya sistemi nesnelerinde dosya sistemi yeteneklerinin ayarlanmasını destekler (dosya sisteminin kendisi de bu işlevi desteklemelidir).

Android'de kararlı bir hizmeti kök olarak çalıştırmak Compatibility Test Suite (CTS) hatasına neden olduğundan, bir işlemi veya hizmeti çalıştırırken özelliği korumak için önceki şartlar, özellikleri ayarlamayı ve ardından çalıştırmak için uygun bir AID'ye setuid/setgid kullanmayı içeriyordu. Sınırlamalar sayesinde bu koşulları atlayabilir ve çekirdeğin sizin için yapmasını sağlayabilirsiniz. Denetim main()'ya devredildiğinde, işleminiz hizmetinizin kök olmayan bir kullanıcı ve grup kullanabilmesi için gereken özelliklere zaten sahiptir (bu, ayrıcalıklı hizmetleri başlatmanın tercih edilen yoludur).

Sınırlar bölümünde şu 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 hatadır. Python'ın 3.2 ve önceki sürümlerinde aynı dosya, önceki bölümü geçersiz kılan bölümler içerebilir. Python 3.2'de ise bu özellik katı moda ayarlanmıştır.
mode Sekizlik dosya modu En az 3 haneli geçerli bir sekizlik dosya modu. 3 belirtilirse başına 0 eklenir, aksi takdirde mod olduğu gibi kullanılır.
user AID_<user> Geçerli bir AID için C define veya kolay ad (ör. hem AID_RADIO hem de radio kabul edilebilir). Özel bir AID tanımlamak için AID bölümünü yapılandırma başlıklı makaleye bakın.
group AID_<group> Kullanıcıyla aynıdır.
caps cap* Ad, bionic/libc/kernel/uapi/linux/capability.h içinde belirtildiği şekilde ve başında CAP_ olmadan. Büyük/küçük harf karışımına izin verilir. Caps'ler ayrıca ham:
  • ikili (0b0101)
  • sekizlik (0455)
  • int (42)
  • onaltılık (0xFF)
Birden fazla büyük harf kullanıyorsanız bunları boşlukla ayırın.

Kullanım örneği için Dosya sistemi özelliklerini kullanma başlıklı makaleyi inceleyin.

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

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, rakam ve alt çizgi karakterlerini içerebilir. Küçük harfli sürüm, kolay ad olarak kullanılır. Kod ekleme için oluşturulan başlık dosyası, tam olarak AID_<name>.

Aynı AID_<name> ile birden fazla bölüm belirtmek hatadır ([path] ile aynı kısıtlamalarla büyük/küçük harf duyarsızdır).

<name>, farklı kaynaklarla çakışmaması 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 hatadır.

Değer seçenekleri, <name> içinde kullanılan bölüme karşılık gelen aralıkta belirtilmelidir. Geçerli bölümlerin ve bunlara karşılık gelen aralıkların listesi 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 Partition
    • 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, bir OEM AID'nin nasıl tanımlanacağı ve kullanılacağı ile dosya sistemi özelliklerinin nasıl etkinleştirileceği ayrıntılı olarak açıklanmaktadır. OEM AID adları ([AID_name]), gelecekteki AOSP adlarıyla veya diğer bölümlerle çakışmamaları 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 config.fs dosyası oluşturun ve AID değerini ayarlayın. Örneğin, device/x/y/config.fs içinde 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 içinde aşağıdakileri ayarlayın:

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

Özel AID'niz artık yeni bir derlemede sistemin tamamı tarafından kullanılabilir.

OEM AIDs'yi kullanma

Bir OEM AID kullanmak için C kodunuzda ilişkili Makefile'inize oemaids_headers ekleyin ve #include "generated_oem_aid.h" ekleyin, ardından bildirilen tanımlayıcıları kullanmaya başlayın. Örneğin, my_file.c bölümüne 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

Kullanıcı dostu adlar kullanma

Android 9'da, AID adlarını destekleyen tüm arayüzler için kolay adı kullanabilirsiniz. Örneğin:

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

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

Kolay adları ilişkilendirme

Android 9, gerçek OEM AID değeriyle kolay ad ilişkilendirmeyi destekler. Kullanıcı ve grup için sayısal olmayan dize bağımsız değişkenleri kullanabilirsiniz. Örneğin, "2901" yerine "vendor_foo" kullanabilirsiniz.

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

OEM AID'leri için Android 8.x, oem_#### ile getpwnam ve benzer işlevlerin yanı sıra getpwnam ile aramaları işleyen yerlerde (ör. init komut dosyaları) kullanılmasını gerektiriyordu. Android 9'da, Android kimliklerinden (AID) kolay adlara ve tam tersi yönde dönüştürme yapmak için Bionic'teki getpwnam ve getgrnam arkadaşlarını kullanabilirsiniz.

Dosya sistemi özelliklerini kullanma

Dosya sistemi yeteneklerini etkinleştirmek için config.fs dosyasında bir üst karakter 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 öğesini BoardConfig.mk içindeki bu dosyayı gösterecek şekilde ayarlayın. Örneğin, device/x/y/BoardConfig.mk içinde aşağıdakileri ayarlayın:

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

vendor_foo hizmeti yürütüldüğünde CAP_SYS_ADMIN ve CAP_SYS_NICE yetenekleriyle başlar. setuid ve setgid çağrıları yapılmaz. Ayrıca, vendor_foo hizmetinin SELinux politikasının artık setuid ve setgid yeteneğine ihtiyacı yoktur 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 konumuna taşıdı. Bu konumda, /system/etc/fs_config_dirs ve /system/etc/fs_config_files konumlarına yüklenen ikili dosyalarla güncellenebilir veya geçersiz kılınabilirler. Dizinler ve dosyalar için ayrı eşleştirme ve ayrıştırma kuralları (ek glob ifadeleri kullanabilir) kullanıldığında Android, dizinleri ve dosyaları iki farklı tabloda işleyebiliyordu. system/core/libcutils/fs_config.c içindeki yapı tanımları yalnızca dizinlerin ve dosyaların çalışma zamanında okunmasına izin vermekle kalmaz, aynı zamanda ana makine, dosya sistemi görüntülerini ${OUT}/system/etc/fs_config_dirs ve ${OUT}/system/etc/fs_config_files olarak oluşturmak için derleme zamanında aynı dosyaları kullanabilir.

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

Geçersiz kılma dosyaları oluşturma

/system/etc/fs_config_dirs ve /system/etc/fs_config_files hizalanmış ikili dosyalarını build/tools/fs_config'deki fs_config_generate aracını kullanarak oluşturabilirsiniz. Araç, DAC gereksinimlerini bir arabellekte yönetmek için libcutils kitaplık işlevini (fs_config_generate()) kullanır ve DAC kurallarını kurumsallaştırmak için bir dahil etme dosyasına yönelik kurallar tanımlar.

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

  • Dizinler için android_device_dirs[] yönergesini kullanın.
  • Dosyalar için android_device_files[] simgesini kullanın.

android_device_dirs[] ve android_device_files[] öğelerini kullanmadığınızda NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS ve NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES öğelerini tanımlayabilirsiniz (aşağıdaki örneğe bakın). Ayrıca, kart yapılandırmasında TARGET_ANDROID_FILESYSTEM_CONFIG_H kullanarak geçersiz kılma dosyasını da belirtebilirsiniz. Bu durumda, temel dosya adı android_filesystem_config.h olarak zorunlu kılınır.

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

Dosyaları dahil etmek için PRODUCT_PACKAGES'nın fs_config_dirs ve/veya fs_config_files içerdiğinden emin olun. Böylece dosyalar sırasıyla /system/etc/fs_config_dirs ve /system/etc/fs_config_files'ye yüklenebilir. Derleme sistemi, android_filesystem_config.h özelini $(TARGET_DEVICE_DIR) içinde arar. Burada BoardConfig.mk mevcuttur. Bu dosya başka bir yerde varsa TARGET_ANDROID_FILESYSTEM_CONFIG_H kart yapılandırma değişkenini bu konuma yönlendirecek ş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. fs_config_dirs ve/veya fs_config_files öğelerini kart yapılandırma dosyasındaki PRODUCT_PACKAGES öğesine ekleyin (ör. $(TARGET_DEVICE_DIR)/device.mk).

Geçersiz kılma örneği

Bu örnekte, system/bin/glgps daemon'ını geçersiz kılmak için bir yama gösterilmektedir. Bu yama, device/vendor/device dizinine uyandırma kilidi desteği ekler. Aşağıdakileri göz önünde bulundurun:

  • Her yapı girişi; mod, uid, gid, özellikler ve addır. system/core/include/private/android_filesystem_config.h, manifest #define'larını (AID_ROOT, AID_SHELL, CAP_BLOCK_SUSPEND) sağlamak için otomatik olarak eklenir.
  • android_device_files[] bölümü, belirtilmediğinde system/etc/fs_config_dirs'e erişimi engelleme işlemini içerir. Bu işlem, dizin geçersiz kılmaları için içerik eksikliğine karşı ek bir DAC koruması sağlar. Ancak bu zayıf bir korumadır. Bir kullanıcı /system üzerinde kontrol sahibiyse 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)

Dosya sistemlerini önceki sürümlerden taşıma

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

  • Bazı include'ları, yapıları ve satır içi tanımları kaldırır.
  • system/core/include/private/android_filesystem_config.h üzerinden doğrudan çalıştırmak yerine libcutils referansı gerektirir. Dosya veya dizin yapıları için system/code/include/private_filesystem_config.h'ya ya da fs_config'ya bağlı olan cihaz üreticisine ait özel yürütülebilir dosyalar libcutils kitaplık bağımlılıklarını eklemelidir.
  • system/core/include/private/android_filesystem_config.h ile device/vendor/device/android_filesystem_config.h'ye geçmek için cihaz üreticisinin mevcut hedeflerdeki ekstra içeriklerle birlikte system/core/include/private/android_filesystem_config.h'nın özel şube kopyalarını sağlaması gerekir.
  • Hedef sistemdeki yapılandırma dosyalarına SELinux Zorunlu Erişim Kontrolleri (MAC) uygulama hakkını saklı tutar. fs_config() kullanan özel hedef yürütülebilir dosyalarını içeren uygulamalar erişimi sağlamalıdır.