O SELinux está configurado para negação padrão, o que significa que cada acesso para o qual ele tem 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 uma compreensão de como escrever regras de política agora é essencial ao trazer 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 de chave
Para habilitar o SELinux, integre o kernel Android mais recente e incorpore os arquivos encontrados no diretório system/sepolicy . Quando compilados, esses arquivos compreendem 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 do 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 superior, as alterações feitas nesses arquivos devem afetar apenas a política no diretório do fornecedor. Para obter mais detalhes sobre a separação da política de segurança pública no Android 8.0 e superior, consulte Personalizando SEPolicy no Android 8.0+ . Independentemente da versão do Android, você ainda está modificando estes arquivos:
Arquivos de política
Os arquivos que terminam com *.te
são arquivos de origem da política SELinux, que definem domínios e seus rótulos. Pode ser 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 a arquivos e é usado por vários componentes do espaço do usuário. À medida que você cria novas políticas, crie ou atualize este 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 rotulado novamente. Em upgrades, as alterações emfile_contexts
são aplicadas automaticamente ao sistema e às partições userdata como parte do upgrade. As alterações também podem ser aplicadas automaticamente na atualização para outras partições adicionando chamadasrestorecon_recursive
ao seu arquivo init. board .rc após a partição ter sido montada leitura-gravação. -
genfs_contexts
atribui rótulos a sistemas de arquivos, comoproc
ouvfat
que não suportam atributos estendidos. Essa configuração é carregada como parte da política do kernel, mas as alterações podem não ter efeito para inodes no núcleo, 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 processo deinit
durante a inicialização. -
service_contexts
atribui rótulos a serviços de binder do Android para controlar quais processos podem adicionar (registrar) e encontrar (procurar) uma referência de binder para o serviço. Essa configuração é lida pelo processo doservicemanager
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 porinstalld
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 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 pelosystem_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. Além disso, o Keystore 2.0 impõe namespaces definidos por 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 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 o 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 está habilitado com SELinux. Agora você pode personalizar suas políticas do 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 estão em vigor, as novas configurações de política são automaticamente incorporadas ao arquivo de política final do kernel. Para obter mais informações sobre como a política de segurança é criada no dispositivo, consulte Criação de política de segurança .
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
Isso é apenas para o desenvolvimento inicial da política para o dispositivo. Depois de ter uma política de bootstrap 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 para avisos semelhantes ao
init: Warning! Service name needs a SELinux domain defined; please fix!
Consulte Validação para obter instruções e ferramentas. - Identifique dispositivos e outros novos arquivos que precisam de rotulagem.
- 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 encaixará na política, mas às vezes será necessário um novo rótulo e serão necessárias regras para 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. Você provavelmente precisará escrever uma política completamente nova para cada um. Todos os serviços gerados a partir do
init
, por exemplo, devem ter 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 de seu processo de desenvolvimento para evitar adicionar regras aoinit
ou confundir 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 a inicialização. 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. - Passe por cada negação e crie uma política SELinux para lidar adequadamente com cada uma. Veja os exemplos em Personalização .
Você deve começar com as políticas no AOSP e depois criá-las para suas próprias personalizações. Para obter mais informações sobre a estratégia de política e uma análise mais detalhada de algumas dessas etapas, consulte Writing SELinux Policy .
Casos de uso
Aqui estão exemplos específicos de exploits a serem considerados 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 ficarem excessivamente abertos.
Os invasores podem substituir esses arquivos por links simbólicos para o código que eles controlam, permitindo que o invasor sobrescreva arquivos arbitrários. Mas se você sabe que seu aplicativo nunca atravessará um link simbólico, você pode proibi-lo de fazê-lo com o SELinux.
Arquivos do sistema - Considere a classe dos arquivos do sistema que devem ser modificados 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
comprometido, ele não pode alternar domínios para o domínio do servidor do sistema e acessar esses arquivos do sistema, embora seja executado como root.
Dados do aplicativo - Outro exemplo é a classe de funções que devem ser executadas como root, mas não devem acessar os dados do aplicativo. Isso é incrivelmente útil, pois afirmações abrangentes podem ser feitas, como certos domínios não relacionados a dados de aplicativos serem proibidos de acessar a Internet.
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, mesmo pelo root. Portanto, um aplicativo pode executar chmod
e chown
contra esses app_data_files
rotulados, mas não shell_data_files
ou system_data_files
.