Android incoraggia vivamente gli OEM a testare le proprie implementazioni SELinux in modo approfondito. Quando i produttori implementano SELinux, devono applicare il nuovo a un pool di dispositivi di test.
Dopo aver applicato un nuovo criterio, assicurati che SELinux sia in esecuzione con il
sul dispositivo inviando il comando getenforce
.
Viene visualizzata la modalità SELinux globale: Enforcing o Permissive (Applicabile). A
determinare la modalità SELinux per ciascun dominio, è necessario esaminare le
o esegui l'ultima versione di sepolicy-analyze
con
flag appropriato (-p
), presente in
.
/platform/system/sepolicy/tools/
Lettura dei rifiuti
Verifica la presenza di errori, che vengono indirizzati come log eventi a dmesg
e logcat
e sono visualizzabili localmente sul dispositivo. Produttori
esaminare l'output SELinux su dmesg
su questi dispositivi e
perfeziona le impostazioni prima della release pubblica in modalità permissiva ed eventuale cambio
alla modalità di applicazione forzata. I messaggi di log di SELinux contengono avc:
e quindi potrebbero
può essere trovata facilmente con grep
. È possibile acquisire l'andamento
denial log eseguendo cat /proc/kmsg
o acquisisci i log di rifiuto.
dall'avvio precedente eseguendo
cat /sys/fs/pstore/console-ramoops
.
I messaggi di errore SELinux hanno una frequenza limitata dopo il completamento dell'avvio per evitare lo swamping
nei log. Per assicurarti di visualizzare tutti i messaggi pertinenti, puoi disattivare questa
eseguendo adb shell auditctl -r 0
.
Con questo output, i produttori possono identificare facilmente quando gli utenti del sistema violano il criterio SELinux. I produttori possono quindi riparare il malfunzionamento, a seguito di modifiche al software, al criterio SELinux o a entrambi.
In particolare, questi messaggi di log indicano i processi che potrebbero avere esito negativo di applicazione forzata e perché. Ecco un esempio:
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
Interpreta questo output in questo modo:
- Il valore
{ connectto }
riportato sopra rappresenta l'azione intrapresa. In collaborazione contclass
alla fine (unix_stream_socket
), ti dice indicativamente ciò che è stato fatto a cosa. In questo caso, qualcosa stava tentando di connettersi a un socket di flusso Unix. - L'elemento
scontext (u:r:shell:s0)
indica il contesto che ha avviato l'azione. Nella in questo caso si tratta di qualcosa in esecuzione come shell. -
tcontext (u:r:netd:s0)
indica il contesto del target dell'azione. Nella in questo caso è un unix_stream_socket di proprietà dinetd
. - Il
comm="ping"
in alto offre un ulteriore suggerimento su ciò che era eseguito al momento della generazione del rifiuto. In questo caso, il suggerimento è piuttosto buono.
Ecco un altro esempio:
adb shell su root dmesg | grep 'avc: '
Uscita:
<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
Ecco gli elementi chiave di questo rifiuto:
- Azione: l'azione che hai tentato di eseguire è evidenziata tra parentesi
read write
osetenforce
. - Attore. La voce
scontext
(contesto di origine) rappresenta l'attore, in questo caso il daemonrmt_storage
. - Oggetto. La voce
tcontext
(contesto di destinazione) rappresenta dell'oggetto su cui si agisce, in questo caso kmem. - Risultato: la voce
tclass
(classe target) indica il tipo dell'oggetto su cui si agisce, in questo casochr_file
(dispositivo a caratteri).
Dumping degli stack utente e del kernel
In alcuni casi, le informazioni contenute nel log eventi non sono sufficienti per individuare l'origine del rifiuto. Spesso è utile raccogliere la catena di chiamate, inclusi kernel e per comprendere meglio perché il rifiuto è avvenuto.
I kernel recenti definiscono un tracepoint denominato avc:selinux_audited
. Usa Android
simpleperf
per abilitare questo tracepoint e acquisire la callchain.
Configurazione supportata
- Kernel Linux >= 5.10, in particolare rami comuni del kernel Linux
principale
e
Android12-5.10
sono supportati.
L'app android12-5.4
è supportato anche il ramo. Puoi utilizzare
simpleperf
per determinare se il tracepoint è definiti sul tuo dispositivo:adb root && adb shell simpleperf list | grep avc:selinux_audited
. Per altre versioni del kernel, puoi scegliere i commit dd81662 e 30969bc. - Dovrebbe essere possibile riprodurre l'evento di cui stai eseguendo il debug. Gli eventi relativi al tempo di avvio non sono supportato usando simpleperf; ma potresti comunque riuscire a riavviare il servizio per attivare l'evento.
Acquisizione della catena di chiamate
Il primo passaggio consiste nel registrare l'evento utilizzando simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
Quindi dovrebbe essere attivato l'evento che ha causato il rifiuto. Dopodiché, la registrazione
l'arresto anomalo. In questo esempio, utilizzando Ctrl-c
, il campione dovrebbe essere stato acquisito:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Infine, è possibile utilizzare simpleperf report
per esaminare lo stacktrace acquisito.
Ad esempio:
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
La catena di chiamate riportata sopra è una catena unificata di chiamate kernel e spazio utente. Offre una migliore
del flusso del codice avviando la traccia dallo spazio utente fino al kernel
la negazione avviene. Per ulteriori informazioni su simpleperf
, consulta
Riferimento per i comandi Simpleperf Executable
Passaggio a permissivo
L'applicazione di SELinux può essere disabilitata tramite ADB su userdebug o build eng. Per farlo,
imposta innanzitutto ADB in root eseguendo adb root
. Quindi, per disattivare SELinux
applicazione forzata, esegui:
adb shell setenforce 0
Oppure dalla riga di comando del kernel (durante il lancio anticipato del dispositivo):
androidboot.selinux=permissive
androidboot.selinux=enforcing
Oppure tramite bootconfig in Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
Utilizzo di audit2allow
Lo strumento audit2allow
accetta dmesg
rifiuti e
le converte in istruzioni di criterio SELinux corrispondenti. Di conseguenza,
lo sviluppo di SELinux molto veloce.
Per utilizzarlo, esegui:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
Ciononostante, occorre prestare attenzione nell'esaminare ogni potenziale aggiunta
il superamento delle autorizzazioni. Ad esempio, l'inserimento di audit2allow
nel feed
Il rifiuto di rmt_storage
mostrato in precedenza ha come risultato quanto segue
istruzione del criterio SELinux suggerita:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Questo concede a rmt
la possibilità di scrivere la memoria del kernel,
buca di sicurezza sgargiante. Spesso le istruzioni audit2allow
sono solo un
punto di partenza. Dopo aver utilizzato queste istruzioni, potrebbe essere necessario modificare
dominio di origine e l'etichetta del target, nonché incorporare correttamente
per ottenere una buona norma. A volte il rifiuto in esame
non comportino alcuna modifica alle norme; ma l'applicazione in questione
modifiche.