SELinux politikası yazma

Android Açık Kaynak Projesi (AOSP), tüm Android cihazlarda ortak olan uygulamalar ve hizmetler için sağlam bir temel politika sağlar. AOSP'ye katkıda bulunanlar bu politikayı düzenli olarak hassaslaştırır. Temel politikanın, cihaz üzerindeki nihai politikanın yaklaşık% 90-95'ini oluşturması ve cihaza özgü özelleştirmelerin kalan %5-10'u oluşturması beklenir. Bu makalede, cihaza özgü özelleştirmeler, cihaza özgü politikanın nasıl yazılacağı ve bu süreçte kaçınılması gereken bazı tuzaklar ele alınmaktadır.

Cihazı kullanıma sunma

Cihaza özel politika yazarken aşağıdaki adımları uygulayın.

İzin verilen modda çalıştırma

Bir cihaz izin verici modda olduğunda reddedilmeler günlüğe kaydedilir ancak uygulanmaz. İzin modu, iki nedenden dolayı önemlidir:

  • İzin verilen mod, politikanın etkinleştirilmesinin diğer erken cihaz etkinleştirme görevlerini geciktirmesini önler.
  • Zorunlu ret, diğer retleri maskeleyebilir. Örneğin, dosya erişimi genellikle bir dizin araması, dosya açma ve ardından dosya okuma işlemlerini içerir. Zorunlu kılma modunda yalnızca dizin araması reddedilir. İzin verici mod, tüm retlerin görülebilmesini sağlar.

Bir cihazı izin verilen moda geçirmenin en basit yolu çekirdek komut satırını kullanmaktır. Bu, cihazın BoardConfig.mk dosyasına eklenebilir: platform/device/<vendor>/<target>/BoardConfig.mk. Komut satırını değiştirdikten sonra make clean, ardından make bootimage'ü gerçekleştirin ve yeni önyükleme görüntüsünü yükleyin.

Ardından, izin verilen modu aşağıdakilerle onaylayın:

adb shell getenforce

Genel müsabaka modunda olmak için iki haftalık makul bir süre vardır. Retlerin çoğunu ele aldıktan sonra tekrar yaptırım moduna geçin ve ortaya çıkan hataları giderin. Hâlâ ret yanıtı veren alanlar veya yoğun geliştirme aşamasında olan hizmetler geçici olarak izin verilen moduna geçirilebilir ancak en kısa sürede yeniden zorunlu moduna geçirilmelidir.

Erken zorunlu kılma

Zorunlu modda, retler hem günlüğe kaydedilir hem de zorunlu kılınır. Cihazınızı mümkün olduğunca erken yaptırım moduna geçirmeniz önerilir. Cihaza özgü politikanın oluşturulup uygulanmasını beklemek, genellikle hatalı bir ürüne ve kötü bir kullanıcı deneyimine yol açar. Dogfooding'e katılmak ve gerçek kullanımda işlevselliğin tam test kapsamını sağlamak için yeterince erken başlayın. Erken başlamak, güvenlik endişelerinin tasarım kararlarını etkilemesini sağlar. Buna karşılık, yalnızca gözlemlenen retlere dayalı izinler vermek güvenli bir yaklaşım değildir. Bu süreyi, cihazda güvenlik denetimi gerçekleştirmek ve izin verilmemesi gereken davranışlara karşı hataları bildirmek için kullanın.

Mevcut politikayı kaldırma veya silme

Yeni bir cihazda sıfırdan cihaza özel politika oluşturmanın birkaç iyi nedeni vardır. Örneğin:

Temel hizmetlerle ilgili retleri ele alma

Temel hizmetler tarafından oluşturulan retler genellikle dosya etiketlemeyle ele alınır. Örnek:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

/dev/kgsl-3d0 doğru bir şekilde etiketlenerek tamamıyla ele alınır. Bu örnekte tcontext, device değeridir. Bu, daha spesifik bir etiket atanmadığı sürece /dev içindeki her şeyin " cihaz" etiketini aldığı varsayılan bağlamı temsil eder. Burada audit2allow'un çıktısını kabul etmek, yanlış ve aşırı izin verici bir kurala neden olur.

Bu tür sorunları çözmek için dosyaya daha spesifik bir etiket verin. Bu durumda etiket gpu_device olmalıdır. Temel politikada gpu_device'a erişmek için mediaserver'ın gerekli izinlere zaten sahip olması nedeniyle başka izinlere gerek yoktur.

Temel politikada önceden tanımlanmış türlerle etiketlenmesi gereken, cihaza özel diğer dosyalar:

Genel olarak varsayılan etiketlere izin vermek yanlıştır. Bu izinlerin çoğuna neverallow kuralları tarafından izin verilmez ancak açıkça izin verilmese bile en iyi uygulama, belirli bir etiket sağlamaktır.

Yeni hizmetleri etiketleme ve retleri ele alma

Init tarafından başlatılan hizmetlerin kendi SELinux alanlarında çalışması gerekir. Aşağıdaki örnekte, "foo" hizmeti kendi SELinux alanına yerleştirilir ve hizmete izinler verilir.

Hizmet, cihazımızın init.device.rc dosyasında şu şekilde başlatılır:

service foo /system/bin/foo
    class core
  1. "foo" adlı yeni bir alan oluşturun

    Aşağıdaki içeriklerle device/manufacturer/device-name/sepolicy/foo.te adlı dosyayı oluşturun:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    Bu, foo SELinux alanı için ilk şablondur. Yürütülebilir dosya tarafından gerçekleştirilen belirli işlemlere dayalı kurallar ekleyebilirsiniz.

  2. Etiket /system/bin/foo

    Aşağıdakileri device/manufacturer/device-name/sepolicy/file_contexts alanına ekleyin:

    /system/bin/foo   u:object_r:foo_exec:s0
    

    Bu işlem, yürütülebilir dosyanın doğru şekilde etiketlenmesini sağlar. Böylece SELinux, hizmeti uygun alanda çalıştırır.

  3. Başlatma ve sistem görüntülerini derleyip flaşlayın.
  4. Alan için SELinux kurallarını hassaslaştırın.

    Gerekli izinleri belirlemek için retleri kullanın. audit2allow aracı, iyi yönergeler sağlar ancak bu aracı yalnızca politika yazma sürecinde bilgi edinmek için kullanın. Yalnızca çıkışı kopyalamayın.

Zorunlu kılma moduna geri dön

İzin verici modda sorun giderebilirsiniz ancak mümkün olduğunca erken bir zamanda zorunlu moduna geri dönüp bu modda kalmaya çalışın.

Sık yapılan yanlışlar

Cihazlara özgü politikalar yazarken yapılan yaygın hatalara yönelik birkaç çözüm aşağıda verilmiştir.

Olumsuzlama ifadelerinin aşırı kullanımı

Aşağıdaki örnek kural, ön kapıyı kilitlemek ancak pencereleri açık bırakmaya benzer:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

Amaç açıktır: Üçüncü taraf uygulamaları dışındaki herkes hata ayıklama cihazına erişebilir.

Kural birkaç açıdan hatalıdır. Tüm uygulamalar isteğe bağlı olarak isolated_app alanında hizmetler çalıştırabileceğinden untrusted_app alanının hariç tutulması kolaydır. Benzer şekilde, AOSP'ye üçüncü taraf uygulamaları için yeni alanlar eklenirse bu uygulamalar da scary_debug_device'ye erişebilir. Kural çok fazla izin vermektedir. Çoğu alan, bu hata ayıklama aracına erişmekten yararlanamaz. Kural, yalnızca erişim gerektiren alanlara izin verecek şekilde yazılmış olmalıdır.

Üretimde hata ayıklama özellikleri

Hata ayıklama özellikleri ve politikaları üretim sürümlerinde bulunmamalıdır.

En basit alternatif, hata ayıklama özelliğine yalnızca SELinux'un adb root ve adb shell setenforce 0 gibi eng/userdebug derlemelerinde devre dışı bırakıldığı durumlarda izin vermektir.

Hata ayıklama izinlerini userdebug_or_eng ifadesine eklemek de güvenli bir alternatiftir.

Politika boyutunda patlama

Characterizing SEAndroid Policies in the Wild (Gerçek Hayatta SEAndroid Politikalarını Tanımlama) adlı makalede, cihaz politikası özelleştirmelerinin artmasıyla ilgili endişe verici bir trend açıklanmaktadır. Cihazlara özgü politika, bir cihazda çalışan genel politikanın% 5-10'unu oluşturmalıdır. %20'nin üzerindeki özelleştirmeler neredeyse kesinlikle ayrıcalıklı alanlar ve geçersiz politika içerir.

Gereksiz büyük politika:

  • Politika, RAM diskte yer aldığı ve çekirdek belleğine yüklendiği için belleğe iki kez isabet ettirilir.
  • Daha büyük bir önyükleme resmi gerektirerek disk alanını boşa harcar.
  • Çalışma zamanı politika arama sürelerini etkiler.

Aşağıdaki örnekte üreticiye özel politikanın, cihaz üzerinde politikanın% 50 ve% 40'ını oluşturduğu iki cihaz gösterilmektedir. Politikanın yeniden yazılması, aşağıda gösterildiği gibi işlevsellikte herhangi bir kayıp yaşanmadan önemli güvenlik iyileştirmeleri sağladı. (Karşılaştırma için Shamu ve Flounder AOSP cihazları dahil edilmiştir.)

Şekil 1: Güvenlik denetiminden sonra cihaza özgü politika boyutunun karşılaştırması.

Şekil 1. Güvenlik denetiminden sonra cihaza özgü politika boyutunun karşılaştırması.

Her iki durumda da politika hem boyut hem de izin sayısı açısından önemli ölçüde küçültülmüştür. Politika boyutundaki düşüş neredeyse tamamen gereksiz izinlerin kaldırılmasından kaynaklanmaktadır. Bu izinlerin çoğu, audit2allow tarafından oluşturulan ve politikaya gelişigüzel eklenen kurallardır. Her iki cihazda da ölü alanlar da sorun oluşturuyordu.

dac_override özelliğini ver

dac_override reddi, soruna neden olan işlemin bir dosyaya yanlış Unix kullanıcı/grup/herkese açık izinleriyle erişmeye çalıştığı anlamına gelir. Doğru çözüm, neredeyse hiçbir zaman dac_override iznini vermemektir. Bunun yerine dosya veya işlemdeki Unix izinlerini değiştirin. init, vold ve installd gibi birkaç alanın, diğer işlemlerin dosyalarına erişmek için Unix dosya izinlerini geçersiz kılma özelliğine gerçekten ihtiyacı vardır. Daha ayrıntılı bilgi için Dan Walsh'ın bloguna göz atın.