Compatibilidade de políticas

Este artigo descreve como o Android lida com os problemas de compatibilidade de políticas com OTAs de plataforma, em que as novas configurações do SELinux da plataforma podem ser diferentes das do fornecedor antigo Configurações do SELinux.

O design de políticas SELinux baseado em Treble considera uma distinção binária entre a política de platform e do vendor; o esquema se torna se as partições do fornecedor gerarem dependências, como platform < vendor < oem.

No Android 8.0 e em versões mais recentes, a política global do SELinux é dividida em componentes públicos. Os componentes públicos consistem na política e nos componentes infraestrutura do Google Cloud, que têm a garantia de disponibilidade para uma versão da plataforma. Esta política será exposta aos criadores de políticas do fornecedor para permitir que os fornecedores criem um arquivo de política do fornecedor, que, quando combinado com a política fornecida pela plataforma, resulta em uma política totalmente funcional para um dispositivo.

  • Para o controle de versões, a política exportada de plataforma pública será gravada como atributos.
  • Para facilitar a criação de políticas, os tipos exportados serão transformados em atributos com controle de versão como parte do processo de criação da política. Pública os tipos também podem ser usados diretamente nas decisões de rotulagem fornecidas pelo fornecedor arquivos de contextos.

O Android mantém um mapeamento entre tipos concretos exportados na plataforma política e os atributos de controle de versões correspondentes para cada plataforma versão. Isso garante que quando os objetos forem rotulados com um tipo, não prejudique o comportamento garantido pela política pública da plataforma em um para a versão anterior. Esse mapeamento é mantido ao manter um arquivo de mapeamento atualizado para cada versão da plataforma, que mantém informações de associação de atributos para cada tipo exportado em políticas públicas.

Propriedade e rotulagem de objetos

Ao personalizar a política no Android 8.0 e versões mais recentes, a propriedade precisa ser claramente definida de cada objeto para manter a plataforma e a política do fornecedor separadas. Por exemplo, se o fornecedor rotula /dev/foo e a plataforma rotula /dev/foo em um OTA subsequente, haverá um comportamento indefinido. Para SELinux, isso se manifesta como uma colisão de rotulagem. O nó do dispositivo pode ter apenas um um único rótulo que resulta no rótulo que for aplicado por último. Como resultado:

  • Os processos que precisam de acesso ao rótulo que não foi aplicado vão perdem o acesso ao recurso.
  • Os processos que conseguem acesso ao arquivo podem ser corrompidos devido a erros nó de dispositivo foi criado.

As propriedades do sistema também têm potencial para nomear colisões que podem resultar em comportamento indefinido no sistema (bem como para rotulagem SELinux). Colisões entre os rótulos de plataforma e fornecedor podem ocorrer para qualquer objeto que tenha um SELinux incluindo propriedades, serviços, processos, arquivos e soquetes. Para evitar esses problemas, defina claramente a propriedade desses objetos.

Além das colisões de rótulos, os nomes de tipo/atributo do SELinux também podem entrar em conflito. Uma colisão de nome/tipo de atributo sempre vai resultar em um erro do compilador de políticas.

Atribuição do namespace do tipo/atributo

O SELinux não permite várias declarações do mesmo tipo/atributo. Política com declarações duplicadas não serão compiladas. Para evitar digitar e conflitos de nomes de atributos, todas as declarações de fornecedor precisam ter namespace começando com vendor_.

type foo, domain; → type vendor_foo, domain;

Propriedade do sistema e propriedade da rotulagem de processos

É melhor evitar conflitos de rotulagem usando namespaces de propriedade. Para identifique facilmente as propriedades da plataforma e evite conflitos de nome ao renomear ou adicionar propriedades de plataforma exportada, garantir que todas as propriedades do fornecedor tenham próprios prefixos:

Tipo de propriedade Prefixos aceitáveis
propriedades de controle ctl.vendor.
ctl.start$vendor.
ctl.stop$vendor.
init.svc.vendor.
leitura-gravável vendor.
somente leitura ro.vendor.
ro.boot.
ro.hardware.
persistente persist.vendor.

Os fornecedores podem continuar usando ro.boot.*, que vem do kernel. cmdline) e ro.hardware.* (uma propriedade óbvia relacionada a hardware).

Todos os serviços do fornecedor nos arquivos init rc precisam ter vendor.. para serviços em arquivos init rc de partições que não são do sistema. Regras semelhantes são aplicados aos rótulos SELinux para as propriedades do fornecedor (vendor_ para as propriedades do fornecedor).

Propriedade do arquivo

Evitar colisões de arquivos é um desafio porque a plataforma e o fornecedor as políticas normalmente fornecem rótulos para todos os sistemas de arquivos. Ao contrário da nomenclatura de tipos, o namespace dos arquivos não é prático, uma vez que muitos deles são criados pelo grão Para evitar essas colisões, siga as orientações de nomenclatura para sistemas de arquivos. nesta seção. Para o Android 8.0, essas são recomendações sem aspectos técnicos a aplicação das políticas. No futuro, essas recomendações serão aplicadas pela Pacote de testes de fornecedor (VTS, na sigla em inglês).

Sistema (/sistema)

Somente a imagem do sistema precisa fornecer rótulos para os componentes /system usando file_contexts, service_contexts etc. Se os rótulos dos componentes /system foram adicionados à política /vendor, uma a atualização OTA somente do framework pode não ser possível.

Fornecedor (/vendor)

A política de SELinux do AOSP já rotula partes da partição vendor com a qual a plataforma interage, o que permite escrever regras SELinux para plataforma processos para falar e/ou acessar partes do vendor partição. Exemplos:

Caminho /vendor Rótulo fornecido pela plataforma Processos da plataforma dependendo do rótulo
/vendor(/.*)? vendor_file Todos os clientes HAL no framework, ueventd etc.
/vendor/framework(/.*)? vendor_framework_file dex2oat, appdomain etc.
/vendor/app(/.*)? vendor_app_file dex2oat, installd, idmap etc.
/vendor/overlay(/.*) vendor_overlay_file system_server, zygote, idmap etc.

Como resultado, regras específicas devem ser seguidas (aplicadas por meio de neverallows) ao rotular arquivos adicionais em vendor partição:

  • vendor_file precisa ser o marcador padrão para todos os arquivos em vendor. A política da plataforma exige isso para acessar as implementações de HAL de passagem.
  • Todos os novos exec_types foram adicionados à partição vendor pelo fornecedor SEPolicy, precisam ter o atributo vendor_file_type. Isso é aplicada por Nunca.
  • Para evitar conflitos com futuras atualizações de plataforma/framework, evite rotular arquivos diferentes de exec_types na partição vendor.
  • Todas as dependências de biblioteca para HALs do mesmo processo identificadas pelo AOSP precisam ser marcado como same_process_hal_file.

Procfs (/proc)

Os arquivos em /proc podem ser rotulados usando apenas o genfscon rótulo. No Android 7.0, os plataforma e fornecedor política usou genfscon para marcar arquivos em procfs.

Recomendação:somente rótulos de política da plataforma /proc. Se os processos do vendor precisarem de acesso aos arquivos no /proc que estão identificados com o rótulo padrão (proc), a política do fornecedor não devem rotulá-los explicitamente e devem usar a expressão genérica proc para adicionar regras para domínios do fornecedor. Isso permite que a plataforma atualizações para acomodar futuras interfaces de kernel expostas por meio de procfs e identifique-as explicitamente conforme necessário.

Debugfs (/sys/kernel/debug)

Debugfs pode ser rotulado em file_contexts e genfscon Do Android 7.0 ao Android 10, tanto a plataforma quanto o rótulo do fornecedor debugfs:

No Android 11, debugfs não pode ser acessados ou montados em dispositivos de produção. Os fabricantes de dispositivos precisam Remova debugfs.

Tracefs (/sys/kernel/debug/tracing)

Tracefs pode ser rotulado em file_contexts e genfscon No Android 7.0, apenas os rótulos de plataforma tracefs:

Recomendação:somente a plataforma pode rotular tracefs.

Sysfs (/sys)

Os arquivos em /sys podem ser rotulados usando file_contexts e genfscon. No Android 7.0, o uso da plataforma e do fornecedor file_contexts e genfscon para marcar arquivos em sysfs

Recomendação:a plataforma pode rotular sysfs nós que não são específicos do dispositivo. Caso contrário, somente o fornecedor pode rotular os arquivos.

tmpfs (/dev)

Arquivos em /dev podem ser marcados em file_contexts. Em Android 7.0, arquivos de rótulos da plataforma e do fornecedor aqui.

Recomendação:o fornecedor pode rotular somente arquivos em /dev/vendor (por exemplo, /dev/vendor/foo, /dev/vendor/socket/bar).

Rootfs (/)

Arquivos em / podem ser marcados em file_contexts. No Android 7.0, arquivos de rótulo da plataforma e do fornecedor aqui.

Recomendação:somente o sistema pode marcar arquivos em /.

Dados (/data)

Os dados são rotulados usando uma combinação de file_contexts e seapp_contexts.

Recomendação:não permita a rotulagem de fornecedores fora da organização /data/vendor Somente a plataforma pode rotular outras partes /data:

Atributos de compatibilidade

A política de SELinux é uma interação entre tipos de origem e destino para classes de objetos e permissões. Todos os objetos (processos, arquivos etc.) afetados por política do SELinux podem ter apenas um tipo, mas esse tipo pode ter atributos.

A política é redigida principalmente em termos dos tipos existentes:

allow source_type target_type:target_class permission(s);

Isso funciona porque a política foi criada com conhecimento de todos os tipos. No entanto, se a política do fornecedor e a política da plataforma usarem tipos específicos, e o rótulo de um alterações específicas de objeto em apenas uma dessas políticas, a outra pode conter política que obtinha ou perdeva o acesso na qual antes se dependia. Exemplo:

File_contexts:
/sys/A   u:object_r:sysfs:s0
Platform: allow p_domain sysfs:class perm;
Vendor: allow v_domain sysfs:class perm;

Pode ser alterado para:

File_contexts:
/sys/A   u:object_r:sysfs_A:s0

Embora a política do fornecedor permaneça a mesma, o v_domain perderiam o acesso devido à falta de política para o novo sysfs_A não é válido.

Ao definir uma política em termos de atributos, podemos dar ao objeto subjacente uma com um atributo correspondente à política para a plataforma e código do fornecedor. Isso pode ser feito para todos os tipos para criar um attribute-policy em que tipos concretos nunca são usados. Na prática, Isso é necessário apenas para as partes da política que se sobrepõem entre as plataformas e fornecedor, que são definidos e fornecidos como política pública da plataforma. que é criado como parte da política do fornecedor.

Definir políticas públicas como atributos com controle de versões atende a duas políticas metas de compatibilidade:

  • Verificar se o código do fornecedor continua funcionando após a atualização da plataforma. Alcançada pela adição de atributos a tipos concretos para objetos correspondentes a aqueles em que o código do fornecedor dependia, preservando o acesso.
  • Capacidade de suspender o uso da política. Alcançada com clareza definir conjuntos de políticas em atributos que podem ser removidos assim que o a versão correspondente não é mais compatível. O desenvolvimento pode continuar na plataforma, sabendo que a política antiga ainda está presente no política do fornecedor e será removido automaticamente quando/se for atualizado.

Capacidade de gravação da política

Para atingir o objetivo de não exigir conhecimento de mudanças específicas da versão para desenvolvimento de políticas, o Android 8.0 inclui um mapeamento entre plataforma pública tipos de política e seus atributos. O tipo foo está mapeado para atribuir foo_vN, em que N é o versão segmentada. vN corresponde ao PLATFORM_SEPOLICY_VERSION variável de build e está no formato MM.NN, em que MM corresponde ao número do SDK da plataforma. e NN é uma versão específica da sepolicy da plataforma.

Os atributos de políticas públicas não têm controle de versão. Eles existem como uma API no qual plataforma e política do fornecedor podem ser criadas para manter a interface entre os dois partições estáveis. Os criadores de políticas da plataforma e do fornecedor podem continuar a escrever política como ela é escrita atualmente.

A política pública da plataforma exportada como allow source_foo target_bar:class perm; é incluída como parte da política do fornecedor. Durante compilation (que inclui o a versão correspondente) ela será transformada na política que será enviada ao do dispositivo (mostrado no bloco de status intermediário comum transformado Idioma (CIL):

 (allow source_foo_vN target_bar_vN (class (perm)))

Como a política do fornecedor nunca está à frente da plataforma, ela não deve se preocupar com em versões anteriores. No entanto, a política da plataforma precisa saber há quanto tempo o fornecedor política do Google: incluir atributos aos tipos e definir a política correspondente ao com controle de versões.

Diferenças da política

Criar atributos automaticamente adicionando _vN ao final. de cada tipo não faz nada sem mapear os atributos para tipos na versão diferenças O Android mantém um mapeamento entre as versões dos atributos e uma o mapeamento de tipos para esses atributos. Isso é feito no mapeamento mencionado acima arquivos com instruções, como (CIL):

(typeattributeset foo_vN (foo))

Upgrades de plataforma

A seção a seguir detalha os cenários de upgrades de plataforma.

Mesmos tipos

Esse cenário ocorre quando um objeto não altera os rótulos nas versões da política. Isso é o mesmo para os tipos de origem e destino e pode ser observado /dev/binder, identificada como binder_device em todas lançamentos. Ela é representada na política transformada como:

binder_device_v1 … binder_device_vN

Ao fazer upgrade de v1v2, a política da plataforma precisa contêm:

type binder_device; -> (type binder_device) (in CIL)

No arquivo de mapeamento v1 (CIL):

(typeattributeset binder_device_v1 (binder_device))

No arquivo de mapeamento v2 (CIL):

(typeattributeset binder_device_v2 (binder_device))

Na política de fornecedores v1 (CIL):

(typeattribute binder_device_v1)
(allow binder_device_v1 …)

Na política de fornecedores v2 (CIL):

(typeattribute binder_device_v2)
(allow binder_device_v2 …)
Novos tipos

Esse cenário ocorre quando a plataforma adiciona um novo tipo, o que pode acontecer ao adicionar novos recursos ou durante o aumento da proteção de políticas.

  • Novo recurso. Quando o tipo está rotulando um objeto que foi anteriormente inexistente (como um novo processo de serviço), o código do fornecedor não interagir anteriormente com ela, portanto, não existe uma política correspondente. A nova o atributo correspondente ao tipo não tem um atributo na entrada versão e, portanto, não precisaria de uma entrada na segmentação do arquivo de mapeamento que para a versão anterior.
  • Aumento da proteção de políticas. Quando o tipo representa a política aumento da proteção, o novo atributo de tipo precisa estar vinculado a uma cadeia de atributos correspondente ao anterior (semelhante ao exemplo anterior, alterando /sys/A de sysfs a sysfs_A). Fornecedor código depende de uma regra que permite o acesso a sysfs e precisa incluir essa regra como um atributo do novo tipo.

Ao fazer upgrade de v1v2, a política da plataforma precisa contêm:

type sysfs_A; -> (type sysfs_A) (in CIL)
type sysfs; (type sysfs) (in CIL)

No arquivo de mapeamento v1 (CIL):

(typeattributeset sysfs_v1 (sysfs sysfs_A))

No arquivo de mapeamento v2 (CIL):

(typeattributeset sysfs_v2 (sysfs))
(typeattributeset sysfs_A_v2 (sysfs_A))

Na política de fornecedores v1 (CIL):

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

Na política de fornecedores v2 (CIL):

(typeattribute sysfs_A_v2)
(allow … sysfs_A_v2 …)
(typeattribute sysfs_v2)
(allow … sysfs_v2 …)
Tipos removidos

Este cenário (raro) ocorre quando um tipo é removido, o que pode acontecer quando o objeto subjacente:

  • Permanece, mas recebe um marcador diferente.
  • É removido pela plataforma.

Durante a flexibilização da política, um tipo é removido e o objeto rotulado com esse tipo recebe um rótulo diferente, que já existe. Isso representa uma fusão de mapeamentos de atributos: o código do fornecedor ainda deve ser capaz de acessar o objeto pelo atributo que ele tinha, mas o resto do sistema agora precisa poderá acessá-lo com seu novo atributo.

Se o atributo para o qual foi alterado for novo, a nova rotulagem será a a mesma do caso do novo tipo. A diferença é que, quando um rótulo existente é usado, os a adição do novo tipo de atributo antigo faria com que outros objetos também rotulados com esse tipo para acesso recente. Isso é essencialmente o que é feito plataforma e é considerado uma compensação aceitável para manter compatibilidade.

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

Exemplo de versão 1: tipos de recolhimento (removendo sysfs_A)

Ao fazer upgrade de v1v2, a política da plataforma precisa contêm:

type sysfs; (type sysfs) (in CIL)

No arquivo de mapeamento v1 (CIL):

(typeattributeset sysfs_v1 (sysfs))
(type sysfs_A) # in case vendors used the sysfs_A label on objects
(typeattributeset sysfs_A_v1 (sysfs sysfs_A))

No arquivo de mapeamento v2 (CIL):

(typeattributeset sysfs_v2 (sysfs))

Na política de fornecedores v1 (CIL):

(typeattribute sysfs_A_v1)
(allow … sysfs_A_v1 …)
(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

Na política de fornecedores v2 (CIL):

(typeattribute sysfs_v2)
(allow … sysfs_v2 …)

Exemplo de versão 2: remoção completa (tipo foo)

Ao fazer upgrade de v1v2, a política da plataforma precisa contêm:

# nothing - we got rid of the type

No arquivo de mapeamento v1 (CIL):

(type foo) #needed in case vendors used the foo label on objects
(typeattributeset foo_v1 (foo))

No arquivo de mapeamento v2 (CIL):

# nothing - get rid of it

Na política de fornecedores v1 (CIL):

(typeattribute foo_v1)
(allow foo …)
(typeattribute sysfs_v1)
(allow sysfs_v1 …)

Na política de fornecedores v2 (CIL):

(typeattribute sysfs_v2)
(allow sysfs_v2 …)
Nova turma/permissões

Esse cenário ocorre quando um upgrade da plataforma introduz novos componentes de política que não existem em versões anteriores. Por exemplo, quando o Android adicionou o Gerenciador de objetos servicemanager que criou as opções de adicionar, localizar e listar permissões, daemons de fornecedor que desejam se registrar no servicemanager precisava de permissões que não eram disponíveis. No Android 8.0, apenas a política da plataforma pode adicionar novas classes e permissões.

Permitir todos os domínios que poderiam ter sido criados ou estendidos pela política do fornecedor para usar a nova classe sem obstruções, a política da plataforma precisa incluir um semelhante a:

allow {domain -coredomain} *:new_class perm;

Isso pode até exigir uma política que permita o acesso para todas as interfaces (política pública) para garantir o acesso à imagem do fornecedor. Se isso resultar em uma política de segurança (como pode ter com as mudanças do servicemanager), um fornecedor o upgrade pode ser forçado.

Turma/permissões removidas

Esse cenário ocorre quando um gerenciador de objetos é removido (como o ZygoteConnection) e não vai causar problemas. A A classe e as permissões do gerenciador de objetos podem permanecer definidas na política até que do fornecedor não a mais usa. Para isso, é preciso adicionar as definições ao arquivo de mapeamento correspondente.

Personalização do fornecedor para tipos novos/rerotulados

Novos tipos de fornecedores são essenciais para o desenvolvimento de políticas de fornecedores, pois são necessários para descrever novos processos, binários, dispositivos, subsistemas e dados armazenados. Conforme é fundamental permitir a criação de tipos definidos pelo fornecedor.

Como a política do fornecedor é sempre a mais antiga no dispositivo, não é necessário converter automaticamente todos os tipos de fornecedor em atributos na política. A plataforma não depende de nada rotulado na política do fornecedor porque a plataforma não tem conhecimento deles; No entanto, a plataforma vai fornecer os atributos usados para interagir com objetos rotulados com esses tipos (como domain, sysfs_type etc.). Para que a plataforma continuem interagindo corretamente com esses objetos, os atributos devem ser aplicadas adequadamente, e regras específicas podem precisar ser adicionadas ao domínios personalizáveis (como init).

Mudanças de atributos do Android 9

Dispositivos que passam por upgrade para o Android 9 podem usar os seguintes atributos, mas os dispositivos lançados com o Android 9.

Atributos do infrator

O Android 9 inclui estes atributos relacionados ao domínio:

  • data_between_core_and_vendor_violators Atributo para todos os domínios que violam a exigência de não compartilhar arquivos por caminho entre vendor e coredomains. Plataforma e os processos do fornecedor não devem usar arquivos em disco para se comunicar (ABI instável). Recomendação:
    • O código do fornecedor deve usar /data/vendor.
    • O sistema não deve usar /data/vendor.
  • system_executes_vendor_violators Atributo para todos os domínios do sistema (exceto init e shell domains) que violem o requisito de não executar binários do fornecedor. Execução de os binários do fornecedor têm uma API instável. A plataforma não pode executar binários de fornecedores diretamente. Recomendação:
    • Essas dependências de plataforma em binários do fornecedor precisam estar por trás de HALs HIDL.

      OU

    • Os coredomains que precisam de acesso aos binários do fornecedor precisam ser movidas para a partição do fornecedor e, assim, deixar de ser coredomain.

Atributos não confiáveis

Apps não confiáveis que hospedam códigos arbitrários não podem ter acesso ao HwBinder serviços, exceto aqueles considerados suficientemente seguros para acesso por esses aplicativos Confira os serviços seguros abaixo. Os dois principais motivos para isso são:

  1. Os servidores HwBinder não realizam a autenticação do cliente porque o HIDL atualmente não expõe as informações do UID do autor da chamada. Mesmo que o HIDL exponha esses dados, muitos Os serviços HwBinder operam em um nível abaixo do dos aplicativos (como HALs) ou não podem depender da identidade do app para autorização. Portanto, por segurança, o padrão é que todo serviço da HwBinder trata todos os seus clientes como autorizados a executar operações oferecidas pelo serviço.
  2. Servidores HAL (um subconjunto de serviços HwBinder) contêm código com maior taxa de incidência de problemas de segurança em comparação com system/core componentes e acesso às camadas inferiores da pilha (até o hardware), oportunidades crescentes para contornar o modelo de segurança do Android.

Serviços seguros

Os serviços seguros incluem:

  • same_process_hwservice: Por definição, esses serviços são executados processo do cliente e, portanto, ter o mesmo acesso que o domínio do cliente no que o processo é executado.
  • coredomain_hwservice: Esses serviços não apresentam riscos associada ao motivo 2.
  • hal_configstore_ISurfaceFlingerConfigs: Este serviço é criada especificamente para uso em qualquer domínio.
  • hal_graphics_allocator_hwservice: Essas operações também são oferecido pelo serviço de vinculação da surfaceflinger, quais apps são permitidos para acessar.
  • hal_omx_hwservice: Esta é uma versão HwBinder do mediacodec Serviço de vinculação, que os apps têm permissão para acessar.
  • hal_codec2_hwservice: Esta é uma versão mais recente do hal_omx_hwservice.

Atributos utilizáveis

Todos os hwservices não considerados seguros têm o atributo untrusted_app_visible_hwservice. Os servidores HAL correspondentes têm o atributo untrusted_app_visible_halserver. Dispositivos em lançamento com o Android 9 NÃO PODE usar nenhum untrusted.

Recomendação:

  • Apps não confiáveis devem se comunicar com um serviço de sistema que se comunica com o a HAL da fornecedora HIDL. Por exemplo, os apps podem se comunicar com binderservicedomain e depois mediaserver (que é um binderservicedomain), por sua vez, se comunica com o hal_graphics_allocator.

    OU

  • Os apps que precisam de acesso direto a HALs vendor precisam ter a próprio domínio sepolicy definido pelo fornecedor.

Testes de atributos de arquivos

O Android 9 inclui testes de tempo de build que garantem que todos os arquivos em ambientes locais têm os atributos apropriados (como todos os arquivos nos sysfs têm o atributo sysfs_type obrigatório).

Política pública da plataforma

A política pública de plataforma é essencial para garantir a conformidade com o Android 8.0. sem precisar manter a união das políticas da plataforma da v1 e da v2. Os fornecedores são expostos a um subconjunto de políticas da plataforma que contém tipos e atributos utilizáveis e regras sobre esses tipos e atributos que depois se torna parte da política do fornecedor (ou seja, vendor_sepolicy.cil).

Os tipos e as regras são convertidos automaticamente na política gerada pelo fornecedor. em attribute_vN, para que todos os tipos fornecidos pela plataforma são atributos com controle de versão, mas não há controle de versões. A plataforma é responsável por mapear os tipos concretos fornecidos nas para garantir que a política do fornecedor continue funcionando e que as regras fornecidos para uma versão específica. A combinação da as políticas públicas da plataforma e as políticas do fornecedor atendem à arquitetura do Android 8.0 o objetivo do modelo é permitir builds independentes de plataforma e fornecedor.

Mapeamento para cadeias de atributos

Ao usar atributos para mapear para versões de política, um tipo é mapeado para um atributo ou vários atributos, garantindo que os objetos rotulados com o tipo possam ser acessados por atributos correspondentes aos tipos anteriores.

Manter a meta de ocultar as informações de versão do criador de políticas significa gerar automaticamente os atributos com controle de versão e atribuí-los ao tipos adequados. No caso comum de tipos estáticos, isso é simples: type_foo é mapeado para type_foo_v1.

Para uma mudança no rótulo de um objeto, como sysfssysfs_A ou mediaserveraudioserver, criar esse mapeamento é não trivial (e é descrito nos exemplos acima). mantenedores da política da plataforma precisa determinar como criar o mapeamento em pontos de transição para objetos, quais requer entender a relação entre objetos e os objetos rótulos e determinar quando isso ocorre. Para compatibilidade com versões anteriores, a complexidade precisa ser gerenciada na plataforma, que é a única partição que pode aumentar a receita.

Aumento de versões

Para simplificar, a plataforma Android lança uma versão sepolicy quando uma nova a ramificação de lançamento é finalizada. Conforme descrito acima, o número da versão está contido em PLATFORM_SEPOLICY_VERSION e está no formato MM.nn, em que MM corresponde ao valor do SDK e nn é um valor privado mantido em /platform/system/sepolicy. Por por exemplo, 19.0 para Kitkat, 21.0 para Lollipop, 22.0 para Lollipop-MR1 23.0 para Marshmallow, 24.0 para Nougat, 25.0 para Nougat-MR1 26.0 para Oreo, 27.0 para Oreo-MR1 e 28.0 para Android 9. Uprevs nem sempre são números inteiros. Para exemplo, se um aumento de MR em uma versão precisar de uma alteração incompatível no system/sepolicy/public, mas não uma promoção de API, então sepolicy pode ser: vN.1. A versão presente em um a ramificação é um 10000.0 que nunca pode ser usado em dispositivos de envio.

O Android pode descontinuar a versão mais antiga durante a atualização. Para saber quando descontinuar uma versão, o Android poderá coletar o número de dispositivos com políticas que executam essa versão do Android e ainda recebem conteúdo atualizações. Se o número for menor que um determinado limite, a versão será descontinuada.

Impacto no desempenho de vários atributos

Como descrito em https://github.com/SELinuxProject/cil/issues/9, um grande número de atributos atribuídos a um tipo resulta em problemas de desempenho no caso de uma ausência no cache da política.

Foi confirmado que esse é um problema no Android. Por isso, as alterações foram feitas no Android 8.0 para remover atributos adicionados à política pelo de políticas do Terraform, bem como para remover atributos não utilizados. Estas alterações foram resolvidas regressões de desempenho.

System_ext: política pública e política do produto

No Android 11 e versões mais recentes, as partições system_ext e produto podem exportar os tipos públicos designados para a partição do fornecedor. Como plataforma política pública, o fornecedor usa tipos e regras convertidos automaticamente em os atributos com controle de versão, por exemplo, de type para type_N, em que N é a versão da plataforma em que a partição do fornecedor é criada.

Quando as partições system_ext e produto forem baseadas na mesma versão da plataforma N, o sistema de build gera arquivos de mapeamento base para system_ext/etc/selinux/mapping/N.cil e product/etc/selinux/mapping/N.cil, que contêm a identidade mapeamentos de type para type_N. O fornecedor pode acessar type com o atributo com controle de versão type_N.

Caso apenas as partições system_ext e produto sejam atualizadas, N para N+1 (ou posterior), enquanto o fornecedor permanecer em N, ele poderá perder o acesso ao das partições system_ext e produto. Para evitar falhas, as As partições "system_ext" e "product" precisam fornecer arquivos de mapeamento de dados concretos em atributos type_N. Cada parceiro responsáveis pela manutenção dos arquivos de mapeamento, se for dar suporte N fornecedor com N+1 (ou mais recente) system_ext e partições de produto.

Para isso, os parceiros precisam:

  1. Copie os arquivos de mapeamento base gerados de N. system_ext e partições de produto à árvore de origem.
  2. Altere os arquivos de mapeamento conforme necessário.
  3. Instale o arquivos de mapeamento para N+1 (ou posterior) system_ext e partições de produto.

Por exemplo, suponha que N system_ext tenha uma tag pública tipo chamado foo_type. Depois system_ext/etc/selinux/mapping/N.cil na partição system_ext N será semelhante a:

(typeattributeset foo_type_N (foo_type))
(expandtypeattribute foo_type_N true)
(typeattribute foo_type_N)

Se bar_type for adicionado a N+1 system_ext e se bar_type precisa ser mapeado para foo_type para Fornecedor N, N.cil pode ser atualizado de

(typeattributeset foo_type_N (foo_type))

a

(typeattributeset foo_type_N (foo_type bar_type))

e instalado na partição do system_ext N+1. N fornecedor pode continuar acessando N+1 foo_type e bar_type do system_ext.

Rotulagem de contextos SELinux

Para dar suporte à distinção entre sepolicy da plataforma e do fornecedor, o sistema cria arquivos de contexto do SELinux de forma diferente para mantê-los separados.

Contextos de arquivo

O Android 8.0 introduziu as seguintes mudanças para file_contexts:

  • Para evitar sobrecarga adicional de compilação no dispositivo durante a inicialização, file_contexts deixam de existir no formato binário. Em vez disso, eles são arquivos de texto de expressão regular legíveis, como {property, service}_contexts (como eram anteriores à versão 7.0).
  • Os file_contexts são divididos entre dois arquivos:
    • plat_file_contexts
      • A file_context da plataforma Android, que não tem rótulos específicos do dispositivo, exceto para rotular partes de /vendor que deve ser identificada precisamente garantir o funcionamento correto dos arquivos sepolicy.
      • Precisa residir na partição system em /system/etc/selinux/plat_file_contexts no dispositivo e ser carregados por init no início junto com o fornecedor file_context.
    • vendor_file_contexts
      • file_context específica para dispositivos, criada pela combinação file_contexts encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no arquivos Boardconfig.mk.
      • Deve ser instalado em /vendor/etc/selinux/vendor_file_contexts pol. vendor e ser carregado por init em o start com a plataforma file_context.

Contextos da propriedade

No Android 8.0, o property_contexts é dividido entre dois arquivos:

  • plat_property_contexts
    • A property_context da plataforma Android, que não tem rótulos específicos do dispositivo.
    • Precisa residir na partição system em /system/etc/selinux/plat_property_contexts e ser carregado por init no início com o fornecedor property_contexts.
  • vendor_property_contexts
    • property_context específica para dispositivos, criada pela combinação property_contexts encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no dispositivo arquivos Boardconfig.mk.
    • Precisa residir na partição vendor em /vendor/etc/selinux/vendor_property_contexts e ser carregado por init no início com a plataforma property_context

Contextos de serviço

No Android 8.0, o service_contexts é dividido entre o seguinte: arquivos:

  • plat_service_contexts
    • service_context específicas da plataforma Android para o servicemanager. O service_context não tem rótulos específicos do dispositivo.
    • Precisa residir na partição system em /system/etc/selinux/plat_service_contexts e ser carregado por servicemanager no início com o fornecedor service_contexts.
  • vendor_service_contexts
    • service_context específica para dispositivos, criada pela combinação service_contexts encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no arquivos Boardconfig.mk.
    • Precisa residir na partição vendor em /vendor/etc/selinux/vendor_service_contexts e ser carregado por servicemanager no início com a plataforma service_contexts.
    • Embora o servicemanager procure esse arquivo na inicialização, para um dispositivo TREBLE totalmente compatível, os vendor_service_contexts NÃO PODE existir. Isso ocorre porque todas as interações entre vendor e system processos PRECISAM passar por hwservicemanager/hwbinder.
  • plat_hwservice_contexts
    • Plataforma Android hwservice_context para hwservicemanager que não tem identificadores específicos do dispositivo.
    • Precisa residir na partição system em /system/etc/selinux/plat_hwservice_contexts e ser carregado por hwservicemanager no início com o vendor_hwservice_contexts.
  • vendor_hwservice_contexts
    • hwservice_context específica para dispositivos, criada pela combinação hwservice_contexts encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no arquivos Boardconfig.mk.
    • Precisa residir na partição vendor em /vendor/etc/selinux/vendor_hwservice_contexts e ser carregado por hwservicemanager no início com o plat_service_contexts.
  • vndservice_contexts
    • service_context específica do dispositivo para o vndservicemanager criado pela combinação vndservice_contexts encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no Boardconfig.mk.
    • Este arquivo deve residir na partição vendor em /vendor/etc/selinux/vndservice_contexts e ser carregado por vndservicemanager no início.

Contextos do Seapp

No Android 8.0, o seapp_contexts é dividido entre dois arquivos:

  • plat_seapp_contexts
    • A seapp_context da plataforma Android não tem dispositivos específicos mudanças.
    • Precisa residir na partição system em /system/etc/selinux/plat_seapp_contexts.
  • vendor_seapp_contexts
    • Extensão específica do dispositivo para a plataforma seapp_context criada combinando o seapp_contexts encontrado nos diretórios apontado por BOARD_SEPOLICY_DIRS no arquivos Boardconfig.mk.
    • Precisa residir na partição vendor em /vendor/etc/selinux/vendor_seapp_contexts.

Permissões MAC

No Android 8.0, o mac_permissions.xml é dividido entre dois arquivos:

  • Plataforma mac_permissions.xml
    • A mac_permissions.xml da plataforma Android, que não tem ou mudanças específicas do dispositivo.
    • Precisa residir na partição system em /system/etc/selinux/.
  • mac_permissions.xml sem plataforma
    • Extensão para plataforma específica do dispositivo mac_permissions.xml criado a partir de mac_permissions.xml encontrado nos diretórios indicados por BOARD_SEPOLICY_DIRS no Boardconfig.mk.
    • Precisa residir na partição vendor em /vendor/etc/selinux/.