O SELinux está configurado para negação por padrão, o que significa que cada acesso que tem um hook no kernel, precisa 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 entender como escrever as regras de política agora são essenciais ao criar novos dispositivos Android. Há um grande quantidade de informações disponíveis sobre o SELinux. Consulte Suporte documentação para recursos sugeridos.
Arquivos de chaves
Para ativar o SELinux, integre a mais recente kernel do Android e depois incorpora os arquivos encontrados na system/sepolicy (link em inglês) diretório. Quando compilados, esses arquivos formam a parte de segurança do kernel e abrangem o sistema operacional Android upstream.
Em geral, não modifique os arquivos system/sepolicy
diretamente. Adicione ou edite seus próprios arquivos de política específicos do dispositivo na
/device/manufacturer/device-name/sepolicy
diretório. No Android 8.0 e versões mais recentes, as alterações feitas nesses arquivos devem
afetam apenas a política no seu diretório de fornecedores. Para mais detalhes sobre a separação
sepolicy pública no Android 8.0 e superior, consulte
Como personalizar o SEPolicy no Android
8.0 ou superior. 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 de políticas do SELinux, que
definem os domínios e os rótulos. Talvez seja necessário criar novos arquivos de política no
/device/manufacturer/device-name/sepolicy
,
mas tente atualizar os arquivos existentes sempre que possível.
Arquivos de contexto
Nos arquivos de contexto, são especificados rótulos para os objetos.
- O
file_contexts
atribui marcadores a arquivos e é usado por vários componentes de espaço do usuário. Ao criar novas políticas, crie ou atualize este arquivo atribuir novos marcadores aos arquivos. Para aplicar os novosfile_contexts
, recrie a imagem do sistema de arquivos ou executerestorecon
no arquivo para ser remarcados. Em upgrades, as mudanças emfile_contexts
são são aplicadas automaticamente às partições do sistema e dos dados do usuário como parte da e fazer o upgrade. As mudanças também podem ser aplicadas automaticamente no upgrade para outros partições adicionando chamadasrestorecon_recursive
às arquivo init.board.rc após a montagem da partição. leitura-gravação. - O
genfs_contexts
atribui rótulos aos sistemas de arquivos, comoproc
ouvfat
que não são compatíveis com a extensão atributos. Essa configuração é carregada como parte da política do kernel, mas alterações podem não entrar em vigor para inodes no núcleo, exigindo uma reinicialização ou desmontando e remontando o sistema de arquivos para aplicar totalmente a alteração. Rótulos específicos também podem ser atribuídos a suportes específicos, comovfat
usando a opçãocontext=mount
. - O
property_contexts
atribui rótulos às propriedades do sistema Android para: e controlar quais processos podem defini-los. Essa configuração é lida pelo Processoinit
durante a inicialização. service_contexts
atribui rótulos aos serviços de vinculação do Android para controlar quais processos podem adicionar (registrar) e encontrar (procurar) um binder para o serviço. Essa configuração é lida pelo Processoservicemanager
durante a inicialização.seapp_contexts
atribui identificadores a processos de apps e/data/data
. Essa configuração é lida pelozygote
a cada inicialização do app e atéinstalld
durante a inicialização.mac_permissions.xml
atribui uma tagseinfo
aos apps com base na assinatura e, opcionalmente, no nome do pacote. A A tagseinfo
pode ser usada como uma chave na Arquivoseapp_contexts
para atribuir um marcador específico a todos os apps com a tagseinfo
. Essa configuração é lidasystem_server
durante a inicialização.keystore2_key_contexts
atribui rótulos aos namespaces do Keystore 2.0. Esse namespace é aplicado pelo daemon keystore2. O Keystore sempre os namespaces fornecidos com base em UID/AID. O Keystore 2.0 também aplica sepolicy os namespaces definidos. Uma descrição detalhada do formato e das convenções desta pode ser encontrado aqui.
Makefile do BoardConfig.mk
Depois de editar ou adicionar os arquivos de política e contexto, atualize o
/device/manufacturer/device-name/BoardConfig.mk
makefile para fazer referência ao subdiretório sepolicy
e a cada novo arquivo de política.
Para 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 recriação, o dispositivo será ativado com o SELinux. Agora é possível personalizar suas políticas de SELinux para acomodar suas próprias adições ao Sistema operacional Android, conforme descrito em Personalização ou verifique sua configuração atual conforme abordado nas Validação.
Quando os novos arquivos de política e as atualizações do BoardConfig.mk estiverem prontos, os novos as configurações de política são incorporadas automaticamente ao arquivo de política do kernel final. Para mais informações sobre como o sepolicy é criado no dispositivo, consulte Como criar sepolicy.
Implementação
Para começar a usar o SELinux:
- Ative 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 serve apenas para o desenvolvimento inicial da política para o dispositivo. Depois de tiver uma política de inicialização inicial, remova esse parâmetro para que dispositivo está aplicando ou falhará no CTS. - Inicialize o sistema como permissivo e confira 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 de avisos semelhantes a
init: Warning! Service name needs a SELinux domain defined; please fix!
. Consulte Validação para instruções e ferramentas. - Identifique dispositivos e outros arquivos novos que precisam de rotulagem.
- Use rótulos novos ou atuais para seus objetos. Observe o
*_contexts
arquivos para saber como os itens eram rotulados anteriormente e usar o conhecimento dos significados dos rótulos para atribuir um novo. Idealmente, esse será um marcador existente que se encaixa na política, mas às vezes um novo rótulo será necessário, e as regras de acesso a ele serão necessários. 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
serviços gerados por
init
, por exemplo, devem ter as por conta própria. Os comandos a seguir ajudam a revelar aqueles que continuam em execução (mas TODOS 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 os domínios que não têm um tipo de domínio. Atribua a eles um domínio no início da sua de desenvolvimento para evitar a adição de regras aoinit
ou ao confundir os acessosinit
com os da uma política própria. - Configurar
BOARD_CONFIG.mk
para usarBOARD_SEPOLICY_*
variáveis. Consulte a README emsystem/sepolicy
para mais detalhes sobre a configuração. - Analise os arquivos init.device.rc e fstab.device e
garanta que cada uso de
mount
corresponda a uma um sistema de arquivos rotulado ou que uma opçãocontext= mount
especificado. - Passe por cada negação e crie uma política do SELinux para lidar adequadamente com cada uma. Consulte os exemplos em Personalização.
Começar com as políticas no AOSP e depois se basear nelas para suas próprias personalizações. Para mais informações sobre estratégias e analisar algumas dessas etapas, ver Como escrever política do SELinux.
Casos de uso
Aqui estão alguns exemplos específicos de explorações a serem consideradas ao criar o seu próprio e políticas de SELinux associadas:
Links simbólicos - Como os links simbólicos aparecem como arquivos, eles são muitas vezes
lidos como arquivos, o que pode levar a exploits. Por exemplo, algumas contas privilegiadas
componentes, como init
, mudam as permissões de determinados arquivos,
muitas vezes fica aberta demais.
Os invasores podem 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 aplicativo nunca transferirá um link simbólico, você poderá proibi-lo de fazer isso com o SELinux.
Arquivos do sistema: considere a classe de arquivos de sistema que
só pode ser modificado pelo servidor do sistema. Ainda assim, desde netd
,
init
e vold
são executadas como raiz, podem acessar
esses arquivos de sistema. Portanto, se o netd
fica comprometido, pode
esses arquivos e possivelmente 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 o netd
ficasse comprometido, não era possível trocar de domínio para o
domínio do servidor do sistema e acessar esses arquivos de sistema, embora seja executado como raiz.
Dados do app: outro exemplo é a classe de funções que precisa ser executado como raiz, mas não deve conseguir acessar os dados do app. Isso é muito úteis, pois podem ser feitas declarações abrangentes, como determinados domínios não relacionados aos dados do aplicativo impedindo o acesso à Internet.
setattr: para comandos como chmod
e
chown
, é possível identificar o conjunto de arquivos em que o
domínio pode realizar setattr
. Qualquer coisa além disso pode ser
proibidas dessas alterações, mesmo pelo acesso raiz. Assim, um aplicativo pode executar
chmod
e chown
em relação aos rotulados
app_data_files
, mas não shell_data_files
ou system_data_files
.