O SELinux está configurado para negar por padrão, o que significa que todo acesso para o qual ele possui um gancho no kernel deve ser explicitamente permitido pela política. Isso significa que um arquivo de política é composto por uma grande quantidade de informações sobre regras, tipos, classes, permissões e muito mais. Uma consideração completa do SELinux está fora do escopo deste documento, mas agora é essencial compreender como escrever regras de política ao criar novos dispositivos Android. Já existe uma grande quantidade de informações disponíveis sobre o SELinux. Consulte a documentação de suporte para recursos sugeridos.
Arquivos principais
Para habilitar o SELinux, integre o kernel Android mais recente e, em seguida, incorpore os arquivos encontrados no diretório system/sepolicy . Quando compilados, esses arquivos constituem a política de segurança do kernel SELinux e cobrem o sistema operacional Android upstream.
Em geral, você não deve modificar os arquivos system/sepolicy
diretamente. Em vez disso, adicione ou edite seus próprios arquivos de política específicos do dispositivo no diretório /device/ manufacturer / device-name /sepolicy
. No Android 8.0 e versões posteriores, as alterações feitas nesses arquivos devem afetar apenas a política no seu diretório de fornecedores. Para obter mais detalhes sobre a separação da sepolicy pública no Android 8.0 e superior, consulte Personalização da SEPolicy no Android 8.0+ . Independentemente da versão do Android, você ainda está modificando estes arquivos:
Arquivos de política
Arquivos que terminam com *.te
são arquivos de origem de políticas do SELinux, que definem domínios e seus rótulos. Talvez seja necessário criar novos arquivos de política em /device/ manufacturer / device-name /sepolicy
, mas você deve tentar atualizar os arquivos existentes sempre que possível.
Arquivos de contexto
Os arquivos de contexto são onde você especifica rótulos para seus objetos.
-
file_contexts
atribui rótulos aos arquivos e é usado por vários componentes do espaço do usuário. À medida que você cria novas políticas, crie ou atualize esse arquivo para atribuir novos rótulos aos arquivos. Para aplicar novosfile_contexts
, reconstrua a imagem do sistema de arquivos ou executerestorecon
no arquivo a ser renomeado. Nas atualizações, as alterações emfile_contexts
são aplicadas automaticamente ao sistema e às partições userdata como parte da atualização. As alterações também podem ser aplicadas automaticamente na atualização para outras partições, adicionando chamadasrestorecon_recursive
ao seu init. board .rc após a partição ter sido montada em leitura e gravação. -
genfs_contexts
atribui rótulos a sistemas de arquivos, comoproc
ouvfat
, que não suportam atributos estendidos. Esta configuração é carregada como parte da política do kernel, mas as alterações podem não ter efeito para inodes in-core, exigindo uma reinicialização ou desmontagem e remontagem do sistema de arquivos para aplicar totalmente a alteração. Rótulos específicos também podem ser atribuídos a montagens específicas, comovfat
usando a opçãocontext=mount
. -
property_contexts
atribui rótulos às propriedades do sistema Android para controlar quais processos podem defini-los. Esta configuração é lida pelo processoinit
durante a inicialização. -
service_contexts
atribui rótulos aos serviços de binder do Android para controlar quais processos podem adicionar (registrar) e encontrar (pesquisar) uma referência de binder para o serviço. Esta configuração é lida pelo processoservicemanager
durante a inicialização. -
seapp_contexts
atribui rótulos a processos de aplicativos e diretórios/data/data
. Essa configuração é lida pelo processozygote
em cada inicialização do aplicativo e peloinstalld
durante a inicialização. -
mac_permissions.xml
atribui uma tagseinfo
aos aplicativos com base em sua assinatura e, opcionalmente, no nome do pacote. A tagseinfo
pode então ser usada como uma chave no arquivoseapp_contexts
para atribuir um rótulo específico a todos os aplicativos com essa tagseinfo
. Esta configuração é lida porsystem_server
durante a inicialização. -
keystore2_key_contexts
atribui rótulos aos namespaces do Keystore 2.0. Esses namespaces são impostos pelo daemon keystore2. O Keystore sempre forneceu namespaces baseados em UID/AID. O Keystore 2.0 também impõe namespaces definidos pela sepolicy. Uma descrição detalhada do formato e convenções deste arquivo pode ser encontrada aqui .
Makefile BoardConfig.mk
Depois de editar ou adicionar arquivos de política e de contexto, atualize seu makefile /device/ manufacturer / device-name /BoardConfig.mk
para fazer referência ao subdiretório sepolicy
e a cada novo arquivo de política. Para obter mais informações sobre as variáveis BOARD_SEPOLICY
, consulte arquivo system/sepolicy/README
.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
Após a reconstrução, seu dispositivo estará habilitado com SELinux. Agora você pode personalizar suas políticas SELinux para acomodar suas próprias adições ao sistema operacional Android, conforme descrito em Personalização , ou verificar sua configuração existente, conforme abordado em Validação .
Quando os novos arquivos de política e as atualizações do BoardConfig.mk estiverem em vigor, as novas configurações de política serão automaticamente incorporadas ao arquivo de política do kernel final. Para obter mais informações sobre como a sepolicy é criada no dispositivo, consulte Construindo sepolicy .
Implementação
Para começar com o SELinux:
- Habilite o SELinux no kernel:
CONFIG_SECURITY_SELINUX=y
- Altere o parâmetro kernel_cmdline ou bootconfig para que:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
ouBOARD_BOOTCONFIG := androidboot.selinux=permissive
Isto seja apenas para o desenvolvimento inicial da política para o dispositivo. Depois de ter uma política de inicialização inicial, remova esse parâmetro para que seu dispositivo seja aplicado ou ele falhará no CTS. - Inicialize o sistema de forma permissiva e veja quais negações são encontradas na inicialização:
No Ubuntu 14.04 ou mais recente:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
No Ubuntu 12.04:adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- Avalie a saída em busca de avisos semelhantes a
init: Warning! Service name needs a SELinux domain defined; please fix!
Consulte Validação para obter instruções e ferramentas. - Identifique dispositivos e outros arquivos novos que precisam ser rotulados.
- Use rótulos novos ou existentes para seus objetos. Observe os arquivos
*_contexts
para ver como as coisas foram rotuladas anteriormente e use o conhecimento dos significados dos rótulos para atribuir um novo. Idealmente, este será um rótulo existente que se enquadrará na política, mas por vezes será necessário um novo rótulo e serão necessárias regras para o acesso a esse rótulo. Adicione seus rótulos aos arquivos de contexto apropriados. - Identifique domínios/processos que devem ter seus próprios domínios de segurança. Provavelmente, você precisará escrever uma política completamente nova para cada um. Todos os serviços gerados a partir de
init
, por exemplo, devem ter os seus próprios. Os comandos a seguir ajudam a revelar aqueles que permanecem em execução (mas TODOS os serviços precisam desse tratamento):adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- Revise
init. device .rc
para identificar quaisquer domínios que não tenham um tipo de domínio. Dê a eles um domínio no início do seu processo de desenvolvimento para evitar adicionar regras aoinit
ou confundir os acessosinit
com aqueles que estão em sua própria política. - Configure
BOARD_CONFIG.mk
para usar variáveisBOARD_SEPOLICY_*
. Consulte o README emsystem/sepolicy
para obter detalhes sobre como configurar isso. - Examine o arquivo init. device .rc e fstab. device e certifique-se de que cada uso de
mount
corresponda a um sistema de arquivos devidamente rotulado ou que uma opçãocontext= mount
seja especificada. - Analise cada negação e crie uma política SELinux para lidar adequadamente com cada uma. Veja os exemplos em Customização .
Você deve começar com as políticas no AOSP e depois desenvolvê-las para suas próprias personalizações. Para obter mais informações sobre a estratégia política e uma análise mais detalhada de algumas dessas etapas, consulte Escrevendo políticas do SELinux .
Casos de uso
Aqui estão exemplos específicos de explorações a serem consideradas ao criar seu próprio software e políticas SELinux associadas:
Links simbólicos - Como os links simbólicos aparecem como arquivos, eles geralmente são lidos como arquivos, o que pode levar a explorações. Por exemplo, alguns componentes privilegiados, como init
, alteram as permissões de determinados arquivos, às vezes para serem excessivamente abertos.
Os invasores podem então substituir esses arquivos por links simbólicos para o código que controlam, permitindo que o invasor substitua arquivos arbitrários. Mas se você sabe que seu aplicativo nunca atravessará um link simbólico, você pode proibi-lo de fazer isso com o SELinux.
Arquivos de sistema - Considere a classe de arquivos de sistema que deve ser modificada apenas pelo servidor do sistema. Ainda assim, como netd
, init
e vold
são executados como root, eles podem acessar esses arquivos do sistema. Portanto, se netd
for comprometido, poderá comprometer esses arquivos e, potencialmente, o próprio servidor do sistema.
Com o SELinux, você pode identificar esses arquivos como arquivos de dados do servidor do sistema. Portanto, o único domínio que tem acesso de leitura/gravação a eles é o servidor do sistema. Mesmo que netd
fosse comprometido, ele não poderia mudar de domínio para o domínio do servidor do sistema e acessar esses arquivos do sistema, embora fosse executado como root.
Dados do aplicativo - Outro exemplo é a classe de funções que deve ser executada como root, mas não deve acessar os dados do aplicativo. Isso é extremamente útil, pois podem ser feitas afirmações abrangentes, como a proibição de acesso à Internet de determinados domínios não relacionados aos dados do aplicativo.
setattr - Para comandos como chmod
e chown
, você pode identificar o conjunto de arquivos onde o domínio associado pode conduzir setattr
. Qualquer coisa fora disso pode ser proibida dessas alterações, até mesmo pelo root. Portanto, um aplicativo pode executar chmod
e chown
naqueles rotulados, app_data_files
, mas não em shell_data_files
ou system_data_files
.