Os objetos e serviços do sistema de arquivos adicionados ao build geralmente precisam de IDs separados, 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 do 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 recursos do sistema de arquivos e/ou AIDs personalizados do OEM. No entanto, esse
sistema não era intuitivo, porque não oferecia suporte ao uso de nomes amigáveis para AIDs do OEM,
exigindo que você especificasse o valor 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 mais recentes) oferecem suporte a um novo método para estender os recursos do sistema de arquivos. Esse novo método oferece suporte ao 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 criação dos valores de AID do OEM.
- Geração de um cabeçalho de AID do 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. Oferece suporte a 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 android_ids[]
matriz 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 AIDs principais são modificados. Para conferir
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 amigáveis de AID são gerados no
arquivo principal system/core/libcutils/include/private/android_filesystem_config.h
ao gerar a matriz android_ids[] do Bionic. Qualquer
define correspondente a AID_* é selecionado pela ferramenta
e * se torna o nome em letras minúsculas.
Por exemplo, em private/android_filesystem_config.h:
#define AID_SYSTEM 1000O resultado é:
- Nome amigável: system
- uid: 1000
- gid: 1000
Para adicionar um novo AID principal do AOSP, basta adicionar o #define ao
android_filesystem_config.h arquivo principal. 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 deve ser reconfigurada automaticamente
em mudanças ou novos intervalos reservados pelo OEM.
Configurar AIDs
Para ativar o novo mecanismo de AIDs, defina TARGET_FS_CONFIG_GEN no
BoardConfig.mk arquivo. 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 é possível usar qualquer nome. Os arquivos config.fs estão no formato ini do Python
ConfigParser e incluem uma seção de recursos (para configurar os recursos do sistema de arquivos) e uma seção de AIDs (para configurar AIDs do OEM).
Configurar a seção de recursos
A seção de recursos oferece suporte à definiçã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 testes de compatibilidade (CTS), os requisitos anteriores para manter um recurso 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 os recursos, é possível ignorar esses requisitos e fazer com que o kernel faça isso para você. Quando o controle é
entregue a main(), o processo já tem os recursos necessários para que o serviço possa usar um usuário e grupo não raiz. Essa é a maneira preferencial
de iniciar serviços privilegiados.
A seção de recursos 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, 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 3 dígitos. Se 3 for especificado, ele será prefixado com um 0. Caso contrário, o modo será usado no estado em que se encontra. |
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 Como configurar
a seçã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. Uso misto de maiúsculas e minúsculas permitido. Os recursos também podem ser
brutos:
|
Para conferir um exemplo de uso, consulte Como usar 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 no conjunto
letras 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 exato
AID_<name>.
É um erro especificar várias seções com o mesmo AID_<name> (sem distinção entre 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 diferentes origens. |
|
value |
<number> | Uma string de número de estilo C válida (hexadecimal, octal, binária 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 conferir exemplos de uso, consulte Como definir nomes de AID do OEM e Como usar AIDs do OEM.
Exemplos de uso
Os exemplos a seguir detalham como definir e usar um AID do OEM 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 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 consumido pelo sistema em geral em um novo build.
Usar AIDs do 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". 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 que ofereça suporte a nomes de AID. Por exemplo:
- Em um comando
chownemsome/init.rc:chown vendor_foo /vendor/some/vendor_foo/file
- Em um
serviceemsome/init.rc:service vendor_foo /vendor/bin/foo_service user vendor_foo group vendor_foo
Como o mapeamento interno do nome amigável para 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éricos para usuário e grupo, ou seja, "vendor_foo" em vez de "2901".
Converter de AID para nomes amigáveis
Para
AIDs do 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
init scripts). 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 de recursos no
config.fs arquivo. 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 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.
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 poderiam 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 poderiam 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 permitiram a leitura de diretórios e arquivos no ambiente de execução, mas o host poderia 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 de extensão do sistema de arquivos tenha sido substituído por o sistema de configuração modular introduzido no Android 8.0, ainda é possível usar o método antigo se desejado. 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 para 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 estiver usando android_device_dirs[] e android_device_files[], é possível 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 base aplicado 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 personalizado 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 mais recentes:
- Crie o arquivo
$(TARGET_DEVICE_DIR)/android_filesystem_config.h. - Adicione
fs_config_dirse/oufs_config_filesaPRODUCT_PACKAGESno 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 system/bin/glgps
daemon para adicionar suporte ao wake lock no
device/vendor/device diretório. Tenha em mente o
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 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_dirsquando não especificado, que serve como uma proteção DAC adicional para falta de conteúdo para substituições de diretório. No entanto, essa é uma 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 algumas inclusões, estruturas e definições inline.
- Exige uma referência a
libcutilsem vez de executar diretamente desystem/core/include/private/android_filesystem_config.h. Os executáveis particulares do fabricante do dispositivo que dependem desystem/code/include/private_filesystem_config.hpara as estruturas de arquivo ou diretório oufs_configprecisam adicionarlibcutilsdependências da biblioteca. - Exige cópias de ramificação particulares do fabricante do dispositivo de
system/core/include/private/android_filesystem_config.hcom conteúdo extra em destinos atuais para migrar 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.