Escribe una política de SELinux

El Proyecto de código abierto de Android (AOSP) proporciona una política de base sólida para el aplicaciones y servicios comunes en todos los dispositivos Android. Los colaboradores del AOSP definen mejor esta política con regularidad. Se espera que la política principal para representar entre el 90 y el 95% de la política final personalizaciones que componen el 5% al 10% restante. Este artículo se centra en estas personalizaciones específicas del dispositivo, cómo escribir la política específica del dispositivo y algunos de los errores que se deben evitar en el camino.

Abre el dispositivo

Cuando escribas la política específica del dispositivo, sigue estos pasos.

Cómo ejecutar en modo permisivo

Cuando un dispositivo está en modo permisivo, las denegaciones se registran, pero no se aplican. El modo permisivo es importante para dos motivos:

  • El modo permisivo garantiza que la introducción de la política no retrase otros para abrir el dispositivo.
  • Una denegación forzosa puede enmascarar otras denegaciones. Por ejemplo, acceso a archivos suele implicar una búsqueda en un directorio, un archivo abierto y, luego, una lectura de archivos. En de aplicación forzosa, solo se produce la denegación de la búsqueda del directorio. Permisivo garantiza que se vean todas las denegaciones.

La forma más sencilla de poner un dispositivo en modo permisivo es usar el Comando del kernel línea. Se puede agregar al archivo BoardConfig.mk del dispositivo: platform/device/<vendor>/<target>/BoardConfig.mk Después de modificar la línea de comandos, realiza make clean y, luego, make bootimage, escribe la nueva imagen de arranque en la memoria flash.

Luego, confirma el modo permisivo con lo siguiente:

adb shell getenforce

Dos semanas es una cantidad de tiempo razonable para estar en el modo permisivo global. Tras abordar la mayoría de los rechazos, vuelve al modo de aplicación forzosa y abordar los errores a medida que se presentan. Los dominios siguen produciendo denegaciones o los servicios aún en un desarrollo intenso puede ponerse temporalmente en modo permisivo, pero volver al modo de aplicación lo antes posible.

Aplicar de manera anticipada

En el modo de aplicación forzosa, las denegaciones se registran y se aplican. Tiene la mejor activa el modo de aplicación forzosa en el dispositivo lo antes posible. Esperando para crear y aplicar políticas específicas del dispositivo a menudo da como resultado un producto con errores y un mala experiencia del usuario. Comience lo antes posible para participar prueba interna y garantizar una cobertura de prueba completa de funcionalidad en el mundo real. Iniciando garantice con anticipación las inquietudes de seguridad para tomar decisiones de diseño. Por el contrario, otorgar los permisos basados únicamente en las denegaciones observadas es un enfoque no seguro. Usar esta tiempo para realizar una auditoría de seguridad del dispositivo e informar errores relacionados con el comportamiento que no deberían permitirse.

Quita o borra la política existente

Hay una serie de buenas razones para crear una política específica para el dispositivo a partir de desde cero en un dispositivo nuevo, como

Cómo abordar las denegaciones de servicios principales

Las denegaciones que generan los servicios principales suelen abordarse mediante el etiquetado de archivos. Por ejemplo:

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

se aborda por completo etiquetando correctamente /dev/kgsl-3d0. En En este ejemplo, tcontext es device. Esto representa un contexto predeterminado en el que todo en /dev recibe el “ device”, a menos que se asigne una más específica. Solo se acepta el resultado de audit2allow daría como resultado una regla incorrecta y demasiado permisiva.

Para resolver este tipo de problema, ponle al archivo una etiqueta más específica, que en este caso es gpu_device No se necesitan más permisos, ya que mediaserver ya tiene los permisos necesarios en la política principal para acceder gpu_device

Otros archivos específicos del dispositivo que deben etiquetarse con tipos predefinidos en política principal:

En general, no es correcto otorgar permisos a etiquetas predeterminadas. Muchos de estos permisos están permitidos por neverallow, pero aunque esto no esté permitido explícitamente, la práctica recomendada es proporcionar un etiqueta.

Etiquetar servicios y direcciones nuevos rechazos

Es necesario que los servicios iniciados se ejecuten en sus propios dominios SELinux. El El siguiente ejemplo coloca el servicio “foo” en su propio dominio SELinux y le otorga permisos.

El servicio se lanza en la versión init.device.rc archivo como:

service foo /system/bin/foo
    class core
  1. Crea un nuevo dominio “foo”

    Crea el archivo device/manufacturer/device-name/sepolicy/foo.te con el siguiente contenido:

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

    Esta es la plantilla inicial para el dominio SELinux de foo, a la cual puedes agregar reglas en función de las operaciones específicas que realiza ese ejecutable.

  2. Etiqueta /system/bin/foo

    Agrega lo siguiente a device/manufacturer/device-name/sepolicy/file_contexts:

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

    Esto garantiza que el ejecutable esté etiquetado correctamente para que SELinux ejecute servicio en el dominio adecuado.

  3. Compila e instala las imágenes de arranque y del sistema.
  4. Define mejor las reglas de SELinux para el dominio.

    Usa denegaciones para determinar los permisos necesarios. El audit2allow brinda buenos lineamientos, pero úsala solo para informar políticas escritura. No te limites a copiar el resultado.

Volver al modo de aplicación forzosa

Es posible solucionar problemas en el modo permisivo, pero se debe volver a la aplicación forzosa lo antes posible y tratar de permanecer allí.

Errores comunes

Estas son algunas soluciones para los errores comunes que se producen al escribir políticas específicas del dispositivo.

Uso excesivo de la negación

La siguiente regla de ejemplo es como trabar la puerta principal, pero dejar la ventanas abiertas:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

La intención es clara: todas las personas, excepto las apps de terceros, pueden tener acceso a la depuración. dispositivo.

La regla tiene varios errores. La exclusión de untrusted_app es sencillo solucionar porque todas las apps pueden, de manera opcional, ejecutar servicios en la isolated_app. Del mismo modo, si se agregan dominios nuevos para apps de terceros al AOSP, también tendrán acceso a scary_debug_device. La regla es demasiado permisiva. La mayoría de los dominios no se beneficiarán por tener acceso a esta herramienta de depuración. La regla se debería haber escrito de modo que solo permita los dominios que requieren acceso.

Depuración de atributos en producción

Las funciones de depuración no deben estar presentes en las compilaciones de producción ni deben .

La alternativa más sencilla es permitir la función de depuración solo cuando SELinux esté inhabilitado en compilaciones eng/userdebug, como adb root y adb shell setenforce 0

Otra alternativa segura es incluir permisos de depuración en un userdebug_or_eng.

Explosión de tamaño de políticas

Caracterización de las políticas de SEAndroid de forma habitual describe una tendencia preocupante en cuanto al crecimiento de las personalizaciones de las políticas de dispositivos. La política específica del dispositivo debe representar entre el 5% y el 10% de la política general que se ejecuta en un dispositivo. Es muy probable que las personalizaciones que estén en más del 20%contengan más de los dominios con privilegios y la política inactiva.

Política innecesariamente grande:

  • Realiza doble carga en la memoria, ya que la política se encuentra en el ramdisk y también se cargan en la memoria del kernel.
  • Desperdicia espacio en el disco porque requiere una imagen de arranque más grande.
  • Afecta los tiempos de búsqueda de la política de tiempo de ejecución.

En el siguiente ejemplo, se muestran dos dispositivos en los que se encuentra comprendían el 50% y el 40% de la política en el dispositivo. Una reescritura de la política obtuvo mejoras de seguridad sustanciales sin pérdida de funcionalidad, ya que que se muestra a continuación. (Se incluyen los dispositivos AOSP Shamu y Flounder a modo de comparación).

Figura 1: Comparación del tamaño de la política específica del dispositivo después de la auditoría de seguridad.

Figura 1. Comparación de dispositivos el tamaño de la política después de la auditoría de seguridad.

En ambos casos, la política se redujo drásticamente en tamaño y cantidad de permisos. La disminución en el tamaño de las políticas se debe casi en su totalidad a quitar permisos innecesarios, muchos de los cuales probablemente fueron reglas generadas por audit2allow que se agregaron indiscriminadamente a la política. Muerto también eran un problema para ambos dispositivos.

Otorga la función dac_override

Una negación del tipo dac_override significa que el proceso ofensivo se intentar acceder a un archivo con permisos de usuario/grupo/mundo de Unix incorrectos La solución adecuada casi nunca es otorgar el permiso dac_override. En cambio cambiar los permisos de Unix en el archivo o proceso Algunos dominios como init, vold y installd realmente necesitan anular los permisos del archivo Unix para acceder a archivos de otros procesos Consulta el blog de Dan Walsh para obtener una explicación más detallada.