Android recomienda encarecidamente a los OEM que prueben sus implementaciones de SELinux. por completo. A medida que los fabricantes implementan SELinux, deben aplicar el nuevo política a un grupo de prueba de dispositivos primero.
Luego de aplicar la nueva política, asegúrate de que SELinux se esté ejecutando en el
en el dispositivo mediante el comando getenforce
.
Esto imprime el modo SELinux global: aplicable o Permisivo. Para
el modo SELinux para cada dominio, debes examinar el
o ejecuta la versión más reciente de sepolicy-analyze
con el comando
marca correspondiente (-p
), presente en
/platform/system/sepolicy/tools/
Denegaciones de lectura
Verificar si hay errores, que se enrutan como registros de eventos a dmesg
y logcat
, y se pueden ver de forma local en el dispositivo. Fabricantes
se debería examinar la salida de SELinux para dmesg
en estos dispositivos
definir mejor la configuración antes del lanzamiento público en el modo permisivo y, eventualmente, cambiar
al modo de aplicación forzosa. Los mensajes de registro de SELinux contienen avc:
, por lo que
se pueden encontrar fácilmente con grep
. Es posible capturar el estado
de denegación a través de la ejecución de cat /proc/kmsg
o para capturar registros de denegación.
del inicio anterior ejecutando
cat /sys/fs/pstore/console-ramoops
Los mensajes de error de SELinux tienen un límite de frecuencia después de que se completa el inicio para evitar saturación.
los registros. Para asegurarte de ver todos los mensajes relevantes, puedes inhabilitar esta opción.
ejecutando adb shell auditctl -r 0
.
Con este resultado, los fabricantes pueden identificar fácilmente cuándo los usuarios incumplen la política de SELinux. Los fabricantes pueden reparar este comportamiento inadecuado, ya sea por cambios en el software, en la política de SELinux o en ambos.
Específicamente, estos mensajes de registro indican en qué procesos fallarían modo de aplicación de políticas y por qué. A continuación, se muestra un ejemplo:
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 este resultado de la siguiente manera:
- El
{ connectto }
anterior representa la acción que se está realizando. Junto con eltclass
al final (unix_stream_socket
), te dice a grandes rasgos lo que se estaba haciendo a qué. En este caso, algo estaba intentando conectarse a un socket de transmisión Unix. -
scontext (u:r:shell:s0)
te indica qué contexto inició la acción. En en este caso, esto es algo que se ejecuta como shell. - El
tcontext (u:r:netd:s0)
te indica el contexto del objetivo de la acción. En En este caso, es un Unix_stream_socket propiedad denetd
. - El elemento
comm="ping"
de la parte superior te da una pista adicional sobre lo que se estaba se ejecutó en el momento en que se generó el rechazo. En este caso, es una buena pista.
Otro ejemplo:
adb shell su root dmesg | grep 'avc: '
Resultado:
<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
Estos son los elementos clave de esta denegación:
- Action: La acción que intentaste realizar se destaca entre corchetes.
read write
osetenforce
. - Actor: La entrada
scontext
(contexto de origen) representa el actor, en este caso el daemonrmt_storage
. - Objeto: La entrada
tcontext
(contexto de destino) representa el objeto sobre el que se actúa, en este caso kmem. - Resultado: La entrada
tclass
(clase objetivo) indica el tipo. del objeto sobre el que actúa, en este caso, unchr_file
(dispositivo de caracteres).
Cómo volcar pilas de usuario y kernel
En algunos casos, la información en el registro de eventos no es suficiente para identificar el origen de la negación. Por lo general, es útil recopilar la cadena de llamadas, incluidos el kernel y del espacio del usuario, para entender mejor por qué ocurrió.
Los kernels recientes definen un punto de seguimiento llamado avc:selinux_audited
. Usar Android
simpleperf
para habilitar este punto de seguimiento y capturar la cadena de llamadas
Configuración compatible
- Kernel de Linux >= 5.10, en particular ramas de kernel común de Android
línea principal
y
android12-5.10
compatibles.
La clase android12-5.4
también es compatible. Puedes usar
simpleperf
para determinar si el punto de seguimiento definido en tu dispositivo:adb root && adb shell simpleperf list | grep avc:selinux_audited
Para otras versiones de kernel, puedes elegir con cuidado las confirmaciones. dd81662 y 30969bc: - Debería ser posible reproducir el evento que estás depurando. Los eventos de tiempo de inicio es compatible con Simpleperf; Sin embargo, es posible que aún puedas reiniciarlo para activar el evento.
Captura la cadena de llamadas
El primer paso es grabar el evento con simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
Luego, se debe activar el evento que causó la denegación. Después de eso, la grabación debería
detenerse. En este ejemplo, con Ctrl-c
, se debería haber capturado la muestra:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
Por último, se puede usar simpleperf report
para inspeccionar el seguimiento de pila capturado.
Por ejemplo:
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 cadena de llamadas anterior es un kernel unificado y una cadena de llamadas del espacio de usuario. Te brinda una mejor
del flujo de código iniciando el seguimiento desde el espacio del usuario hasta el kernel, donde
se produce la negación. Para obtener más información sobre simpleperf
, consulta la
Referencia de comandos ejecutables de Simpleperf
Cambiando a permisivo
La aplicación forzosa de SELinux se puede inhabilitar a través de ADB en compilaciones userdebug o eng. Para ello, sigue estos pasos:
Primero, ejecuta adb root
para cambiar ADB al directorio raíz. Luego, para inhabilitar SELinux
aplicación, ejecuta el siguiente comando:
adb shell setenforce 0
También puedes hacerlo en la línea de comandos del kernel (durante la primera activación del dispositivo):
androidboot.selinux=permissive
androidboot.selinux=enforcing
O bien, a través de bootconfig en Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
Cómo usar audit2allow
La herramienta audit2allow
toma dmesg
denegaciones y
los convierte en instrucciones de política de SELinux correspondientes. Por lo tanto, puede
acelerar enormemente el desarrollo de SELinux.
Para usarlo, ejecuta el siguiente comando:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
No obstante, se debe tener cuidado al examinar cada posible aditivo para
la violación de la seguridad de los permisos. Por ejemplo, si proporcionas a audit2allow
el
La denegación de rmt_storage
que se mostró anteriormente genera lo siguiente:
declaración de política de SELinux sugerida:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
Esto otorgaría a rmt
la capacidad de escribir memoria del kernel, un
de seguridad desagradable. A menudo, las sentencias audit2allow
son solo un
punto de partida. Luego de emplear estas instrucciones, es posible que debas cambiar la
el dominio de origen y la etiqueta del objetivo, además de incorporar
para llegar a una buena política. A veces, el rechazo que se está examinando debería
no genera cambios en las políticas en absoluto; en lugar de la aplicación ofensiva
se debe cambiar.