Os objetos e serviços do sistema de arquivos adicionados à compilação geralmente precisam de IDs exclusivos e separados, conhecidos como IDs do Android (AIDs). Atualmente, muitos recursos, como arquivos e serviços, usam AIDs principais (definidos pelo Android) desnecessariamente; em muitos casos, você pode usar AIDs OEM (definidos pelo OEM) em vez disso.
Versões anteriores do Android (Android 7.xe inferior) estenderam o mecanismo de AIDs usando um arquivo android_filesystem_config.h
específico do dispositivo para especificar recursos do sistema de arquivos e/ou AIDs OEM personalizados. No entanto, esse sistema não era intuitivo, pois não suportava o uso de nomes agradáveis para AIDs OEM, exigindo que você especificasse o numérico bruto para campos de usuário e grupo sem uma maneira de associar um nome amigável ao AID numérico.
As versões mais recentes do Android (Android 8.0 e superior) oferecem suporte a um novo método para estender os recursos do sistema de arquivos. Este novo método tem suporte para o seguinte:
- Vários locais de origem para arquivos de configuração (permite configurações de compilação extensíveis).
- Verificação de sanidade em tempo de construção dos valores de OEM AID.
- Geração de um cabeçalho OEM AID personalizado que pode ser usado em arquivos de origem conforme necessário.
- Associação de um nome amigável com o valor real do OEM AID. Suporta argumentos de string não numéricos para usuário e grupo, ou seja, "foo" em vez de "2901".
Melhorias adicionais incluem a remoção do array android_ids[]
de system/core/libcutils/include/private/android_filesystem_config.h
. Esse array agora existe no Bionic como um array gerado totalmente privado, com acessadores via getpwnam()
e getgrnam()
. (Isso tem o efeito colateral de produzir binários estáveis à medida que os AIDs principais são modificados.) Para ferramentas e um arquivo README com mais detalhes, consulte build/make/tools/fs_config
.
Adicionando IDs do Android (AIDs)
O Android 8.0 removeu a matriz android_ids[]
do Android Open Source Project (AOSP). Todos os nomes compatíveis com AID são gerados a partir do arquivo de cabeçalho system/core/libcutils/include/private/android_filesystem_config.h
ao gerar o array Bionic android_ids[]
. Qualquer define
correspondente AID_*
é selecionada pelo conjunto de ferramentas e * se torna o nome em minúsculas.
Por exemplo, em private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
Torna-se:
- Nome amigável: sistema
- uid: 1000
- gid: 1000
Para adicionar um novo AOSP core AID, basta adicionar o #define
ao arquivo de cabeçalho android_filesystem_config.h
. O AID será gerado na compilação e disponibilizado para interfaces que usam argumentos de usuário e grupo. O ferramental valida que o novo AID não está dentro das faixas de APP ou OEM; ele também respeita as alterações nesses intervalos e deve ser reconfigurado automaticamente nas alterações ou nos novos intervalos reservados ao OEM.
Configurando AIDs
Para habilitar o novo mecanismo de AIDs, defina TARGET_FS_CONFIG_GEN
no arquivo BoardConfig.mk
. Essa variável contém uma lista de arquivos de configuração, permitindo anexar arquivos conforme necessário.
Por convenção, os arquivos de configuração usam o nome config.fs
, mas na prática você pode usar qualquer nome. Os arquivos config.fs
estão no formato Python ConfigParser ini e incluem uma seção caps (para configurar recursos do sistema de arquivos) e uma seção AIDs (para configurar AIDs OEM).
Configurando a seção de maiúsculas
A seção caps suporta a configuração de recursos do sistema de arquivos em objetos do sistema de arquivos dentro da compilação (o próprio sistema de arquivos também deve suportar essa funcionalidade).
Como a execução de um serviço estável como root no Android causa uma falha do Compatibility Test Suite (CTS) , os requisitos anteriores para reter um recurso durante a execução de um processo ou serviço envolviam configurar recursos e usar setuid
/ setgid
para um AID adequado para execução. Com caps, você pode pular esses requisitos e fazer com que o kernel faça isso por você. Quando o controle é passado para main()
, seu processo já possui os recursos necessários para que seu serviço possa usar um usuário e grupo não root (essa é a maneira preferida de iniciar serviços privilegiados).
A seção caps usa a seguinte sintaxe:
Seção | Valor | Definição |
---|---|---|
[path] | O caminho do sistema de arquivos a ser configurado. Um caminho que termina em / é considerado um dir, senão é um arquivo. É um erro especificar várias seções com o mesmo [path] em arquivos diferentes. Nas versões do Python <= 3.2, o mesmo arquivo pode conter seções que substituem a seção anterior; no Python 3.2, está definido para o modo estrito. | |
mode | Modo de arquivo octal | Um modo de arquivo octal válido de pelo menos 3 dígitos. Se 3 for especificado, será prefixado com 0, senão o modo será usado como está. |
user | AID_<usuário> | O C define para um AID válido ou o nome amigável (por exemplo, AID_RADIO e radio são aceitáveis). Para definir um AID personalizado, consulte a seção Configurando o AID . |
group | AID_<grupo> | O mesmo que usuário. |
caps | boné* | O nome declarado em bionic/libc/kernel/uapi/linux/capability.h sem o CAP_ . Caso misto permitido. As tampas também podem ser o bruto:
|
Para obter um exemplo de uso, consulte Usando recursos do sistema de arquivos .
Configurando a seção AID
A seção AID contém AIDs OEM e usa a seguinte sintaxe:
Seção | Valor | Definição |
---|---|---|
[AID_<name>] | O <name> pode conter caracteres em maiúsculas, números e sublinhados. A versão em minúsculas é usada como nome amigável. O arquivo de cabeçalho gerado para inclusão de código usa o AID_<name> exato.É um erro especificar várias seções com o mesmo AID_<name> (não diferencia maiúsculas de minúsculas com as mesmas restrições que [path] ).<name> deve começar com um nome de partição para garantir que não entre em conflito com fontes diferentes. | |
value | <número> | Uma string de número de estilo C válida (hex, octal, binário e decimal). É um erro especificar várias seções com a mesma opção de valor. As opções de valor devem ser especificadas no intervalo correspondente à partição usada em <name> . A lista de partições válidas e seus intervalos correspondentes é definida em system/core/libcutils/include/private/android_filesystem_config.h . As opções são:
|
Para exemplos de uso, consulte Definindo nomes de OEM AID e Usando OEM AIDs .
Exemplos de uso
Os exemplos a seguir detalham como definir e usar um OEM AID e como habilitar os recursos do sistema de arquivos. Os nomes de OEM AID ( [AID_ name ] ) devem começar com um nome de partição, como " fornecedor_ " para garantir que não entrem em conflito com futuros nomes de AOSP ou outras partições.
Definindo nomes de OEM AID
Para definir um OEM AID, crie um arquivo config.fs
e defina o valor do AID. Por exemplo, em device/x/y/config.fs
, defina o seguinte:
[AID_VENDOR_FOO] value: 2900
Após criar o arquivo, defina a variável TARGET_FS_CONFIG_GEN
e aponte para ela em BoardConfig.mk
. Por exemplo, em device/x/y/BoardConfig.mk
, defina o seguinte:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Seu AID personalizado agora pode ser consumido pelo sistema em geral em uma nova compilação.
Usando AIDs OEM
Para usar um OEM AID, em seu código C, inclua o oemaids_headers
em seu Makefile associado e adicione #include "generated_oem_aid.h"
e comece a usar os identificadores declarados. Por exemplo, em my_file.c
, adicione o seguinte:
#include "generated_oem_aid.h" … If (ipc->uid == AID_VENDOR_FOO) { // Do something ...
Em seu arquivo Android.bp
associado, adicione o seguinte:
header_libs: ["oemaids_headers"],
Se você estiver usando um arquivo Android.mk
, adicione o seguinte:
LOCAL_HEADER_LIBRARIES := oemaids_headers
Usando nomes amigáveis
No Android 9, você pode usar o nome amigável para qualquer interface compatível com nomes de AID. Por exemplo:
- Em um comando
chown
emsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- Em um
service
emsome/init.rc
:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Como o mapeamento interno do nome amigável para o uid é executado por /vendor/etc/passwd
e /vendor/etc/group
, a partição do fornecedor deve ser montada.
Associando nomes amigáveis
O Android 9 inclui suporte para associar um nome amigável ao valor real do OEM AID. Você pode usar argumentos de string não numéricos para usuário e grupo, ou seja, " fornecedor_foo " em vez de "2901".
Convertendo de AID para nomes amigáveis
Para AIDs de OEM , o Android 8.x exigia o uso de oem_####
com getpwnam
e funções semelhantes, bem como em locais que lidam com pesquisas via getpwnam
(como scripts de init
). No Android 9, você pode usar os amigos getpwnam
e getgrnam
no Bionic para converter de IDs do Android (AIDs) para nomes amigáveis e vice-versa.
Usando recursos do sistema de arquivos
Para habilitar os recursos do sistema de arquivos, crie uma seção caps no arquivo config.fs
. Por exemplo, em device/x/y/config.fs
, adicione a seguinte seção:
[system/bin/foo_service] mode: 0555 user: AID_VENDOR_FOO group: AID_SYSTEM caps: SYS_ADMIN | SYS_NICE
Após criar o arquivo, defina o TARGET_FS_CONFIG_GEN
para apontar para esse arquivo em BoardConfig.mk
. Por exemplo, em device/x/y/BoardConfig.mk
, defina o seguinte:
TARGET_FS_CONFIG_GEN += device/x/y/config.fs
Quando o serviço vendor_ foo
é executado, ele inicia com os recursos CAP_SYS_ADMIN
e CAP_SYS_NICE
sem chamadas setuid
e setgid
. Além disso, a política SELinux do serviço vendor_ foo
não precisa mais do recurso setuid
e setgid
e pode ser excluída.
Como configurar substituições (Android 6.x-7.x)
O Android 6.0 realocou fs_config
e definições de estrutura associadas ( system/core/include/private/android_filesystem_config.h
) para system/core/libcutils/fs_config.c
onde eles podem ser atualizados ou substituídos por arquivos binários instalados em /system/etc/fs_config_dirs
e /system/etc/fs_config_files
. O uso de regras separadas de correspondência e análise para diretórios e arquivos (que podem usar expressões glob adicionais) permitiu que o Android lidasse com diretórios e arquivos em duas tabelas diferentes. As definições de estrutura em system/core/libcutils/fs_config.c
não apenas permitiam a leitura de diretórios e arquivos em tempo de execução, mas o host poderia usar os mesmos arquivos durante o tempo de compilação para construir imagens do sistema de arquivos como ${OUT}/system/etc/fs_config_dirs
e ${OUT}/system/etc/fs_config_files
.
Embora o método de substituição de extensão do sistema de arquivos tenha sido substituído pelo sistema de configuração modular introduzido no Android 8.0, você ainda pode usar o método antigo, se desejar. As seções a seguir detalham como gerar e incluir arquivos de substituição e configurar o sistema de arquivos.
Gerando arquivos de substituição
Você pode gerar os arquivos binários alinhados /system/etc/fs_config_dirs
e /system/etc/fs_config_files
usando a ferramenta fs_config_generate
em build/tools/fs_config
. A ferramenta usa uma função de biblioteca libcutils
( fs_config_generate()
) para gerenciar os requisitos de DAC em um buffer e define regras para um arquivo de inclusão para institucionalizar as regras de DAC.
Para usar, crie um arquivo de inclusão em device/ vendor / device /android_filesystem_config.h
que atua como substituição. O arquivo deve usar o formato de structure fs_path_config
definido em system/core/include/private/android_filesystem_config.h
com as seguintes inicializações de estrutura para símbolos de diretório e arquivo:
- Para diretórios, use
android _device _dirs[]
. - Para arquivos, use
android _device _files[]
.
Quando não estiver usando android_device_dirs[]
e android_device_files[]
, você pode definir NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
e NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(veja o exemplo abaixo). Você também pode especificar o arquivo de substituição usando TARGET_ANDROID_FILESYSTEM_CONFIG_H
na configuração da placa, com um nome de base obrigatório de android_filesystem_config.h
.
Incluindo arquivos de substituição
Para incluir arquivos, certifique-se de que PRODUCT_PACKAGES
inclua fs_config_dirs
e/ou fs_config_files
para que possa instalá-los em /system/etc/fs_config_dirs
e /system/etc/fs_config_files
, respectivamente. O sistema de compilação procura android_filesystem_config.h
personalizado em $(TARGET_DEVICE_DIR)
, onde existe BoardConfig.mk
. Se este arquivo existir em outro lugar, defina a variável de configuração da placa TARGET_ANDROID_FILESYSTEM_CONFIG_H
para apontar para esse local.
Configurando o sistema de arquivos
Para configurar o sistema de arquivos no Android 6.0 e superior:
- Crie o arquivo
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Adicione os
fs_config_dirs
e/oufs_config_files
aPRODUCT_PACKAGES
no arquivo de configuração da placa (por exemplo,$(TARGET_DEVICE_DIR)/device.mk
).
Substituir exemplo
Este exemplo mostra um patch para substituir o daemon system/bin/glgps
para adicionar suporte a wake lock no diretório device/ vendor / device
. Tenha em mente o seguinte:
- Cada entrada de estrutura é o modo, uid, gid, capacidades e o nome.
system/core/include/private/android_filesystem_config.h
é incluído automaticamente para fornecer o manifesto #defines (AID_ROOT
,AID_SHELL
,CAP_BLOCK_SUSPEND
). - A seção
android_device_files[]
inclui uma ação para suprimir o acesso asystem/etc/fs_config_dirs
quando não especificado, que serve como uma proteção adicional de DAC por falta de conteúdo para substituições de diretório. No entanto, esta é uma proteção fraca; se alguém tem controle sobre/system
, eles normalmente podem fazer o que quiserem.
diff --git a/android_filesystem_config.h b/android_filesystem_config.h new file mode 100644 index 0000000..874195f --- /dev/null +++ b/android_filesystem_config.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* This file is used to define the properties of the filesystem +** images generated by build tools (eg: mkbootfs) and +** by the device side of adb. +*/ + +#define NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS +/* static const struct fs_path_config android_device_dirs[] = { }; */ + +/* Rules for files. +** These rules are applied based on "first match", so they +** should start with the most specific path and work their +** way up to the root. Prefixes ending in * denotes wildcard +** and will allow partial matches. +*/ +static const struct fs_path_config android_device_files[] = { + { 00755, AID_ROOT, AID_SHELL, (1ULL << CAP_BLOCK_SUSPEND), "system/bin/glgps" }, +#ifdef NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS + { 00000, AID_ROOT, AID_ROOT, 0, "system/etc/fs_config_dirs" }, +#endif +}; diff --git a/device.mk b/device.mk index 0c71d21..235c1a7 100644 --- a/device.mk +++ b/device.mk @@ -18,7 +18,8 @@ PRODUCT_PACKAGES := \ libwpa_client \ hostapd \ wpa_supplicant \ - wpa_supplicant.conf + wpa_supplicant.conf \ + fs_config_files ifeq ($(TARGET_PREBUILT_KERNEL),) ifeq ($(USE_SVELTE_KERNEL), true)
Migrando sistemas de arquivos de versões anteriores
Ao migrar sistemas de arquivos do Android 5.xe anteriores, lembre-se de que o Android 6.x
- Remove algumas inclusões, estruturas e definições embutidas.
- Requer uma referência a
libcutils
em vez de ser executado diretamente desystem/core/include/private/android_filesystem_config.h
. Os executáveis privados do fabricante do dispositivo que dependem desystem/code/include/private_filesystem_config.h
para as estruturas de arquivo ou diretório oufs_config
devem adicionar dependências da bibliotecalibcutils
. - Requer cópias de ramificação privada do fabricante do dispositivo do
system/core/include/private/android_filesystem_config.h
com conteúdo extra em destinos existentes para mover paradevice/ vendor / device /android_filesystem_config.h
. - Reserva-se o direito de aplicar o SELinux Mandatory Access Controls (MAC) aos arquivos de configuração no sistema de destino, implementações que incluem executáveis de destino personalizados usando
fs_config()
devem garantir o acesso.