O processo init tem permissões quase irrestritas e usa scripts de entrada de partições do sistema e do fornecedor para inicializar o sistema durante a inicialização de desenvolvimento de software. Esse acesso causa uma grande brecha na divisão do sistema/fornecedor do Treble, scripts de fornecedores podem instruir o init a acessar arquivos, propriedades etc. que não fazem parte da interface binária de aplicativo (ABI, na sigla em inglês) estável do fornecedor do sistema.
Vendor Init foi projetado para fechar essa brecha usando um
domínio vendor_init
do Linux com segurança aprimorada (SELinux) para ser executado
encontrados em /vendor
com permissões específicas do fornecedor.
Mecanismo
O fornecedor init divide um subprocesso init no início do processo de inicialização com o
Contexto do SELinux u:r:vendor_init:s0
. Esse contexto do SELinux
muito menos permissões do que o contexto init padrão e seu acesso é
confinado a arquivos, propriedades etc. que são específicos do fornecedor ou parte do
a ABI do fornecedor de sistema estável.
O init verifica cada script que carrega para ver se seu caminho começa com
/vendor
e, em caso afirmativo, o marca com uma indicação de que os comandos
precisa ser executado no contexto init do fornecedor. Cada builtin init é anotado com um
booleano que especifica se o comando deve ou não ser executado no init do fornecedor
subprocesso:
- A maioria dos comandos que acessam o sistema de arquivos é anotada para execução no fornecedor init subprocesso e, portanto, estão sujeitos ao init SEPolicy do fornecedor.
- A maioria dos comandos que afetam o estado init interno (por exemplo, iniciar e parar) serviços) são executados no processo init normal. Esses comandos são feitos cientes de que um script de fornecedor está chamando eles para fazer seu próprio processamento de permissões.
O loop de processamento principal do init contém uma verificação de que, se um comando for anotado para execução no subprocesso do fornecedor e tem origem em um script do fornecedor, que é enviado via comunicação entre processos (IPC) ao init do fornecedor. que executa o comando e envia o resultado de volta ao init.
Como usar a Init do fornecedor
O init do fornecedor é ativado por padrão e as restrições dele se aplicam a todos os scripts init
presentes na partição /vendor
. O init do fornecedor deve ser transparente
para fornecedores cujos scripts já não estão acessando arquivos somente do sistema,
propriedades etc.
No entanto, se os comandos em um determinado script de fornecedor violarem o comando "init" restrições, os comandos falharão. Os comandos com falha têm uma linha no kernel log (visível com dmesg) do init indicando falha. Uma auditoria do SELinux acompanha qualquer comando com falha que falhou devido à política do SELinux. Exemplo de falha, incluindo uma auditoria do 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
Se um comando falhar, há duas opções:
- Se o comando estiver falhando devido a uma restrição pretendida (por exemplo, se o comando estiver acessando um arquivo ou propriedade do sistema), o comando deverá ser reimplementados de modo amigável ao Treble, passando apenas por interfaces estáveis. As regras Neverallow impedem a adição de permissões para acessar arquivos do sistema que não são parte da ABI do fornecedor de sistema estável.
- Se o rótulo SELinux for novo e ainda não tiver recebido permissões no
vendor_init.te
do sistema nem as permissões excluídas pelo parâmetro as regras específicas do dispositivo, o novo marcador pode receber permissõesvendor_init.te
:
Para dispositivos lançados antes do Android 9, as regras de "nunca" podem ser ignoradas com
adicionando o atributo de tipo data_between_core_and_vendor_violators
o arquivo vendor_init.te
específico do dispositivo.
Locais do código
A maior parte da lógica para a IPC init do fornecedor está em system/core/init/subcontext.cpp.
A tabela de comandos está na classe BuiltinFunctionMap
em system/core/init/builtins.cpp.
e inclui anotações que indicam se o comando precisa ser executado no provedor
subprocesso init.
O SEPolicy para init do fornecedor é dividido entre o privado (system/sepolicy/private/vendor_init.te). e público (system/sepolicy/public/vendor_init.te) diretórios em system/sepolicy.