Os objetos e serviços do sistema de arquivos adicionados ao build geralmente precisam de IDs exclusivos 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, é possível usar AIDs de 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 os recursos do sistema de arquivos e/ou os AIDs personalizados do OEM. No entanto, esse
sistema não era intuitivo, porque não permitia o uso de nomes agradáveis para AIDs OEM,
exigindo que você especificasse o número bruto para campos de usuário e grupo sem uma
maneira de associar um nome amigável ao AID numérico.
Versões mais recentes do Android (Android 8.0 e versões mais recentes) oferecem suporte a um novo método para estender os recursos do sistema de arquivos. Esse novo método oferece suporte para os seguintes recursos:
- Vários locais de origem para os arquivos de configuração (ativa configurações de build extensíveis).
- Verificação de sanidade dos valores de AID do OEM no tempo de build.
- Geração de um cabeçalho AID do OEM personalizado que pode ser usado em arquivos de origem, conforme necessário.
- Associação de um nome amigável com o valor real do AID do OEM. Suporta argumentos de string não numérica 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
os acessadores com getpwnam()
e getgrnam()
. Isso tem o efeito colateral de produzir binários estáveis à medida que os AIDs do núcleo 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). 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 a matriz android_ids[]
do Bionic. Qualquer
define
correspondente a AID_*
é detectado pela ferramenta
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: system
- uid: 1000
- gid: 1000
Para adicionar um novo AID principal do AOSP, basta adicionar o #define
ao
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 está dentro dos intervalos de APP ou OEM.
Ela também respeita as mudanças nesses intervalos e precisa ser reconfigurada
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ê anexe 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
ConfigParser do Python e incluem uma seção de caps (para configurar os recursos
do sistema de arquivos) e uma seção de AIDs (para configurar AIDs OEM).
Configurar a seção de tampas
A seção de maiúsculas oferece suporte à configuração de recursos do sistema de arquivos em objetos do sistema de arquivos no 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 raiz no Android causa uma
falha no conjunto de teste de compatibilidade (CTS),
os requisitos anteriores para manter um recurso durante a execução de um
processo ou serviço envolviam a configuração de recursos e, em seguida, o uso de
setuid
/setgid
para um AID adequado. Com o caps, você
pode pular esses requisitos e deixar que o kernel faça isso por você. Quando o controle é entregue a main()
, seu processo já tem os recursos necessários para que seu serviço possa usar um usuário e um grupo não raiz (essa é a maneira preferencial de iniciar serviços privilegiados).
A seção de letras 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. Nas versões do Python 3.2 ou anteriores, o
mesmo arquivo pode conter seções que substituem a 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 terá um prefixo 0. Caso contrário, 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 Como configurar
o AID. |
group |
AID_<group> | Igual ao usuário. |
caps |
cap* | O nome declarado em
bionic/libc/kernel/uapi/linux/capability.h
sem o CAP_ inicial. É permitido usar letras maiúsculas e minúsculas. As letras maiúsculas também podem ser
o bruto:
|
Para conferir um exemplo de uso, consulte Como usar os recursos do sistema de arquivos.
Configurar a seção AID
A seção AID contém AIDs do 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 letras minúsculas é usada como o
nome amigável. O arquivo principal gerado para inclusão de código usa o
AID_<name> exato.
É um erro especificar várias seções com o mesmo AID_<name> (independentemente da maiúscula ou minúscula, com as mesmas restrições que
[path] ).
<name> precisa começar com um nome de partição para garantir
que não haja conflito com diferentes fontes. |
|
value |
<número> | Uma string de número de estilo C válida (hexa, octal, binário e decimal).
É um erro especificar várias seções com a opção de mesmo 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 conferir exemplos de uso, consulte Como definir nomes de AID OEM e Como usar AIDs OEM.
Exemplos de uso
Os exemplos a seguir detalham como definir e usar um OEM AID e como ativar os 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 garantir que não entrem em conflito com nomes AOSP futuros ou outras partições.
Definir nomes de AID de OEM
Para definir um AID 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
Agora, seu AID personalizado pode ser consumido pelo sistema em um novo build.
Usar AIDs OEM
Para usar um AID OEM, no código C, inclua o oemaids_headers
no Makefile
associado e adicione #include "generated_oem_aid.h"
. Em seguida, 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 amigáveis
No Android 9, é possível usar o nome amigável para qualquer interface compatível com nomes de AID. Exemplo:
- Em um comando
chown
emsome/init.rc
:chown vendor_foo /vendor/some/vendor_foo/file
- Em uma
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 a associação de um nome amigável ao valor real do AID do OEM. É possível usar argumentos de string não numéricos para usuário e grupo, ou seja, "vendor_foo" em vez de "2901".
Converter de AID para nomes amigáveis
Para
AIDs OEM, o Android 8.x exigia o uso de
oem_####
com getpwnam
e funções semelhantes, bem como
em locais 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 em limites no
arquivo config.fs
. Por exemplo, em
device/x/y/config.fs
, adicione esta 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 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
de capacidade setuid
e setgid
e pode ser
excluída.
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 elas podem 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 de correspondência e análise
separadas 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
apenas permitiam a leitura de diretórios e arquivos no ambiente de execução, mas o host podia usar
os mesmos arquivos durante o build para criar 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, ainda é possível usar o método antigo, se necessário. 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 da biblioteca libcutils
(fs_config_generate()
) para gerenciar os requisitos do DAC em um buffer
e define regras para um arquivo de inclusão para institucionalizar as regras do 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 estiver usando android_device_dirs[]
e
android_device_files[]
, você poderá definir
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_DIRS
e
NO_ANDROID_FILESYSTEM_CONFIG_DEVICE_FILES
(consulte 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 de 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
procura 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 do dispositivo (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 ativação no
diretório device/vendor/device
. Lembre-se
do seguinte:
- Cada entrada de estrutura é o modo, o uid, o gid, os 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 adicional do DAC para a falta de conteúdo para substituições de diretório. No entanto, essa é uma proteção fraca. Se alguém tem controle sobre/system
, essa pessoa geralmente pode 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, não esqueça que o Android 6.x
- Remove algumas inclusões, estruturas e definições inline.
- Requer 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 estruturas de arquivo ou diretório oufs_config
precisam adicionar dependências de bibliotecalibcutils
. - Requer que cópias da ramificação privada do fabricante do dispositivo de
system/core/include/private/android_filesystem_config.h
com conteúdo extra nos destinos atuais sejam movidas paradevice/vendor/device/android_filesystem_config.h
. - Reserva o direito de aplicar controles de acesso obrigatórios (MAC, na sigla em inglês) do SELinux a
arquivos de configuração no sistema de destino. As implementações que incluem executáveis
de destino personalizados usando
fs_config()
precisam garantir o acesso.