Este artigo aborda como a política do SELinux é construída. A política do SELinux é construída a partir da combinação da política principal do AOSP (plataforma) e da política específica do dispositivo (fornecedor). O fluxo de compilação da política SELinux para Android 4.4 a Android 7.0 mesclava todos os fragmentos de sepolicy e gerava arquivos monolíticos no diretório raiz. Isso significava que os fornecedores de SoC e fabricantes de ODM modificavam boot.img
(para dispositivos não A/B) ou system.img
(para dispositivos A/B) toda vez que a política era modificada.
No Android 8.0 e superior, a política de plataforma e fornecedor é criada separadamente. SOCs e OEMs podem atualizar suas partes da política, criar suas imagens (como vendor.img
e boot.img
) e atualizar essas imagens independentemente das atualizações da plataforma.
No entanto, como os arquivos de política SELinux modularizados são armazenados em partições /vendor
, o processo init
deve montar as partições do sistema e do fornecedor antes para que possa ler os arquivos SELinux dessas partições e mesclá-los com os arquivos principais do SELinux no diretório do sistema (antes de carregá-los no o núcleo).
Arquivos Fonte
A lógica para construir o SELinux está nestes arquivos:
-
external/selinux
: Projeto SELinux externo, usado para construir utilitários de linha de comando HOST para compilar a política e os rótulos do SELinux.-
external/selinux/libselinux
: o Android usa apenas um subconjunto do projetolibselinux
externo junto com algumas personalizações específicas do Android. Para obter detalhes, consulteexternal/selinux/README.android
. -
external/selinux/libsepol
: -
external/selinux/checkpolicy
: compilador de política SELinux (executáveis do host:checkpolicy
,checkmodule
edispol
). Depende delibsepol
.
-
-
system/sepolicy
: configurações principais de política do Android SELinux, incluindo contextos e arquivos de política. A lógica principal de compilação de sepolicy também está aqui (system/sepolicy/Android.mk
).
Para mais detalhes sobre os arquivos em system/sepolicy
Implementando o SELinux .
Android 7.0 e anteriores
Esta seção aborda como a política SELinux é criada no Android 7.xe anterior.
Criando a política do SELinux
A política SELinux é criada combinando a política principal do AOSP com personalizações específicas do dispositivo. A política combinada é então passada para o compilador de políticas e vários verificadores. A personalização específica do dispositivo é feita através da variável BOARD_SEPOLICY_DIRS
definida no arquivo Boardconfig.mk
específico do dispositivo. Essa variável de construção global contém uma lista de diretórios que especificam a ordem na qual procurar arquivos de política adicionais.
Por exemplo, um fornecedor de SoC e um ODM podem adicionar um diretório, um para as configurações específicas do SoC e outro para as configurações específicas do dispositivo, para gerar as configurações finais do SELinux para um determinado dispositivo:
-
BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
-
BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy
O conteúdo dos arquivos file_contexts em system/sepolicy
e BOARD_SEPOLICY_DIRS
são concatenados para gerar o file_contexts.bin
no dispositivo:
![Esta imagem mostra a lógica de compilação do SELinux para o Android 7.x.](https://source.android.google.cn/static/security/selinux/images/n-selinux-build-logic.png?authuser=4&hl=pt-br)
O arquivo sepolicy
consiste em vários arquivos de origem:
- O
policy.conf
de texto simples é gerado concatenandosecurity_classes
,initial_sids
, arquivos*.te
,genfs_contexts
eport_contexts
nessa ordem. - Para cada arquivo (como
security_classes
), seu conteúdo é a concatenação dos arquivos com o mesmo nome emsystem/sepolicy/
eBOARDS_SEPOLICY_DIRS
. - O
policy.conf
é enviado ao compilador SELinux para verificação de sintaxe e compilado em formato binário comosepolicy
no dispositivo.Figura 2 . arquivo de política SELinux
Arquivos SELinux
Após a compilação, os dispositivos Android com versão 7.xe anteriores normalmente contêm os seguintes arquivos relacionados ao SELinux:
-
selinux_version
- sepolicy: saída binária após a combinação de arquivos de política (como
security_classes
,initial_sids
e*.te
) -
file_contexts
-
property_contexts
-
seapp_contexts
-
service_contexts
-
system/etc/mac_permissions.xml
Para obter mais detalhes, consulte Implementando o SELinux .
Inicialização do SELinux
Quando o sistema inicializa, o SELinux está no modo permissivo (e não no modo de imposição). O processo init executa as seguintes tarefas:
- Carrega arquivos de
sepolicy
do ramdisk no kernel por meio de/sys/fs/selinux/load
. - Muda o SELinux para o modo de imposição.
- Executa
re-exec()
para aplicar a regra de domínio SELinux a si mesmo.
Para diminuir o tempo de inicialização, execute o re-exec()
no processo de init
o mais rápido possível.
Android 8.0 e superior
No Android 8.0, a política do SELinux é dividida em componentes de plataforma e fornecedor para permitir atualizações independentes de política de plataforma/fornecedor, mantendo a compatibilidade.
A política de segurança da plataforma é dividida em partes privadas da plataforma e partes públicas da plataforma para exportar tipos e atributos específicos para os criadores de políticas do fornecedor. Os tipos/atributos públicos da plataforma são mantidos como APIs estáveis para uma determinada versão da plataforma. A compatibilidade com tipos/atributos públicos da plataforma anterior pode ser garantida para várias versões usando arquivos de mapeamento de plataforma.
Política de segurança pública da plataforma
A política de segurança pública da plataforma inclui tudo definido em system/sepolicy/public
. A plataforma pode assumir que os tipos e atributos definidos nas políticas públicas são APIs estáveis para uma determinada versão da plataforma. Isso faz parte da sepolicy que é exportada pela plataforma na qual os desenvolvedores de políticas do fornecedor (ou seja, do dispositivo) podem escrever políticas adicionais específicas do dispositivo.
Os tipos são versionados de acordo com a versão da política na qual os arquivos do fornecedor são gravados, definida pela variável de construção PLATFORM_SEPOLICY_VERSION
. A política pública com versão é então incluída na política do fornecedor e (em sua forma original) na política da plataforma. Assim, a política final inclui a política de plataforma privada, a política de segurança pública da plataforma atual, a política específica do dispositivo e a política pública versionada correspondente à versão da plataforma na qual a política do dispositivo foi escrita.
Sepolicy privado da plataforma
A política de segurança privada da plataforma inclui tudo definido em /system/sepolicy/private
. Essa parte da política forma tipos, permissões e atributos somente de plataforma necessários para a funcionalidade da plataforma. Eles não são exportados para os escritores de política de vendor/device
. Os criadores de políticas que não são de plataforma não devem gravar suas extensões de política com base em tipos/atributos/regras definidas na sepolicy privada da plataforma. Além disso, essas regras podem ser modificadas ou podem desaparecer como parte de uma atualização somente da estrutura.
Mapeamento privado da plataforma
O mapeamento privado da plataforma inclui declarações de política que mapeiam os atributos expostos na política pública da plataforma das versões anteriores da plataforma para os tipos concretos usados na política pública da plataforma atual. Isso garante que a política do fornecedor que foi escrita com base nos atributos públicos da plataforma da(s) versão(ões) de política pública da plataforma anterior continue funcionando. O controle de versão é baseado na variável de construção PLATFORM_SEPOLICY_VERSION
definida no AOSP para uma determinada versão da plataforma. Existe um arquivo de mapeamento separado para cada versão de plataforma anterior da qual se espera que essa plataforma aceite a política do fornecedor. Para obter mais detalhes, consulte Compatibilidade .
Android 11 e superior
system_ext e sepolicy do produto
No Android 11, a política system_ext e a política do produto são adicionadas. Assim como a sepolicy da plataforma, a política system_ext e a política do produto são divididas em política pública e política privada.
A política pública é exportada para o fornecedor. Tipos e atributos se tornam APIs estáveis, e a política do fornecedor pode se referir a tipos e atributos na política pública. Os tipos são versionados de acordo com PLATFORM_SEPOLICY_VERSION
e a política versionada é incluída na política do fornecedor. A política original está incluída em cada partição do system_ext e do produto.
A política privada contém tipos, permissões e atributos somente system_ext e somente produto, necessários para a funcionalidade das partições system_ext e do produto. A política privada é invisível para o fornecedor, o que implica que essas regras são internas e podem ser modificadas.
system_ext e mapeamento de produtos
system_ext e product podem exportar seus tipos públicos designados para o fornecedor. No entanto, a responsabilidade de manter a compatibilidade é de cada parceiro. Para compatibilidade, os parceiros podem fornecer seus próprios arquivos de mapeamento que mapeiam os atributos de versão de versões anteriores para tipos concretos usados na política pública atual.
- Para instalar um arquivo de mapeamento para system_ext, coloque um arquivo cil contendo as informações de mapeamento desejadas em
{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
e adicionesystem_ext_{ver}.cil
aPRODUCT_PACKAGES
. - Para instalar um arquivo de mapeamento para o produto, coloque um arquivo cil contendo as informações de mapeamento desejadas em
{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
e adicioneproduct_{ver}.cil
aPRODUCT_PACKAGES
. Consulte um exemplo que adiciona um arquivo de mapeamento da partição do produto do dispositivo redbull. - Convertendo políticas para o formato SELinux Common Intermediate Language (CIL), especificamente:
- política de plataforma pública (sistema + system_ext + produto)
- política privada + pública combinada
- política pública + fornecedor e
BOARD_SEPOLICY_DIRS
- Controle de versão da política fornecida pelo público como parte da política do fornecedor. Feito usando a política CIL pública produzida para informar a política combinada público + fornecedor +
BOARD_SEPOLICY_DIRS
sobre quais partes devem ser transformadas em atributos que serão vinculados à política da plataforma. - Criando um arquivo de mapeamento ligando a plataforma e as partes do fornecedor. Inicialmente, isso apenas vincula os tipos da política pública com os atributos correspondentes na política do fornecedor; posteriormente, também fornecerá a base para o arquivo mantido em versões futuras da plataforma, permitindo a compatibilidade com a política do fornecedor direcionada a essa versão da plataforma.
- Combinando arquivos de política (descreva soluções no dispositivo e pré-compiladas).
- Combine mapeamento, plataforma e política de fornecedores.
- Compile o arquivo de política binária de saída.
- Ambos
/system/etc/selinux/plat_sepolicy_and_mapping.sha256
e/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256
existem e são idênticos. - Ambos
/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256
e/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256
não existem. Ou ambos existem e são idênticos. - Ambos
/product/etc/selinux/product_sepolicy_and_mapping.sha256
e/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256
não existem. Ou ambos existem e são idênticos.
Criando a política do SELinux
A política do SELinux no Android 8.0 é feita combinando partes de /system
e /vendor
. A lógica para configurar isso adequadamente está em /platform/system/sepolicy/Android.mk
.
A política existe nos seguintes locais:
Localização | Contém |
---|---|
system/sepolicy/public | API de sepolicy da plataforma |
system/sepolicy/private | Detalhes de implementação da plataforma (os fornecedores podem ignorar) |
system/sepolicy/vendor | Arquivos de política e contexto que os fornecedores podem usar (os fornecedores podem ignorar, se desejar) |
BOARD_SEPOLICY_DIRS | Política de segurança do fornecedor |
BOARD_ODM_SEPOLICY_DIRS (Android 9 e superior) | Sepolicy Odm |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 e superior) | API de sepolicy do System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 e superior) | Detalhes de implementação do System_ext (os fornecedores podem ignorar) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 e superior) | API de sepolicy do produto |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 e superior) | Detalhes de implementação do produto (os fornecedores podem ignorar) |
O sistema de compilação usa essa política e produz componentes de política system, system_ext, product, vendor e odm na partição correspondente. As etapas incluem:
Política SELinux pré-compilada
Antes do init
init
SELinux, ele reúne todos os arquivos CIL das partições ( system
, system_ext
, product
, vendor
e odm
) e os compila em política binária, o formato que pode ser carregado no kernel. Como a compilação leva tempo (geralmente 1-2 segundos), os arquivos CIL são pré-compilados no momento da compilação e colocados em /vendor/etc/selinux/precompiled_sepolicy
ou /odm/etc/selinux/precompiled_sepolicy
, junto com os hashes sha256 dos arquivos CIL de entrada. Em tempo de execução, o init
verifica se algum arquivo de política foi atualizado comparando os hashes. Se nada mudou, o init
carrega a política pré-compilada. Caso contrário, o init
compila em tempo real e o usa em vez do pré-compilado.
Mais especificamente, a política pré-compilada é usada se todas as condições a seguir forem atendidas. Aqui, {partition}
representa a partição onde existe a política pré-compilada: vendor
ou odm
.
Se algum deles for diferente, o init
retornará ao caminho de compilação no dispositivo. Veja system/core/init/selinux.cpp
para mais detalhes.