Objetos e serviços do sistema de arquivos adicionados ao build geralmente precisam de IDs separados e exclusivos, conhecidos como IDs do Android (AIDs). Atualmente, muitos recursos, como arquivos e serviços, usam AIDs principais (definidos pelo Android) desnecessariamente. Em muitos casos, é possível usar AIDs OEM (definidos pelo OEM).
As versões anteriores do Android (Android 7.x e anteriores) estenderam o mecanismo de AIDs usando um arquivo android_filesystem_config.h
específico do dispositivo para especificar funcionalidades do sistema de arquivos e/ou AIDs personalizados do OEM. No entanto, esse sistema não era intuitivo porque não permitia o uso de nomes conhecidos para AIDs de OEM. Era necessário especificar o valor numérico bruto para os campos de usuário e grupo sem uma maneira de associar um nome conhecido ao AID numérico.
Versões mais recentes do Android (Android 8.0 e mais recentes) oferecem suporte a um novo método para ampliar os recursos do sistema de arquivos. Esse novo método é compatível com o seguinte:
- Vários locais de origem para arquivos de configuração (permite configurações de build extensíveis).
- Verificação de integridade no momento da build dos valores de AID do OEM.
- Geração de um cabeçalho AID OEM personalizado que pode ser usado em arquivos de origem conforme necessário.
- Associação de um nome amigável ao valor real do AID do OEM. Aceita argumentos de string não numéricos para usuário e grupo, ou seja, "foo" em vez de "2901".
Outras melhorias incluem a remoção da matriz android_ids[]
de system/core/libcutils/include/private/android_filesystem_config.h
. Essa matriz agora existe no Bionic como uma matriz gerada totalmente particular, com acessadores com getpwnam()
e getgrnam()
. Isso tem o efeito colateral de produzir binários estáveis à medida que os AID principais são modificados. Para
ferramentas e um arquivo README com mais detalhes, consulte
build/make/tools/fs_config
.
Adicionar IDs do Android (AIDs)
O Android 8.0 removeu a matriz android_ids[]
do Android Open Source Project (AOSP). Em vez disso, todos os nomes compatíveis com AID são gerados do arquivo de cabeçalho system/core/libcutils/include/private/android_filesystem_config.h
ao gerar a matriz android_ids[]
do Bionic. Qualquer
define
que corresponda a AID_*
é capturada pelas ferramentas
e * se torna o nome em letras minúsculas.
Por exemplo, em private/android_filesystem_config.h
:
#define AID_SYSTEM 1000
O resultado é:
- Nome amigável: sistema
- uid: 1000
- gid: 1000
Para adicionar uma nova AID principal do AOSP, basta incluir #define
no arquivo de cabeçalho android_filesystem_config.h
. O AID é gerado no build e disponibilizado para interfaces que usam argumentos de usuário e grupo. A ferramenta valida se o novo AID não está nos intervalos do APP ou do OEM. Ela também respeita as mudanças nesses intervalos e se reconfigura automaticamente em caso de mudanças ou novos intervalos reservados pelo OEM.
Configurar AIDs
Para ativar 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 que você adicione 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 ini do Python
ConfigParser e incluem uma seção de recursos (para configurar as funcionalidades do sistema de
arquivos) e uma seção de AIDs (para configurar os AIDs do OEM).
Configurar a seção de maiúsculas
A seção de recursos permite definir capacidades do sistema de arquivos em objetos do sistema de arquivos na build. O próprio sistema de arquivos também precisa oferecer suporte a essa funcionalidade.
Como a execução de um serviço estável como root no Android causa uma
falha no conjunto de teste de compatibilidade (CTS), os requisitos anteriores para reter uma capacidade ao executar um
processo ou serviço envolviam a configuração de recursos e o uso de
setuid
/setgid
para um AID adequado para execução. Com as capacidades, você
pode pular esses requisitos e deixar que o kernel faça isso por você. Quando o controle é transferido para main()
, seu processo já tem os recursos necessários para que o serviço use um usuário e um grupo não raiz. Essa é a maneira preferida de iniciar serviços privilegiados.
A seção de maiúsculas 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 diretório, caso contrário, é um arquivo.
É um erro especificar várias seções com o mesmo [path] em arquivos diferentes. Em versões do Python <= 3.2, o mesmo arquivo pode conter seções que substituem a seção anterior. No Python 3.2, ele é definido como modo estrito. |
|
mode |
Modo de arquivo octal | Um modo de arquivo octal válido de pelo menos três dígitos. Se 3 for especificado, ele vai receber o prefixo 0. Caso contrário, o modo será usado como está. |
user |
AID_<user> | 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 Configurar
a seção AID. |
group |
AID_<group> | Igual a "user". |
caps |
cap* | O nome declarado em
bionic/libc/kernel/uapi/linux/capability.h
sem o CAP_ inicial. É permitido usar maiúsculas e minúsculas. As maiúsculas também podem ser
o valor bruto:
|
Para um exemplo de uso, consulte Como usar recursos do sistema de arquivos.
Configurar a seção AID
A seção AID contém AIDs de OEM e usa a seguinte sintaxe:
Seção | Valor | Definição |
---|---|---|
[AID_<name>] |
O <name> pode conter caracteres do conjunto
maiúsculas, números e sublinhados. A versão em letras minúsculas é usada como o
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> (sem diferenciação de maiúsculas e minúsculas, com as mesmas restrições de
[path] ).
<name> precisa começar com um nome de partição para garantir
que não haja conflito com fontes diferentes. |
|
value |
<número> | Uma string de número válida no estilo C (hexadecimal, octal, binário e decimal).
É um erro especificar várias seções com a mesma opção de valor. As opções de valor precisam ser especificadas no intervalo correspondente à partição usada em <name> . A lista de partições válidas e os intervalos correspondentes são definidos em system/core/libcutils/include/private/android_filesystem_config.h .
As opções são:
|
Para exemplos de uso, consulte Definir nomes de AID do OEM e Usar AIDs do OEM.
Exemplos de uso
Os exemplos a seguir detalham como definir e usar um AID do OEM e como ativar recursos do sistema de arquivos. Os nomes de AID do OEM ([AID_name]) precisam começar com um nome de partição, como "vendor_", para não entrar em conflito com nomes futuros do AOSP ou outras partições.
Definir nomes de AID do OEM
Para definir um AID do OEM, 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
Depois de 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 usado pelo sistema em geral em um novo build.
Usar AIDs OEM
Para usar um AID do OEM, no código C, inclua o oemaids_headers
no Makefile associado e adicione #include "generated_oem_aid.h"
. Depois, 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 ...
No 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
Usar nomes fáceis de lembrar
No Android 9, é possível usar o nome amigável para qualquer interface que ofereça suporte a nomes de AID. Exemplo:
- Em um comando
chown
nosome/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 é realizado por
/vendor/etc/passwd
e /vendor/etc/group
, a partição
do fornecedor precisa ser montada.
Associar nomes amigáveis
O Android 9 inclui suporte para associar um nome amigável ao valor real do AID do OEM. É possível usar argumentos de string não numérica para usuário e grupo, ou seja, "vendor_foo" em vez de "2901".
Converter de AID para nomes fáceis de lembrar
Para AIDs de OEM, o Android 8.x exigia o uso de oem_####
com getpwnam
e funções semelhantes, bem como em lugares que processam pesquisas com getpwnam
(como scripts init
). No Android 9, é possível
usar os amigos getpwnam
e getgrnam
no Bionic para
converter de IDs do Android (AIDs) para nomes amigáveis e vice-versa.
Usar recursos do sistema de arquivos
Para ativar 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
Depois de 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 começa
com as funcionalidades CAP_SYS_ADMIN
e CAP_SYS_NICE
sem chamadas setuid
e setgid
. Além disso, a política do SELinux do serviço
vendor_foo
não precisa mais das capacidades
setuid
e setgid
e pode ser
excluída.
Configurar substituições (Android 6.x a 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 podiam ser atualizadas ou substituídas 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 processasse diretórios e arquivos em duas tabelas diferentes.
As definições de estrutura em system/core/libcutils/fs_config.c
não
permitiam apenas a leitura de diretórios e arquivos em tempo de execução, mas o host podia usar
os mesmos arquivos durante o tempo de build 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 para estender o sistema de arquivos tenha sido substituído pelo sistema de configuração modular introduzido no Android 8.0, ainda é possível usar o método antigo, se quiser. As seções a seguir detalham como gerar e incluir arquivos de substituição e configurar o sistema de arquivos.
Gerar arquivos de substituição
É possível 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 institucionalizar as regras de DAC.
Para usar, crie um arquivo de inclusão em
device/vendor/device/android_filesystem_config.h
que funcione como a substituição. O arquivo precisa usar o formato
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 usar android_device_dirs[]
e
android_device_files[]
, você poderá definir
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
e
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(confira o
exemplo abaixo). Também é possível especificar o arquivo de substituição usando TARGET_ANDROID_FILESYSTEM_CONFIG_H
na configuração da placa, com um nome base forçado de android_filesystem_config.h
.
Incluir arquivos de substituição
Para incluir arquivos, verifique se PRODUCT_PACKAGES
inclui
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 build
pesquisa android_filesystem_config.h
personalizados em
$(TARGET_DEVICE_DIR)
, onde BoardConfig.mk
existe.
Se esse arquivo existir em outro lugar, defina a variável de configuração da placa
TARGET_ANDROID_FILESYSTEM_CONFIG_H
para apontar para esse local.
Configurar o sistema de arquivos
Para configurar o sistema de arquivos no Android 6.0 e versões mais recentes:
- Crie o arquivo
$(TARGET_DEVICE_DIR)/android_filesystem_config.h
. - Adicione
fs_config_dirs
e/oufs_config_files
aPRODUCT_PACKAGES
no arquivo de configuração da placa (por exemplo,$(TARGET_DEVICE_DIR)/device.mk
).
Exemplo de substituição
Este exemplo mostra um patch para substituir o daemon system/bin/glgps
e adicionar suporte ao bloqueio de despertar no diretório
device/vendor/device
. Lembre-se do seguinte:
- Cada entrada de estrutura é o modo, uid, gid, recursos e o nome.
system/core/include/private/android_filesystem_config.h
é incluído automaticamente para fornecer as #defines do manifesto (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, o que serve como uma proteção DAC adicional por falta de conteúdo para substituições de diretório. No entanto, essa proteção é fraca. Se alguém tiver controle sobre/system
, geralmente poderá fazer o que quiser.
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 file system +** 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)
Migrar sistemas de arquivos de versões anteriores
Ao migrar sistemas de arquivos do Android 5.x e versões anteriores, lembre-se de que o Android 6.x
- Remove alguns includes, estruturas e definições inline.
- Exige uma referência a
libcutils
em vez de ser executado diretamente desystem/core/include/private/android_filesystem_config.h
. Executáveis particulares do fabricante do dispositivo que dependem desystem/code/include/private_filesystem_config.h
para as estruturas de arquivo ou diretório oufs_config
precisam adicionar dependências da bibliotecalibcutils
. - Exige 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 atuais para migrar paradevice/vendor/device/android_filesystem_config.h
. - Reserva o direito de aplicar controles de acesso obrigatório (MAC) do SELinux a
arquivos de configuração no sistema de destino. Implementações que incluem executáveis de
destino personalizados usando
fs_config()
precisam garantir o acesso.