Inicio del proveedor

El proceso de inicio tiene permisos casi ilimitados y utiliza scripts de entrada tanto del sistema como de las particiones del proveedor para inicializar el sistema durante el proceso de inicio. Este acceso causa un gran agujero en la división sistema/proveedor de Treble, ya que los scripts del proveedor pueden indicarle a init que acceda a archivos, propiedades, etc. que no forman parte de la interfaz binaria de aplicación (ABI) estable del sistema-proveedor.

Vendor init está diseñado para cerrar este agujero mediante el uso de un dominio separado de Linux con seguridad mejorada (SELinux) vendor_init para ejecutar comandos que se encuentran en /vendor con permisos específicos del proveedor.

Mecanismo

Vendor init bifurca un subproceso de init al principio del proceso de arranque con el contexto SELinux u:r:vendor_init:s0 . Este contexto SELinux tiene considerablemente menos permisos que el contexto de inicio predeterminado y su acceso se limita a archivos, propiedades, etc. que son específicos del proveedor o forman parte de la ABI estable del proveedor del sistema.

Init verifica cada script que carga para ver si su ruta comienza con /vendor y, de ser así, lo etiqueta con una indicación de que sus comandos deben ejecutarse en el contexto de inicio del proveedor. Cada init incorporado está anotado con un valor booleano que especifica si el comando debe ejecutarse o no en el subproceso init del proveedor:

  • La mayoría de los comandos que acceden al sistema de archivos están anotados para ejecutarse en el subproceso de inicio del proveedor y, por lo tanto, están sujetos a la política SEPolicy de inicio del proveedor.
  • La mayoría de los comandos que afectan el estado de inicio interno (por ejemplo, iniciar y detener servicios) se ejecutan dentro del proceso de inicio normal. Estos comandos son conscientes de que un script de proveedor los está llamando para realizar su propio manejo de permisos que no son de SELinux.

El bucle de procesamiento principal de init contiene una verificación de que si un comando está anotado para ejecutarse en el subproceso del proveedor y se origina en un script del proveedor, ese comando se envía a través de comunicación entre procesos (IPC) al subproceso init del proveedor, que ejecuta el comando. y envía el resultado de vuelta a init.

Usando el proveedor de inicio

Vendor init está habilitado de forma predeterminada y sus restricciones se aplican a todos los scripts de inicio presentes en la partición /vendor . El inicio del proveedor debe ser transparente para los proveedores cuyos scripts ya no acceden únicamente a archivos, propiedades, etc. del sistema.

Sin embargo, si los comandos en un script de proveedor determinado violan las restricciones de inicio del proveedor, los comandos fallarán. Los comandos fallidos tienen una línea en el registro del kernel (visible con dmesg) desde init que indica el error. Una auditoría de SELinux acompaña a cualquier comando fallido debido a la política de SELinux. Ejemplo de falla que incluye una auditoría de SELinux:

type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0
init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied

Si un comando falla, hay dos opciones:

  • Si el comando falla debido a una restricción prevista (como si el comando accede a un archivo o propiedad del sistema), el comando debe volver a implementarse de una manera compatible con Treble, pasando solo por interfaces estables. Las reglas Neverallow impiden agregar permisos para acceder a archivos del sistema que no forman parte de la ABI estable del proveedor del sistema.
  • Si la etiqueta SELinux es nueva y aún no tiene permisos otorgados en el sistema vendor_init.te ni permisos excluidos a través de las reglas neverallow, a la nueva etiqueta se le pueden otorgar permisos en el vendor_init.te específico del dispositivo.

Para dispositivos que se inician antes de Android 9, las reglas de nunca permitir pueden omitirse agregando el atributo de tipo data_between_core_and_vendor_violators al archivo vendor_init.te específico del dispositivo.

Ubicaciones de códigos

La mayor parte de la lógica para el IPC de inicio del proveedor se encuentra en system/core/init/subcontext.cpp .

La tabla de comandos se encuentra en la clase BuiltinFunctionMap en system/core/init/builtins.cpp e incluye anotaciones que indican si el comando debe ejecutarse en el subproceso de inicio del proveedor.

La SEPolicy para el proveedor init se divide en los directorios privado ( system/sepolicy/private/vendor_init.te ) y público ( system/sepolicy/public/vendor_init.te ) en system/sepolicy.