SELinux validieren

Android empfiehlt OEMs dringend, ihre SELinux-Implementierungen zu testen. gründlich. Wenn Hersteller SELinux implementieren, sollten sie das neue für einen Testpool von Geräten festlegen.

Nachdem Sie eine neue Richtlinie angewendet haben, stellen Sie sicher, dass SELinux im richtigen auf dem Gerät mit dem Befehl getenforce.

Damit wird der globale SELinux-Modus ausgegeben: entweder „Erzwingen“ oder „Moderat“. Bis den SELinux-Modus für jede Domain ermitteln, müssen Sie die entsprechenden -Dateien oder die neueste Version von sepolicy-analyze mit dem entsprechende Markierung (-p), vorhanden in <ph type="x-smartling-placeholder"></ph> /platform/system/sepolicy/tools/.

Leseverweigerungen

Auf Fehler prüfen, die als Ereignislogs an dmesg weitergeleitet werden und logcat und sind lokal auf dem Gerät sichtbar. Hersteller sollte die SELinux-Ausgabe für dmesg auf diesen Geräten untersuchen und Verfeinern der Einstellungen vor der Veröffentlichung im Modus „Weniger strikt“ und bei einem möglichen Wechsel in den Erzwingungsmodus wechseln. SELinux-Logmeldungen enthalten avc: und somit mit grep leicht gefunden werden. Es ist möglich, die laufenden Ablehnungslogs durch Ausführen von cat /proc/kmsg oder Erfassen von Ablehnungslogs aus dem vorherigen Bootvorgang, indem Sie cat /sys/fs/pstore/console-ramoops.

SELinux-Fehlermeldungen sind nach Abschluss des Bootvorgangs begrenzt, um Swamping zu vermeiden. die Protokolle. Um sicherzustellen, dass Sie alle relevanten Nachrichten sehen, können Sie diese Option deaktivieren mit adb shell auditctl -r 0.

Anhand dieser Ausgabe können Hersteller sofort erkennen, Komponenten verstoßen gegen die SELinux-Richtlinie. Hersteller können dann dieses unerwünschte Verhalten, entweder durch Änderungen an der Software und/oder die SELinux-Richtlinie.

Diese Logeinträge geben insbesondere an, bei welchen Prozessen und die Gründe dafür. Hier ein Beispiel:

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

Interpretieren Sie diese Ausgabe so:

  • { connectto } steht für die durchgeführte Aktion. Zusammen mit den tclass am Ende (unix_stream_socket), sehen Sie, was in etwa was zu tun ist. In diesem Fall wurde versucht, eine Verbindung zu einem Unix-Stream-Socket herzustellen.
  • scontext (u:r:shell:s0) gibt an, welcher Kontext die Aktion ausgelöst hat. In In diesem Fall wird das als Shell ausgeführt.
  • tcontext (u:r:netd:s0) gibt den Kontext des Ziels der Aktion an. In in diesem Fall ein Unix_stream_Socket von netd.
  • Das comm="ping" ganz oben gibt Ihnen einen zusätzlichen Hinweis darauf, was gerade angezeigt wurde. ausgeführt wurde, als die Ablehnung generiert wurde. In diesem Fall ist das ein ziemlich guter Hinweis.

Ein weiteres Beispiel:

adb shell su root dmesg | grep 'avc: '

Ausgabe:

<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

Hier sind die wichtigsten Elemente dieser Ablehnung:

  • Aktion: Die gewünschte Aktion ist in Klammern markiert. read write oder setenforce.
  • Akteur: Der Eintrag scontext (Quellkontext) steht für den Akteur, in diesem Fall den Daemon rmt_storage.
  • Objekt: Der Eintrag tcontext (Zielkontext) steht für das Objekt, auf das reagiert wird, in diesem Fall "kmem".
  • Ergebnis: Der Eintrag tclass (Zielklasse) gibt den Typ an. des Objekts, auf das reagiert wird, in diesem Fall chr_file (Zeichengerät).

Dumping von Nutzer- und Kernel-Stacks

In einigen Fällen reichen die Informationen im Ereignisprotokoll nicht aus, um den Ursprung der Ablehnung. Es ist oft nützlich, die Aufrufkette, einschließlich Kernel und um die Gründe für die Ablehnung besser zu verstehen.

Aktuelle Kernel definieren einen Tracepoint mit dem Namen avc:selinux_audited. Android verwenden simpleperf, um diesen Tracepoint zu aktivieren und die Aufrufkette zu erfassen.

Unterstützte Konfiguration

  • Linux-Kernel >= 5.10, insbesondere Android Common Kernel-Zweige Mainline und android12–5.10 unterstützt werden. android12-5.4 Branch ebenfalls unterstützt. Mit simpleperf können Sie feststellen, ob der Tracepoint wie auf Ihrem Gerät definiert: adb root && adb shell simpleperf list | grep avc:selinux_audited. Bei anderen Kernel-Versionen können Sie Commits separat auswählen. dd81662 und 30969bc.
  • Es sollte möglich sein, das Ereignis zu reproduzieren, für das Sie eine Fehlerbehebung durchführen. Startzeitereignisse sind nicht unterstützt mit simpleperf; Sie können den Dienst aber möglicherweise neu starten, über den Termin.

Anrufkette erfassen

Der erste Schritt besteht darin, das Ereignis mit simpleperf record aufzuzeichnen:

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

Dann sollte das Ereignis ausgelöst werden, das die Ablehnung verursacht hat. Danach sollte die Aufzeichnung dass sie gestoppt werden. In diesem Beispiel sollte die Stichprobe durch die Verwendung von Ctrl-c erfasst worden sein:

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

Schließlich kann simpleperf report verwendet werden, um den erfassten Stacktrace zu prüfen. Beispiel:

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

Die obige Aufrufkette ist eine einheitliche Kernel- und Userspace-Aufrufkette. Sie erhalten eine bessere des Codeflusses ansehen, indem wir das Trace vom Userspace bis zum Kernel starten, die Leugnung passiert. Weitere Informationen zu simpleperf finden Sie in der Referenz zu ausführbaren Simpleperf-Befehlen

Zu moderaten Einstellungen wechseln

Die SELinux-Erzwingung kann bei UserDebug- oder Engine-Builds über ADB deaktiviert werden. Gehen Sie dazu wie folgt vor: Wechsle zuerst ADB zum Root, indem du adb root ausführst. Um SELinux zu deaktivieren, Erzwingung, führen Sie Folgendes aus:

adb shell setenforce 0

Oder an der Kernel-Befehlszeile (während der ersten Geräteeinführung):

androidboot.selinux=permissive
androidboot.selinux=enforcing

Oder über bootconfig in Android 12:

androidboot.selinux=permissive
androidboot.selinux=enforcing

Audit2allow verwenden

<ph type="x-smartling-placeholder">

Das audit2allow-Tool nimmt dmesg Ablehnungen und wandelt sie in entsprechende SELinux-Richtlinienanweisungen um. Daher kann es die SELinux-Entwicklung erheblich zu beschleunigen.

Führen Sie folgenden Befehl aus, um sie zu verwenden:

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

Dennoch muss jede mögliche Ergänzung für zu viele Berechtigungen. Wenn Sie z. B. audit2allow mit dem Die vorherige Ablehnung von rmt_storage führt zu folgendem Ergebnis: vorgeschlagene SELinux-Richtlinienanweisung:

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

Dies würde rmt die Möglichkeit geben, Kernel-Arbeitsspeicher, einen eine Blendenöffnung. Häufig sind die audit2allow-Anweisungen nur eine Ausgangspunkt ist. Nachdem Sie diese Anweisungen verwendet haben, müssen Sie möglicherweise die Methode Quelldomain und das Label des Ziels sowie die korrekten um zu einer guten Richtlinie zu gelangen. Manchmal sollte die zu prüfende Ablehnung keinerlei Richtlinienänderungen zur Folge haben. und nicht auf die problematische Anwendung geändert werden sollte.