SELinux'u doğrulayın

Android, OEM'lerin SELinux uygulamalarını ayrıntılı bir şekilde test etmelerini önemle tavsiye eder. Üreticiler SELinux'u uyguladıkça yeni test amaçlı bir cihaz havuzuna eklemeniz gerekir.

Yeni bir politika uyguladıktan sonra getenforce komutunu vererek SELinux'un cihazda doğru modda çalıştığından emin olun.

Bu komut, genel SELinux modunu (Zorunlu veya İzin Veren) yazdırır. Her alanın SELinux modunu belirlemek için ilgili dosyaları incelemeniz veya sepolicy-analyze'ın en son sürümünü /platform/system/sepolicy/tools/'da bulunan uygun (-p) işaretiyle çalıştırmanız gerekir.

Reddedilenleri oku

dmesg ve logcat'e etkinlik günlükleri olarak yönlendirilen ve cihazda yerel olarak görüntülenebilen hataları kontrol edin. Üreticiler, bu cihazlarda SELinux çıkışını dmesg olarak inceleyip herkese açık sürümden önce izin verici modda ayarları hassaslaştırıp zorunlu moduna geçmelidir. SELinux günlük mesajları avc: içerdiğinden grep ile kolayca bulunabilir. Devam etmekte olan cat /proc/kmsg çalıştırarak ret günlüklerini çalıştırın veya ret günlüklerini yakalayın. önceki başlatıldıktan sonra cat /sys/fs/pstore/console-ramoops.

SELinux hata mesajları, bataklıktan kaçınmak için önyükleme tamamlandıktan sonra hız sınırlaması yapar günlükler. Alakalı tüm mesajları gördüğünüzden emin olmak için adb shell auditctl -r 0'ü çalıştırarak bu özelliği devre dışı bırakabilirsiniz.

Bu çıkış sayesinde üreticiler, sistem kullanıcılarının veya bileşenlerinin SELinux politikasını ne zaman ihlal ettiğini kolayca belirleyebilir. Üreticiler daha sonra yazılımda, SELinux politikasında veya her ikisinde de değişiklik yaparak bu kötü davranışı düzeltebilir.

Özellikle, bu günlük mesajları hakkında daha fazla bilgi edineceksiniz. Örnek:

avc: denied  { connectto } for  pid=2671 comm="ping" path="/dev/socket/dnsproxyd"
scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket

Bu çıkışı şu şekilde yorumlayın:

  • Yukarıdaki { connectto }, yapılan işlemi temsil eder. Sonda tclass (unix_stream_socket), kabaca ne yapıldığını anlatıyor neye benzetebiliriz. Bu durumda, bir unix akış yuvasına bağlanmaya çalışılıyordu.
  • scontext (u:r:shell:s0), işlemin hangi bağlamda başlatıldığını belirtir. İçinde bu, kabuk olarak çalışan bir şeydir.
  • tcontext (u:r:netd:s0), işlemin hedefinin bağlamını belirtir. Bu durumda, netd tarafından sahip olunan bir unix_stream_socket olur.
  • En üstteki comm="ping" gösterilen şey hakkında ek bilgi verir. ret işleminin oluşturulduğu anda çalışır. Bu durumda oldukça iyi bir ipucu.

Başka bir örnek:

adb shell su root dmesg | grep 'avc: '

Ses çıkışı:

<5> type=1400 audit: avc:  denied  { read write } for  pid=177
comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0
tcontext=u:object_r:kmem_device:s0 tclass=chr_file

Bu reddin temel unsurları şunlardır:

  • İşlem: Yapılmak istenen işlem köşeli parantez içinde vurgulanır read write veya setenforce.
  • Aktör: scontext (kaynak bağlamı) girişi, bu durumda rmt_storage daemon'ı temsil eden aktörü belirtir.
  • Nesne: tcontext (hedef bağlam) girişi, (bu örnekte kmem).
  • Sonuç: tclass (hedef sınıf) girişi, türü belirtir bu örnekte bir chr_file (karakter cihazı).

Kullanıcı ve çekirdek yığınlarının dökümünü al

Bazı durumlarda, olay günlüğünde yer alan bilgiler, reddinin kaynağını gösterir. Reddetmenin nedenini daha iyi anlamak için genellikle çekirdek ve kullanıcı alanı da dahil olmak üzere çağrı zincirini toplamak yararlıdır.

Son çekirdekler avc:selinux_audited adlı bir izleme noktası tanımlar. Android kullan Bu izleme noktasını etkinleştirmek ve çağrı zincirini yakalamak için simpleperf tuşlarına basın.

Desteklenen yapılandırma

  • Özellikle Android Ortak Çekirdeği şu şubeleri olmak üzere mainline ve android12-5.10 dahil olmak üzere 5.10 ve üzeri sürümlerin Linux çekirdeği desteklenir. android12-5.4 şube de destekleniyor. İzleme noktasının cihazınızda tanımlanıp tanımlanmadığını belirlemek için simpleperf'ü kullanabilirsiniz: adb root && adb shell simpleperf list | grep avc:selinux_audited. Diğer çekirdek sürümlerinde dd81662 ve 30969bc.
  • Hata ayıklamakta olduğunuz etkinliği yeniden oluşturabilirsiniz. Başlatma süresi etkinlikleri Simpleperf kullanılarak desteklenir. ancak yine de tetiklemek için hizmeti yeniden başlatabilirsiniz. etkinliği tıklayın.

Çağrı zincirini yakalama

İlk adım, etkinliği simpleperf record kullanarak kaydetmektir:

adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"

Ardından, ret işlemine neden olan etkinlik tetiklenir. Bundan sonra kayıt durdurulabilir. Bu örnekte, Ctrl-c kullanılarak örnek yakalanmış olmalıdır:

^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.

Son olarak, simpleperf report, yakalanan yığın izlemeyi incelemek için kullanılabilir. Örneğin:

adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph"
[...]
Children  Self     Command  Pid   Tid   Shared Object                                   Symbol
100.00%   0.00%    dmesg    3318  3318  /apex/com.android.runtime/lib64/bionic/libc.so  __libc_init
       |
       -- __libc_init
          |
           -- main
              toybox_main
              toy_exec_which
              dmesg_main
              klogctl
              entry_SYSCALL_64_after_hwframe
              do_syscall_64
              __x64_sys_syslog
              do_syslog
              selinux_syslog
              slow_avc_audit
              common_lsm_audit
              avc_audit_post_callback
              avc_audit_post_callback

Yukarıdaki çağrı zinciri, birleştirilmiş çekirdek ve kullanıcı alanı çağrı zinciridir. Bu sayede daha iyi önce kullanıcı alanından çekirdeğe kadar başlayarak kod akışının bir görünümünü sunar. kullanıcı ret işlemi gerçekleşir. simpleperf hakkında daha fazla bilgi için Simpleperf yürütülebilir komutları referansı başlıklı makaleyi inceleyin.

İzin verici ayarlara geçiş yapın

SELinux'u zorunlu kılma, userdebug veya eng derlemelerinde adb ile devre dışı bırakılabilir. Bunun için önce adb root komutunu çalıştırarak ADB'yi root'a geçirin. Ardından, SELinux'u devre dışı bırakmak için yaptırım, çalıştırma:

adb shell setenforce 0

Veya çekirdek komut satırında (cihazın ilk başlatılması sırasında):

androidboot.selinux=permissive
androidboot.selinux=enforcing

Alternatif olarak Android 12'deki bootconfig üzerinden de yapabilirsiniz:

androidboot.selinux=permissive
androidboot.selinux=enforcing

audit2allow'u kullanma

audit2allow aracı, dmesg retlerini alır ve bunları ilgili SELinux politika beyanlarına dönüştürür. Dolayısıyla, hızlandırdı.

Bu özelliği kullanmak için şu komutu çalıştırın:

adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy

Bununla birlikte, her potansiyel eklemenin izinleri aşma açısından incelenmesi gerekir. Örneğin, audit2allow adlı kullanıcıya Daha önce gösterilen rmt_storage reddi şu sonucu verir: önerilen SELinux politika ifadesi:

#============= shell ==============
allow shell kernel:security setenforce;
#============= rmt ==============
allow rmt kmem_device:chr_file { read write };

Bu, rmt'e çekirdek belleğine yazma yetkisi verir. Bu da bariz bir güvenlik açığıdır. audit2allow ifadeleri genellikle yalnızca bir bir başlangıç noktası olabilir. Bu ifadeleri kullandıktan sonra, iyi bir politikaya ulaşmak için kaynak alanını ve hedefin etiketini değiştirmenizin yanı sıra uygun makrolar eklemeniz gerekebilir. Bazen incelenmekte olan ret kararı hiçbir politika değişikliğine neden olmadı. bunun yerine rahatsız edici uygulamayı değiştirilmelidir.