Depois de integrar o nível básico da funcionalidade do SELinux e analisar os resultados, adicione suas próprias configurações de política para abranger as personalizações no sistema operacional Android. Essas políticas ainda precisam atender aos requisitos do Programa de compatibilidade do Android e não podem remover as configurações padrão do SELinux.
Os fabricantes não podem remover a política de SELinux atual. Caso contrário, eles arriscam quebrar a implementação do SELinux do Android e os apps que ele governa. Isso inclui apps de terceiros que provavelmente precisarão ser aprimorados para serem compatíveis e operacionais. Os apps não podem exigir modificações para continuar funcionando em dispositivos com SELinux ativado.
Ao personalizar o SELinux, lembre-se de:
- Gravar a política do SELinux para todos os novos daemons
- Use domínios predefinidos sempre que apropriado
- Atribuir um domínio a qualquer processo gerado como um serviço
init
- Conheça a política de macros antes de escrever
- Enviar mudanças na política principal para o AOSP
E não faça o seguinte:
- Criar política incompatível
- Permitir a personalização da política do usuário final
- Permitir personalizações de política de MDM
- Assustar os usuários com violações de políticas
- Adicionar backdoors
Consulte a seção Recursos de segurança do kernel do documento de definição de compatibilidade do Android para requisitos específicos.
O SELinux usa uma abordagem de lista de permissões, o que significa que todo o acesso precisa ser explicitamente permitido na política para ser concedido. Como a política SELinux padrão do Android já oferece suporte ao Android Open Source Project, não é necessário modificar as configurações do SELinux de nenhuma forma. Se você personalizar as configurações do SELinux, tenha cuidado para não corromper os apps que já existem. Para começar, faça o seguinte:
- Use o kernel mais recente do Android.
- Adote o princípio do menor privilégio.
- Abordar apenas suas próprias adições ao Android. A política padrão funciona com a base de código do Android Open Source Project automaticamente.
- Compartimentalizar componentes de software em módulos que realizam tarefas únicas.
- Crie políticas do SELinux que isolem essas tarefas de funções não relacionadas.
- Coloque essas políticas em arquivos
*.te
(a extensão para arquivos de origem de política do SELinux) no diretório/device/manufacturer/device-name/sepolicy
e use variáveisBOARD_SEPOLICY
para incluí-las no seu build. - Torne os novos domínios permissivos inicialmente. Isso é feito usando uma declaração
permissiva no arquivo
.te
do domínio. - Analise os resultados e refine suas definições de domínio.
- Remova a declaração permissiva quando nenhuma outra negação aparecer nos builds userdebug.
Depois de integrar a alteração da política do SELinux, adicione uma etapa ao fluxo de trabalho de desenvolvimento para garantir a compatibilidade com o SELinux no futuro. Em um processo ideal de desenvolvimento de software, a política do SELinux muda apenas quando o modelo de software muda, e não a implementação real.
Ao começar a personalizar o SELinux, primeiro audite suas adições no Android. Se você adicionou um componente que executa uma nova função, verifique se ele atende à política de segurança do Android e a qualquer política associada criada pelo OEM antes de ativar o modo de aplicação.
Para evitar problemas desnecessários, é melhor ser muito amplo e compatível do que muito restritivo e incompatível, o que resulta em funções de dispositivo corrompidas. Por outro lado, se as mudanças beneficiarem outras pessoas, envie as modificações para a política SELinux padrão como um patch. Se o patch for aplicado à política de segurança padrão, não será necessário fazer essa mudança em cada nova versão do Android.
Exemplos de declarações de política
O SELinux é baseado na linguagem de computador M4 e, portanto, oferece suporte a várias macros para economizar tempo.
No exemplo a seguir, todos os domínios recebem acesso de leitura ou gravação em /dev/null
e leitura de /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 };
Essa mesma instrução pode ser escrita com macros *_file_perms
do SELinux (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;
Exemplo de política
Veja abaixo um exemplo completo de política para DHCP:
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 };
Vamos analisar o exemplo:
Na primeira linha, a declaração de tipo, o daemon DHCP herda da
política de segurança básica (domain
). Com base nos exemplos de instrução
anteriores, o DHCP pode ler e gravar em /dev/null
.
Na segunda linha, o DHCP é identificado como um domínio permissivo.
Na linha init_daemon_domain(dhcp)
, a política declara que o DHCP é
gerado de init
e tem permissão para se comunicar com ele.
Na linha net_domain(dhcp)
, a política permite que o DHCP use
funcionalidades de rede comuns do domínio net
, como ler
e gravar pacotes TCP, comunicar-se por soquetes e conduzir solicitações
DNS.
Na linha allow dhcp proc_net:file write;
, a política indica
que o DHCP pode gravar em arquivos específicos em /proc
. Esta linha demonstra a rotulação refinada
de arquivos do SELinux. Ele usa o rótulo proc_net
para limitar o acesso de gravação apenas aos arquivos em /proc/sys/net
.
O bloco final do exemplo que começa com
allow dhcp netd:fd use;
mostra como os apps podem interagir
entre si. A política diz que o DHCP e o netd podem se comunicar entre
si por descritores de arquivos, arquivos FIFO, soquetes de datagrama e soquetes de fluxo
UNIX. O DHCP só pode ler e gravar nos soquetes de datagrama e nos soquetes de fluxo
do UNIX, e não pode criar nem abrir esses soquetes.
Controles disponíveis
Classe | Permissão |
---|---|
arquivo |
ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton |
diretório |
add_name remove_name reparent search rmdir open audit_access execmod |
soquete |
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 arquivos |
mount remount unmount getattr relabelfrom relabelto transition associate quotamod quotaget |
Processo |
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 |
segurança |
compute_av compute_create compute_member check_context load_policy compute_relabel compute_user setenforce setbool setsecparam setcheckreqprot read_policy |
capacidade |
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 |
MAIS |
E MAIS |
regras de nunca permitir
As regras neverallow
do SELinux proíbem comportamentos que nunca devem ocorrer.
Com o teste de compatibilidade,
as regras neverallow
do SELinux agora são aplicadas em todos os dispositivos.
As diretrizes a seguir têm o objetivo de ajudar os fabricantes a evitar erros
relacionados às regras neverallow
durante a personalização. Os números de regra
usados aqui correspondem ao Android 5.1 e estão sujeitos a alterações por versão.
Regra 48: neverallow { domain -debuggerd -vold -dumpstate
-system_server } self:capability sys_ptrace;
Consulte a página do manual de ptrace
. O recurso sys_ptrace
concede a capacidade de ptrace
qualquer processo, o que permite um grande
controle sobre outros processos e deve pertencer apenas a componentes
do sistema designados, descritos na regra. A necessidade desse recurso geralmente indica
a presença de algo que não se destina a builds voltados ao usuário ou
funcionalidades que não são necessárias. Remova o componente desnecessário.
Regra 76: neverallow { domain -appdomain -dumpstate
-shell -system_server -zygote } { file_type -system_file -exec_type }:file execute;
O objetivo desta regra é impedir a execução de código arbitrário no sistema.
Especificamente, ele garante que apenas o código em /system
seja executado,
o que permite garantias de segurança graças a mecanismos como a inicialização verificada.
Muitas vezes, a melhor solução ao encontrar um problema com essa
regra neverallow
é mover o código com problemas para a
partição /system
.
Personalizar o SEPolicy no Android 8.0 e versões mais recentes
Esta seção apresenta diretrizes para a política SELinux do fornecedor no Android 8.0 e versões mais recentes, incluindo detalhes sobre o Projeto de código aberto do Android (AOSP) SEPolicy e as extensões SEPolicy. Para mais informações sobre como a política do SELinux é mantida compatível com partições e versões do Android, consulte Compatibilidade.
Posicionamento da política
No Android 7.0 e versões anteriores, os fabricantes de dispositivos poderiam adicionar uma política ao
BOARD_SEPOLICY_DIRS
, incluindo uma política criada para aumentar a política do AOSP
em diferentes tipos de dispositivos. No Android 8.0 e versões mais recentes, a adição de uma política a
BOARD_SEPOLICY_DIRS
coloca a política apenas na imagem
do fornecedor.
No Android 8.0 e versões mais recentes, a política existe nos seguintes locais no AOSP:
- system/sepolicy/public. Inclui a política exportada para uso
na política específica do fornecedor. Tudo vai para a infraestrutura de compatibilidade
do Android 8.0.
A política pública é mantida em todas as versões para que você possa incluir
qualquer
/public
na sua política personalizada. Por isso, o tipo de política que pode ser colocado em/public
é mais restrito. Considere essa a API de política exportada da plataforma: tudo o que lida com a interface entre/system
e/vendor
pertence a esse grupo. - system/sepolicy/private. Inclui a política necessária para o funcionamento da imagem do sistema, mas a política de imagem do fornecedor não precisa ter conhecimento.
- system/sepolicy/vendor. Inclui a política para componentes que
vão para
/vendor
, mas existem na árvore de plataforma principal (não diretórios específicos do dispositivo). Esse é um artefato da distinção entre dispositivos e componentes globais do sistema de build. Conceitos são parte da política específica do dispositivo descrita abaixo. - device/manufacturer/device-name/sepolicy. Inclui a política específica do dispositivo. Também inclui personalizações do dispositivo para a política, que no Android 8.0 e versões mais recentes corresponde à política para componentes na imagem do fornecedor.
No Android 11 e versões mais recentes, as partições system_ext e do produto também podem incluir políticas específicas da partição. As políticas system_ext e do produto também são divididas em públicas e privadas, e os fornecedores podem usar as políticas públicas do system_ext e do produto, como a política do sistema.
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS
. Inclui a política exportada para uso na política específica do fornecedor. Instalado na partição system_ext.SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS
. Inclui a política necessária para o funcionamento da imagem system_ext, mas da qual a política de imagem do fornecedor não tem conhecimento. Instalado na partição system_ext.PRODUCT_PUBLIC_SEPOLICY_DIRS
. Inclui a política exportada para uso na política específica do fornecedor. Instalado na partição do produto.PRODUCT_PRIVATE_SEPOLICY_DIRS
: inclui a política necessária para o funcionamento da imagem do produto, mas da qual a política de imagem do fornecedor não precisa ter conhecimento. Instalada na partição do produto.
Cenários de política com suporte
Em dispositivos lançados com o Android 8.0 e versões mais recentes, a imagem do fornecedor precisa funcionar com a imagem do sistema do OEM e a imagem do sistema AOSP de referência fornecida pelo Google (e transmitir o CTS nesta imagem de referência). Esses requisitos garantem uma separação limpa entre o framework e o código do fornecedor. Esses dispositivos são compatíveis com os seguintes cenários.
extensões somente de imagem do fornecedor
Exemplo:adicionar um novo serviço a vndservicemanager
na imagem do fornecedor que oferece suporte a processos da imagem do fornecedor.
Como nos dispositivos lançados com versões anteriores do Android, adicione a personalização
específica do dispositivo em
device/manufacturer/device-name/sepolicy
.
A nova política que rege como os componentes do fornecedor interagem (apenas) com outros componentes
precisa envolver os tipos presentes apenas em
device/manufacturer/device-name/sepolicy
.
A política escrita aqui permite que o código do fornecedor funcione, não será atualizada como parte
de um OTA somente de framework e está presente na política combinada em um dispositivo
com a imagem de sistema AOSP de referência.
Suporte de imagem do fornecedor para trabalhar com o AOSP
Exemplo:adição de um novo processo (registrado com
hwservicemanager
da imagem do fornecedor) que implementa um
HAL definido pelo AOSP.
Como nos dispositivos lançados com versões anteriores do Android, realize
personalizações específicas do dispositivo em
device/manufacturer/device-name/sepolicy
.
A política exportada como parte do system/sepolicy/public/
está disponível para uso e é enviada como parte da política do fornecedor. Os tipos e atributos da
política pública podem ser usados em novas regras que ditam as interações com os novos
bits específicos do fornecedor, sujeitos às restrições
neverallow
fornecidas. Assim como no caso exclusivo do fornecedor, a nova política aqui não será atualizada
como parte de uma OTA exclusiva do framework e estará presente na política combinada em um
dispositivo com a imagem de sistema AOSP de referência.
extensões somente para imagens do sistema
Exemplo:adição de um novo serviço (registrado no servicemanager) que é acessado apenas por outros processos a partir da imagem do sistema.
Adicione essa política a system/sepolicy/private
. É possível adicionar
processos ou objetos extras para ativar a funcionalidade em uma imagem do sistema do parceiro, desde que
esses novos bits não precisem interagir com novos componentes na imagem do fornecedor.
Especificamente, esses processos ou objetos precisam funcionar totalmente sem a política da
imagem do fornecedor. A política exportada por system/sepolicy/public
está
disponível aqui, assim como para extensões somente de imagem do fornecedor. Essa política faz
parte da imagem do sistema e pode ser atualizada em uma OTA somente de framework, mas não
estará presente ao usar a imagem do sistema AOSP de referência.
extensões de imagem do fornecedor que servem componentes estendidos do AOSP
Exemplo:um HAL novo que não é do AOSP para uso por clientes estendidos que também existem na imagem do sistema do AOSP (como um system_server estendido).
A política de interação entre o sistema e o fornecedor precisa ser incluída no diretório
device/manufacturer/device-name/sepolicy
enviado na partição do fornecedor.
Isso é semelhante ao cenário acima de adicionar suporte à imagem do fornecedor para trabalhar
com a imagem de referência do AOSP, exceto que os componentes modificados do AOSP também podem
requerer uma política adicional para operar corretamente com o restante da partição
do sistema (o que é aceitável, desde que eles ainda tenham os rótulos de tipo AOSP
público).
A política de interação de componentes públicos do AOSP com extensões
somente de imagem do sistema precisa estar em system/sepolicy/private
.
extensões de imagem do sistema que acessam apenas interfaces AOSP
Exemplo:um novo processo do sistema não AOSP precisa acessar uma HAL de que o AOSP depende.
Isso é semelhante ao exemplo de extensão
somente para imagem do sistema, exceto que novos componentes do sistema podem interagir na
interface system/vendor
. A política do novo componente do sistema precisa
estar em system/sepolicy/private
, o que é aceitável, desde que seja
por uma interface já estabelecida pelo AOSP em
system/sepolicy/public
, ou seja, os tipos e atributos necessários para
a funcionalidade existem. Embora a política possa ser incluída na política específica do
dispositivo, ela não poderia usar outros tipos de system/sepolicy/private
ou fazer mudanças (de qualquer maneira que afete a política) como resultado de uma atualização somente
de framework. A política pode ser alterada em uma OTA somente de framework, mas não será
apresentada ao usar uma imagem do sistema AOSP, que também não terá o novo componente
do sistema.
extensões de imagem do fornecedor que servem novos componentes do sistema
Exemplo:adição de um HAL não AOSP para uso por um processo de cliente sem um análogo AOSP (e, portanto, requer o próprio domínio).
Assim como no exemplo de extensões
AOSP, a política para interações entre o sistema e o fornecedor precisa ser colocada no
diretório
device/manufacturer/device-name/sepolicy
enviado na partição do fornecedor
para garantir que a política do sistema não tenha conhecimento de detalhes específicos do fornecedor. Você
pode adicionar novos tipos públicos que estendem a política em
system/sepolicy/public
. Isso deve ser feito apenas além da
política AOSP atual, ou seja, não remova a política pública do AOSP. Os novos tipos
públicos podem ser usados para a política em system/sepolicy/private
e em
device/manufacturer/device-name/sepolicy
.
Lembre-se de que cada adição a system/sepolicy/public
aumenta
a complexidade expondo uma nova garantia de compatibilidade que precisa ser rastreada em um
arquivo de mapeamento e que está sujeita a outras restrições. Somente novos tipos e
regras de permissão correspondentes podem ser adicionados em system/sepolicy/public
.
Não há suporte para atributos e outras declarações de política. Além disso, os novos
tipos públicos não podem ser usados para rotular objetos diretamente na
política /vendor
.
Cenários de política sem suporte
Os dispositivos lançados com o Android 8.0 e versões mais recentes não oferecem suporte ao cenário e aos exemplos de política a seguir.
Extensões adicionais à imagem do sistema que precisam de permissão para novos componentes da imagem do fornecedor após uma OTA somente de framework
Exemplo:um novo processo de sistema não AOSP, que exige o próprio domínio, foi adicionado na próxima versão do Android e precisa de acesso a uma nova HAL não AOSP.
Semelhante à
interação de
novos componentes do sistema e do fornecedor (não AOSP), exceto que o novo tipo de sistema
é introduzido em uma
OTA somente de framework. Embora o novo tipo possa ser adicionado à política em
system/sepolicy/public
, a política do fornecedor atual não tem conhecimento
do novo tipo, porque está rastreando apenas a política pública do sistema Android 8.0.
O AOSP lida com isso expondo recursos fornecidos pelo fornecedor por um atributo (por exemplo,
o atributo hal_foo
), mas como as extensões de parceiro de atributo não são
compatíveis com system/sepolicy/public
, esse método não está disponível para
a política do fornecedor. O acesso precisa ser fornecido por um tipo público existente anteriormente.
Exemplo:uma mudança em um processo do sistema (AOSP ou não AOSP) precisa mudar a forma como ele interage com o novo componente do fornecedor que não é do AOSP.
A política na imagem do sistema precisa ser escrita sem o conhecimento de personalizações
específicas do fornecedor. A política relacionada a interfaces específicas no AOSP é
exposta por atributos em system/sepolicy/public para que a política do fornecedor possa
ser ativada para uma política de sistema futura que use esses atributos. No entanto,
não há suporte para extensões de atributo em system/sepolicy/public
. Portanto, todas as políticas que determinam como os componentes do sistema interagem
com novos componentes do fornecedor (e que não são processadas por atributos já
presentes no AOSP system/sepolicy/public
) precisam estar em
device/manufacturer/device-name/sepolicy
.
Isso significa que os tipos de sistema não podem mudar
o acesso permitido aos tipos de fornecedores como parte de uma OTA somente de framework.