Inicialización del proveedor

El proceso de inicio tiene permisos casi ilimitados y utiliza secuencias de comandos de entrada tanto del sistema como de las particiones del proveedor para inicializar el sistema durante el proceso de arranque. Este acceso provoca un gran agujero en la división sistema/proveedor de Treble, ya que las secuencias de comandos 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 y del proveedor.

Vendor init está diseñado para cerrar este agujero mediante el uso de un dominio independiente de seguridad mejorada de Linux (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 de SELinux u:r:vendor_init:s0 . Este contexto de SELinux tiene muchos menos permisos que el contexto de inicio predeterminado y su acceso se limita a archivos, propiedades, etc. que son específicos del proveedor o 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 se anota con un valor booleano que especifica si el comando debe ejecutarse o no en el subproceso de inicio 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 SEPolicy de inicio del proveedor.
  • La mayoría de los comandos que afectan el estado de inicio interno (p. ej., 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 se anota para ejecutarse en el subproceso del proveedor y se origina en un script del proveedor, ese comando se envía a través de la comunicación entre procesos (IPC) al subproceso de inicio del proveedor, que ejecuta el comando. y envía el resultado de vuelta a init.

Uso de la inicialización del proveedor

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

Sin embargo, si los comandos en un script de un proveedor dado violan las restricciones de inicio del proveedor, los comandos fallarán. Los comandos que fallan tienen una línea en el registro del kernel (visible con dmesg) desde init que indica falla. Una auditoría de SELinux acompaña a cualquier comando fallido debido a la política de SELinux. Ejemplo de una 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 intencionada (por ejemplo, si el comando está accediendo a un archivo o propiedad del sistema), el comando debe volver a implementarse de manera compatible con Treble, pasando solo por interfaces estables. Las reglas Neverallow impiden agregar permisos para acceder a los archivos del sistema que no forman parte de la ABI estable del proveedor del sistema.
  • Si la etiqueta de 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, la nueva etiqueta puede recibir permisos en el dispositivo vendor_init.te específico.

Para los 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ódigo

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 inicio del proveedor se divide en los directorios privado (system/sepolicy/private/vendor_init.te ) y público ( system/sepolicy/public/vendor_init.te ) en system/sepolicy.