Personalización de SELinux

Una vez que haya integrado el nivel básico de la funcionalidad de SELinux y haya analizado minuciosamente los resultados, puede agregar su propia configuración de políticas para cubrir sus personalizaciones en el sistema operativo Android. Estas políticas aún deben cumplir con los requisitos del programa de compatibilidad de Android y no deben eliminar la configuración predeterminada de SELinux.

Los fabricantes no deben eliminar la política SELinux existente. De lo contrario, corren el riesgo de romper la implementación de Android SELinux y las aplicaciones que rige. Esto incluye aplicaciones de terceros que probablemente deban mejorarse para que sean compatibles y operativas. Las aplicaciones no deben requerir modificaciones para continuar funcionando en dispositivos habilitados para SELinux.

Al embarcarse en la personalización de SELinux, recuerde:

  • Escriba la política de SELinux para todos los demonios nuevos
  • Use dominios predefinidos cuando sea apropiado
  • Asigne un dominio a cualquier proceso generado como un servicio de init
  • Familiarícese con las macros antes de escribir la política
  • Enviar cambios a la política principal a AOSP

Y recuerda no:

  • Crear política incompatible
  • Permitir la personalización de políticas de usuario final
  • Permitir personalizaciones de políticas de MDM
  • Asustar a los usuarios con infracciones de políticas
  • Agregar puertas traseras

Consulte la sección Funciones de seguridad del kernel del documento Definición de compatibilidad de Android para conocer los requisitos específicos.

SELinux utiliza un enfoque de lista blanca, lo que significa que todos los accesos deben permitirse explícitamente en la política para que se concedan. Dado que la política de SELinux predeterminada de Android ya es compatible con el Proyecto de código abierto de Android, no es necesario que modifique la configuración de SELinux de ninguna manera. Si personaliza la configuración de SELinux, tenga mucho cuidado de no dañar las aplicaciones existentes. Para empezar:

  1. Usa el kernel de Android más reciente .
  2. Adoptar el principio de privilegio mínimo .
  3. Aborda solo tus propias adiciones a Android. La política predeterminada funciona automáticamente con el código base del proyecto de código abierto de Android .
  4. Compartimente los componentes de software en módulos que realicen tareas singulares.
  5. Cree políticas de SELinux que aíslen esas tareas de funciones no relacionadas.
  6. Coloque esas políticas en archivos *.te (la extensión de los archivos fuente de políticas de SELinux) dentro del directorio /device/ manufacturer / device-name /sepolicy y use las variables BOARD_SEPOLICY para incluirlas en su compilación.
  7. Haga que los nuevos dominios sean permisivos inicialmente. Esto se hace usando una declaración permisiva en el archivo .te del dominio.
  8. Analice los resultados y refine las definiciones de su dominio.
  9. Elimine la declaración permisiva cuando no aparezcan más denegaciones en las compilaciones de depuración de usuarios.

Una vez que haya integrado su cambio de política de SELinux, agregue un paso a su flujo de trabajo de desarrollo para garantizar la compatibilidad con SELinux en el futuro. En un proceso de desarrollo de software ideal, la política de SELinux cambia solo cuando cambia el modelo de software y no la implementación real.

Cuando comience a personalizar SELinux, primero audite sus adiciones a Android. Si agregó un componente que realiza una nueva función, asegúrese de que el componente cumpla con la política de seguridad de Android, así como con cualquier política asociada creada por el OEM, antes de activar el modo de cumplimiento.

Para evitar problemas innecesarios, es mejor ser demasiado amplio y compatible que demasiado restrictivo e incompatible, lo que da como resultado que las funciones del dispositivo no funcionen. Por el contrario, si sus cambios beneficiarán a otros, debe enviar las modificaciones a la política predeterminada de SELinux como un parche . Si el parche se aplica a la política de seguridad predeterminada, no necesitará realizar este cambio con cada nueva versión de Android.

Ejemplos de declaraciones de política

SELinux se basa en el lenguaje informático M4 y, por lo tanto, admite una variedad de macros para ahorrar tiempo.

En el siguiente ejemplo, todos los dominios tienen acceso para leer o escribir en /dev/null y leer desde /dev/zero .

# Allow read / write access to /dev/null
allow domain null_device:chr_file { getattr open read ioctl lock append write};

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file { getattr open read ioctl lock };

Esta misma declaración se puede escribir con las macros SELinux *_file_perms (abreviatura):

# Allow read / write access to /dev/null
allow domain null_device:chr_file rw_file_perms;

# Allow read-only access to /dev/zero
allow domain zero_device:chr_file r_file_perms;

Política de ejemplo

Aquí hay una política de ejemplo completa para DHCP, que examinamos a continuación:

type dhcp, domain;
permissive dhcp;
type dhcp_exec, exec_type, file_type;
type dhcp_data_file, file_type, data_file_type;

init_daemon_domain(dhcp)
net_domain(dhcp)

allow dhcp self:capability { setgid setuid net_admin net_raw net_bind_service
};
allow dhcp self:packet_socket create_socket_perms;
allow dhcp self:netlink_route_socket { create_socket_perms nlmsg_write };
allow dhcp shell_exec:file rx_file_perms;
allow dhcp system_file:file rx_file_perms;
# For /proc/sys/net/ipv4/conf/*/promote_secondaries
allow dhcp proc_net:file write;
allow dhcp system_prop:property_service set ;
unix_socket_connect(dhcp, property, init)

type_transition dhcp system_data_file:{ dir file } dhcp_data_file;
allow dhcp dhcp_data_file:dir create_dir_perms;
allow dhcp dhcp_data_file:file create_file_perms;

allow dhcp netd:fd use;
allow dhcp netd:fifo_file rw_file_perms;
allow dhcp netd:{ dgram_socket_class_set unix_stream_socket } { read write };
allow dhcp netd:{ netlink_kobject_uevent_socket netlink_route_socket
netlink_nflog_socket } { read write };

Analicemos el ejemplo:

En la primera línea, la declaración de tipo, el demonio DHCP hereda de la política de seguridad base ( domain ). De los ejemplos de sentencias anteriores, DHCP puede leer y escribir en /dev/null .

En la segunda línea, DHCP se identifica como un dominio permisivo.

En la init_daemon_domain(dhcp) , la política establece que DHCP se genera desde init y se le permite comunicarse con él.

En la net_domain(dhcp) , la política permite que DHCP use la funcionalidad de red común del dominio de net , como leer y escribir paquetes TCP, comunicarse a través de sockets y realizar solicitudes de DNS.

En la línea allow dhcp proc_net:file write; , la política establece que DHCP puede escribir en archivos específicos en /proc . Esta línea demuestra el etiquetado de archivos detallado de SELinux. Utiliza la etiqueta proc_net para limitar el acceso de escritura solo a los archivos en /proc/sys/net .

El bloque final del ejemplo que comienza con allow dhcp netd:fd use; describe cómo se puede permitir que las aplicaciones interactúen entre sí. La política dice que DHCP y netd pueden comunicarse entre sí a través de descriptores de archivos, archivos FIFO, sockets de datagramas y sockets de flujo UNIX. DHCP solo puede leer y escribir desde los sockets de datagramas y los sockets de flujo UNIX y no puede crearlos ni abrirlos.

Controles disponibles

Clase Permiso
expediente
ioctl read write create getattr setattr lock relabelfrom relabelto append
unlink link rename execute swapon quotaon mounton
directorio
add_name remove_name reparent search rmdir open audit_access execmod
enchufe
ioctl read write create getattr setattr lock relabelfrom relabelto append bind
connect listen accept getopt setopt shutdown recvfrom sendto recv_msg send_msg
name_bind
sistema de archivos
mount remount unmount getattr relabelfrom relabelto transition associate
quotamod quotaget
proceso
fork transition sigchld sigkill sigstop signull signal ptrace getsched setsched
getsession getpgid setpgid getcap setcap share getattr setexec setfscreate
noatsecure siginh setrlimit rlimitinh dyntransition setcurrent execmem
execstack execheap setkeycreate setsockcreate
seguridad
compute_av compute_create compute_member check_context load_policy
compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot
read_policy
capacidad
chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap
linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock
ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin
sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write
audit_control setfcap

MÁS

Y MÁS

reglas nunca permitidas

Las reglas de SELinux neverallow prohíben comportamientos que nunca deberían ocurrir. Con las pruebas de compatibilidad , las reglas de neverallow de SELinux ahora se aplican en todos los dispositivos.

Las siguientes pautas están destinadas a ayudar a los fabricantes a evitar errores relacionados con neverallow durante la personalización. Los números de regla que se usan aquí corresponden a Android 5.1 y están sujetos a cambios según la versión.

Regla 48: neverallow { domain -debuggerd -vold -dumpstate -system_server } self:capability sys_ptrace;
Consulte la página de manual de ptrace . La capacidad sys_ptrace otorga la capacidad de ptrace cualquier proceso, lo que permite un gran control sobre otros procesos y debe pertenecer solo a los componentes del sistema designados, descritos en la regla. La necesidad de esta capacidad a menudo indica la presencia de algo que no está diseñado para compilaciones orientadas al usuario o funcionalidad que no se necesita. Retire el componente innecesario.

Regla 76: neverallow { domain -appdomain -dumpstate -shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
Esta regla está destinada a evitar la ejecución de código arbitrario en el sistema. En concreto, afirma que solo se ejecuta código en /system , lo que permite garantías de seguridad gracias a mecanismos como el arranque verificado. A menudo, la mejor solución cuando se encuentra con un problema con esta regla neverallow es mover el código infractor a la partición /system .

Personalización de SEPolicy en Android 8.0+

Esta sección proporciona pautas para la política de SELinux del proveedor en Android 8.0 y versiones posteriores, incluidos los detalles sobre SEPolicy y las extensiones de SEPolicy del proyecto de código abierto de Android (AOSP). Para obtener más información sobre cómo la política de SELinux se mantiene compatible entre particiones y versiones de Android, consulte Compatibilidad .

Colocación de pólizas

En Android 7.0 y versiones anteriores, los fabricantes de dispositivos podían agregar una política a BOARD_SEPOLICY_DIRS , incluida una política destinada a aumentar la política AOSP en diferentes tipos de dispositivos. En Android 8.0 y versiones posteriores, agregar una política a BOARD_SEPOLICY_DIRS coloca la política solo en la imagen del proveedor.

En Android 8.0 y superior, la política existe en las siguientes ubicaciones en AOSP:

  • system/sepolicy/público . Incluye la política exportada para su uso en la política específica del proveedor. Todo entra en la infraestructura de compatibilidad con Android 8.0. La política pública está destinada a persistir en todos los lanzamientos para que pueda incluir cualquier cosa /public en su política personalizada. Debido a esto, el tipo de política que se puede colocar en /public es más restringido. Considere esto como la API de política exportada de la plataforma: todo lo relacionado con la interfaz entre /system y /vendor pertenece aquí.
  • system/sepolicy/privado . Incluye la política necesaria para el funcionamiento de la imagen del sistema, pero de la cual la política de imagen del proveedor no debe tener conocimiento.
  • sistema/sepolítica/proveedor . Incluye la política para los componentes que van en /vendor pero que existen en el árbol de la plataforma principal (no en los directorios específicos del dispositivo). Este es un artefacto de la distinción del sistema de compilación entre dispositivos y componentes globales; conceptualmente, esto es parte de la política específica del dispositivo que se describe a continuación.
  • dispositivo/ manufacturer / device-name /sepolicy . Incluye política específica del dispositivo. También incluye personalizaciones de dispositivos para la política, que en Android 8.0 y superior corresponde a la política para componentes en la imagen del proveedor.

En Android 11 y versiones posteriores, system_ext y las particiones de productos también pueden incluir políticas específicas de partición. system_ext y las políticas de productos también se dividen en públicas y privadas, y los proveedores pueden usar las políticas públicas de system_ext y productos, como la política del sistema.

  • SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS . Incluye la política exportada para su uso en la política específica del proveedor. Instalado en la partición system_ext.
  • SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS . Incluye la política necesaria para el funcionamiento de la imagen system_ext, pero de la cual la política de imagen del proveedor no debe tener conocimiento. Instalado en la partición system_ext.
  • PRODUCT_PUBLIC_SEPOLICY_DIRS . Incluye la política exportada para su uso en la política específica del proveedor. Instalado en la partición del producto.
  • PRODUCT_PRIVATE_SEPOLICY_DIRS . Incluye la política necesaria para el funcionamiento de la imagen del producto, pero de la cual la política de imagen del proveedor no debe tener conocimiento. Instalado en la partición del producto.
Nota: cuando se utiliza GSI, las particiones system_ext y producto del OEM no se montarán. Las reglas en la política de seguridad del proveedor que utiliza system_ext del OEM y la política pública del producto se convierten en NOP porque faltan las definiciones de tipo específicas del OEM.
Nota: tenga mucho cuidado al usar system_ext y políticas públicas de productos. Las políticas públicas actúan como una API exportada entre system_ext/product y el proveedor. Se supone que los socios gestionan los problemas de compatibilidad por sí mismos.

Escenarios de políticas admitidos

En los dispositivos que se inician con Android 8.0 y versiones posteriores, la imagen del proveedor debe funcionar con la imagen del sistema OEM y la imagen del sistema AOSP de referencia proporcionada por Google (y pasar CTS en esta imagen de referencia). Estos requisitos aseguran una clara separación entre el marco y el código del proveedor. Dichos dispositivos admiten los siguientes escenarios.

extensiones de solo imagen del proveedor

Ejemplo : agregar un nuevo servicio a vndservicemanager desde la imagen del proveedor que admita procesos desde la imagen del proveedor.

Al igual que con los dispositivos que se inician con versiones anteriores de Android, agregue la personalización específica del dispositivo en device/ manufacturer / device-name /sepolicy . La nueva política que rige cómo los componentes del proveedor interactúan con (solo) otros componentes del proveedor deben incluir tipos presentes solo en device/ manufacturer / device-name /sepolicy . La política escrita aquí permite que funcione el código del proveedor, no se actualizará como parte de una OTA solo del marco y estará presente en la política combinada en un dispositivo con la imagen del sistema AOSP de referencia.

soporte de imagen de proveedor para trabajar con AOSP

Ejemplo : Agregar un nuevo proceso (registrado con hwservicemanager desde la imagen del proveedor) que implementa una HAL definida por AOSP.

Al igual que con los dispositivos que se inician con versiones anteriores de Android, realice una personalización específica del dispositivo en device/ manufacturer / device-name /sepolicy . La política exportada como parte de system/sepolicy/public/ está disponible para su uso y se envía como parte de la política del proveedor. Los tipos y atributos de la política pública se pueden usar en nuevas reglas que dictan interacciones con los nuevos bits específicos del proveedor, sujeto a las restricciones proporcionadas neverallow . Al igual que con el caso de solo proveedor, la nueva política aquí no se actualizará como parte de una OTA solo de marco y estará presente en la política combinada en un dispositivo con la imagen del sistema AOSP de referencia.

extensiones de solo imagen del sistema

Ejemplo : agregar un nuevo servicio (registrado con servicemanager) al que solo acceden otros procesos desde la imagen del sistema.

Agregue esta política a system/sepolicy/private . Puede agregar procesos u objetos adicionales para habilitar la funcionalidad en una imagen del sistema asociado, siempre que esos nuevos bits no necesiten interactuar con nuevos componentes en la imagen del proveedor (específicamente, dichos procesos u objetos deben funcionar completamente sin la política de la imagen del proveedor) . La política exportada por system/sepolicy/public está disponible aquí al igual que para las extensiones de solo imagen del proveedor. Esta política es parte de la imagen del sistema y podría actualizarse en una OTA solo del marco, pero no estará presente cuando se use la imagen del sistema AOSP de referencia.

extensiones de imagen de proveedor que sirven componentes AOSP extendidos

Ejemplo: una nueva HAL que no es AOSP para uso de clientes extendidos que también existen en la imagen del sistema AOSP (como un system_server extendido).

La política de interacción entre el sistema y el proveedor debe incluirse en el directorio device/ manufacturer / device-name /sepolicy incluye en la partición del proveedor. Esto es similar al escenario anterior de agregar soporte de imagen de proveedor para trabajar con la imagen AOSP de referencia, excepto que los componentes AOSP modificados también pueden requerir una política adicional para operar correctamente con el resto de la partición del sistema (lo cual está bien siempre que todavía tienen las etiquetas de tipo AOSP públicas).

La política para la interacción de los componentes públicos de AOSP con extensiones de solo imagen del sistema debe estar en system/sepolicy/private .

extensiones de imagen del sistema que acceden solo a las interfaces AOSP

Ejemplo: un nuevo proceso del sistema que no sea AOSP debe acceder a una HAL en la que se basa AOSP.

Esto es similar al ejemplo de extensión de solo imagen del sistema , excepto que los nuevos componentes del sistema pueden interactuar a través de la interfaz del system/vendor . La política para el nuevo componente del sistema debe ir en system/sepolicy/private , lo cual es aceptable siempre que sea a través de una interfaz ya establecida por AOSP en system/sepolicy/public (es decir, los tipos y atributos necesarios para la funcionalidad están allí). Si bien la política podría incluirse en la política específica del dispositivo, no podría usar otros tipos de system/sepolicy/private o cambiar (de ninguna manera que afecte la política) como resultado de una actualización solo del marco. La política se puede cambiar en una OTA solo de marco, pero no estará presente cuando se use una imagen del sistema AOSP (que tampoco tendrá el nuevo componente del sistema).

extensiones de imagen de proveedor que sirven a nuevos componentes del sistema

Ejemplo: agregar una nueva HAL que no sea de AOSP para que la use un proceso de cliente sin un análogo de AOSP (y, por lo tanto, requiere su propio dominio).

Al igual que en el ejemplo de extensiones AOSP , la política para las interacciones entre el sistema y el proveedor debe ir en el directorio device/ manufacturer / device-name /sepolicy enviado en la partición del proveedor (para garantizar que la política del sistema no tenga conocimiento de los detalles específicos del proveedor). Puede agregar nuevos tipos públicos que amplíen la política en system/sepolicy/public ; esto debe hacerse solo además de la política AOSP existente, es decir, no eliminar la política pública AOSP. Los nuevos tipos públicos se pueden usar para la política en system/sepolicy/private y en device/ manufacturer / device-name /sepolicy .

Tenga en cuenta que cada adición a system/sepolicy/public agrega complejidad al exponer una nueva garantía de compatibilidad que debe rastrearse en un archivo de asignación y que está sujeta a otras restricciones. Solo se pueden agregar nuevos tipos y las correspondientes reglas de permiso en system/sepolicy/public ; los atributos y otras declaraciones de política no son compatibles. Además, los nuevos tipos públicos no se pueden usar para etiquetar objetos directamente en la política /vendor .

Escenarios de políticas no admitidos

Los dispositivos que se inician con Android 8.0 y versiones posteriores no son compatibles con los siguientes escenarios y ejemplos de políticas.

Extensiones adicionales a la imagen del sistema que necesitan permiso para nuevos componentes de la imagen del proveedor después de una OTA de solo marco

Ejemplo: en la próxima versión de Android se agrega un nuevo proceso del sistema que no es AOSP, que requiere su propio dominio, y necesita acceso a una nueva HAL que no es AOSP.

Similar a la interacción entre el nuevo sistema (no AOSP) y los componentes del proveedor , excepto que el nuevo tipo de sistema se introduce en una OTA de solo marco. Aunque el nuevo tipo podría agregarse a la política en system/sepolicy/public , la política del proveedor existente no tiene conocimiento del nuevo tipo, ya que solo realiza un seguimiento de la política pública del sistema Android 8.0. AOSP maneja esto al exponer los recursos proporcionados por el proveedor a través de un atributo (por ejemplo, el atributo hal_foo ), pero como las extensiones de socios de atributos no son compatibles con system/sepolicy/public , este método no está disponible para la política del proveedor. El acceso debe ser proporcionado por un tipo público previamente existente.

Ejemplo: un cambio en un proceso del sistema (AOSP o no AOSP) debe cambiar la forma en que interactúa con el nuevo componente del proveedor que no es AOSP.

La política sobre la imagen del sistema debe escribirse sin conocimiento de las personalizaciones específicas del proveedor. La política relativa a interfaces específicas en AOSP se expone a través de atributos en system/sepolicy/public para que la política del proveedor pueda optar por la futura política del sistema que utiliza estos atributos. Sin embargo, las extensiones de atributos en system/sepolicy/public no son compatibles , por lo que todas las políticas que dictan cómo los componentes del sistema interactúan con los nuevos componentes del proveedor (y que no son manejadas por atributos ya presentes en AOSP system/sepolicy/public ) deben estar en device/ manufacturer / device-name /sepolicy . Esto significa que los tipos de sistemas no pueden cambiar el acceso permitido a los tipos de proveedores como parte de una OTA de solo marco.