Antes de tudo, devo admitir que concordo plenamente com o seu "achei isso incrivelmente difícil de fazer" afirmação . O Google projetou o Android principalmente da perspectiva do consumidor, e não para usuários avançados. O resultado é que, assim que você deseja fazer algo fora do uso do aplicativo mais recente do Facebook ou jogar com o Candy Crush, rapidamente se encontra de volta ao reino do Linux do início de 2000, quando era necessário mudar o conhecimento de um desenvolvedor. o que deve ser configurações simples. Acredito que a situação evolua rapidamente à medida que o sistema Android amadurece, mas, por enquanto, temos a ver com o que temos ...
Como você disse, há duas razões pelas quais é necessário compilar seu próprio conjunto de ferramentas SELinux:
- O conjunto de ferramentas fornecido pelo sistema é geralmente uma versão anterior. Enquanto o SELinux do Android conta com o banco de dados de políticas versão 30, as caixas atuais do Linux geralmente lidam apenas com versões de até 29.
- Mesmo que fosse mais recente, não ajudaria, na verdade, a criação do SELinux a partir do código upstream (o que é fácil de fazer, pelo menos nas máquinas Fedora seguindo as recomendações upstream) efetivamente permite que o sistema lide com a política DB versão 30, no entanto, o SELinux do Android foi modificado com muita força (a documentação do Google destaca algumas modificações), portanto, tentar lidar com o SELinux do Android falha devido a erros de sintaxe e de análise.
Portanto, para continuar na busca de análise SELinux do Android, teremos que colocar as mãos na terra ... da maneira mais limpa possível:
- Primeiro vamos configurar um ambiente são,
- Feito isso, compilaremos as bibliotecas SELinux e as primeiras ferramentas do Android,
- Além disso, criaremos ferramentas SELinux,
- Terminaremos adicionando alguns utilitários adicionais.
Configure um ambiente adequado
Propriedades do ambiente
O mais limpo recomendado, um modo possivelmente possivelmente apenas confiável de trabalhar é dedicar um ambiente ao seu trabalho no Android:
Uma máquina virtual é perfeita (se não a melhor opção). Prefira usar um VMware, pois você precisará conectar seu telefone via USB ao sistema convidado. A alternativa gratuita Qemu não parece lidar com essa tarefa muito bem. Eu não tentei com outro software de virualização.
Ele precisará ser um sistema de 64 bits, caso contrário, o código simplesmente não será compilado devido ao número inteiro ser do tamanho errado.
É altamente recomendável, possivelmente obrigatório, usar um sistema Ubuntu. Sinta-se à vontade para usar o Xubuntu, se preferir o ambiente de desktop mais leve do XFCE, isso não altera o núcleo e o pacote disponível do sistema e não terá impacto no seu trabalho relacionado ao Android (o que eu digo sobre o Ubuntu neste procedimento também se aplica ao Xubuntu). Você pode encontrar na árvore de fontes do SELinux do Android alguns arquivos Leia-me recomendando o uso do Fedora, esses arquivos são herdados do projeto SELinux da NSA upstream e seu conteúdo não corresponde necessariamente ao Android do Google.
A versão exata do Unbuntu a ser usada depende da versão do Android que você deseja criar. Para o Android 6.0, o Ubuntu 14.04 (Trusty) é recomendado. Consulte a página de requisitos do Google para obter mais informações.
Você precisará de muito espaço em disco (pelo menos 50 GB se planejar apenas uma investigação relacionada ao SELinux, pelo menos 100 GB se planejar uma compilação completa do Android). A CPU e a memória são menos relevantes, elas afetam apenas o tempo para uma compilação completa e não terão impacto real nas tarefas relacionadas ao SELinux.
O uso do Ubuntu tem duas vantagens principais:
Ao usar o sistema recomendado, você trabalha em um ambiente conhecido e testado: as bibliotecas, ferramentas e pacotes do sistema estão na versão e no local esperados pelo projeto.
E, mais especificamente, no nosso caso atual: o próprio Ubuntu conta com o AppArmor, que é uma alternativa ao SELinux, não usa o SELinux. A boa notícia é que você poderá instalar as ferramentas e binários SELinux do Android em todo o sistema, sem correr o risco de alterar a confiabilidade do sistema.
Procedimento de instalação do ambiente
Você pode instalar o Ubuntu da maneira tradicional, iniciando a partir de um live-DVD completo, mas uma alternativa mais rápida é usar uma instalação pelo netboot (instalação por modo de texto) e selecionar o ambiente de área de trabalho que você preferir no final. Isso poupará o tempo de atualização inicial, instalando diretamente a versão atualizada dos pacotes, em vez de instalar os obsoletos e solicitando a aplicação de 389 atualizações pendentes na primeira inicialização.
O instalador do netboot ISO para Ubuntu / Xubuntu 14.04 (mesmo ISO) está disponível aqui .
Para pular o problemático recurso "Instalação Fácil" da VMware, é um bom hábito começar selecionando a opção "Instalarei o sistema operacional mais tarde" .
Certifique-se de selecionar Linux e Ubuntu 64 bits como SO convidado.
A VM precisará dos seguintes recursos:
- Obrigatório: o espaço em disco deve ter no mínimo 40 GB (os 20 GB padrão não serão suficientes, apenas o código-fonte ocupa mais espaço do que isso); recomenda-se maior. Uma compilação completa requer um disco de 100 GB, no mínimo, esse é o valor que costumo usar. Não esqueça que essa configuração é apenas um limite máximo: o tamanho real obtido pela VM cresce dinamicamente com as solicitações dos convidados.
- Facultativo: aumente a RAM de 1024 para pelo menos 2048 ou superior (depende da capacidade do host, uso 4096),
- Facultativo: Aumente o número de núcleos do processador de 1 para 2 ou superior (depende da capacidade do host, eu uso 3).
- O CD-Rom deve apontar para o arquivo ISO de instalação.
- Você pode mudar o USB do padrão 1.1 para o 2.0, pois o primeiro pode emitir avisos quando você conecta o dispositivo. Dependendo do uso, você também pode desmarcar com segurança "Conectar automaticamente novos dispositivos USB" e "Compartilhar dispositivos Bluetooth com a máquina virtual" .
- Dependendo do seu ambiente, você também pode precisar ajustar as configurações de exibição (desativar 3D, impor um tamanho de tela).
Atenção:
- Se você escolheu a instalação do netboot, não se esqueça de selecionar o ambiente da área de trabalho ( área de trabalho Ubuntu ou área de trabalho Xubuntu ) ao acessar a seleção Software tela de ou você terá um ambiente apenas de texto mínimo!
- Na primeira inicialização, recuse - se a atualizar para a versão mais recente: o ponto principal aqui é permanecer na versão 14.04!
Após a primeira inicialização, uma das primeiras que você pode querer fazer é instalar as ferramentas de convidado do Linux:
sudo apt-get install open-vm-tools
Este pacote coloca gatilhos no momento da inicialização, portanto, sua instalação será concluída somente após a reinicialização do convidado.
Buscar código fonte do Android
Embora semelhantes, os detalhes do procedimento dependem da ROM escolhida:
- No CyanogenMod, procure seu dispositivo (selecione o fornecedor primeiro) e clique em "Como criar o CyanogenMod" link para obter instruções adaptadas ao seu dispositivo.
- Para o AOSP, siga o procedimento que começa aqui .
Pode-se notar que o CyanogeMod agrupa em sua árvore de origem uma ferramenta que permite descompactar boot.img
arquivos. Em outras palavras, o CyanogenMod fornece uma ferramenta que permite acessar o sepolicy
arquivo armazenado em dispositivos e arquivos ROM. O AOSP do Google não fornece essa ferramenta; portanto, se você não tem outro imperativo, usar a árvore de fontes do CyanogenMod pode ser a escolha mais conveniente; caso contrário, você precisará instalá-lo separadamente (o que é rápido e fácil de fazer, então não se preocupe aqui).
Aqui estou seguindo o procedimento CyanogenMod 13.0 (Android 6.0). As explicações sobre os comandos utilizados estão disponíveis nas páginas vinculadas acima. Por favor, leia-os, o texto datilografado abaixo é fornecido apenas para fins de referência.
Dica: Enquanto eu usoapt-get
este post para manter o menor denominador comum e manter todos felizes, você pode preferir usá-aptitude
lo, pois ele cuidará das dependências de uma maneira melhor (ao remover um pacote que requer a instalação de algumas dependências) , essas dependências também serão removidas, deixando o sistema mais limpo). AFAIK, oaptitude
comando deve estar instalado no Ubuntu, mas está disponível por padrão no Xubuntu.
sudo apt-get install bison build-essential curl flex git gnupg gperf \
libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk2.8-dev libxml2 \
libxml2-utils lzop maven openjdk-7-jdk pngcrush schedtool squashfs-tools \
xsltproc zip zlib1g-dev g++-multilib gcc-multilib lib32ncurses5-dev \
lib32readline-gplv2-dev lib32z1-dev
mkdir -p ~/bin
mkdir -p ~/android/system
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod u+x ~/bin/repo
cd ~/android/system/
git config --global user.name "Your Name"
git config --global user.email "you@example.com
repo init -u https://github.com/CyanogenMod/android.git -b cm-13.0
repo sync
# Coffee time: around 20GB are being downloaded, this may take several hours.
source ./build/envsetup.sh
breakfast
Agora você tem uma árvore de fontes limpa e quase completa. Os blobs proprietários estão ausentes, mas você não precisa deles para tarefas relacionadas ao SELinux.
Gorjeta: Buscar as fontes é um processo tedioso; pode valer a pena fazer um instantâneo ou backup da sua VM agora.
Compile e instale o conjunto de ferramentas e bibliotecas SELinux do Android
Agora começa a parte engraçada da viagem;)!
Até agora, o procedimento deveria ter sido bastante direto. O objetivo era principalmente garantir que você tivesse o mesmo ambiente que eu. Se o fizer, a sequência também deve permanecer direta.
Sob o capô do Google, não hesite em aplicar mudanças profundas no código-fonte do Android entre as versões; portanto, as etapas exatas de compilação serão certamente dependentes da versão (por exemplo, o mestre do AOSP mostra que o sepolicy/
diretório será movido ).
Primeiro compartilharei meu procedimento exato para compilar e instalar as bibliotecas e o conjunto de ferramentas SElinux do Android, mas, para manter a relevância deste post ao longo do tempo, adicionarei algumas notas sobre a abordagem genérica a seguir para resolver a maioria dos problemas de compilação.
Procedimento passo a passo
As bibliotecas SELinux do Android fornecem a camada de abstração que permitirá que o software da camada superior lide com arquivos de política do SELinux específicos do Android. Portanto, precisaremos compilá-los e instalá-los primeiro (o que, por si só, realmente representa o núcleo das dificuldades aqui, até você encontrar o caminho).
Poderemos então construir e instalar ferramentas do SELinux. Como veremos, felizmente, eles não precisam ser específicos para Android, precisam apenas corresponder à versão da biblioteca do SELinux.
Este procedimento foi testado usando as árvores de código-fonte CyanogenMod e AOSP.
Compilar e instalar as bibliotecas do Android SELinux e as primeiras ferramentas
Primeiro instale dependências:
sudo apt-get install libapol-dev libaudit-dev libdbus-glib-1-dev libgtk2.0-dev \
libustr-dev python-dev python-networkx swig xmlto
Nesta postagem, a variável $ANDROID_BUILD_TOP
armazena sua localização de origem (o diretório em que você emitiu o repo sync
comando). Sinta-se livre para mudar o nome como quiser.
ANDROID_BUILD_TOP=~/android/system
cd $ANDROID_BUILD_TOP
source ./build/envsetup.sh
Por padrão, a compilação dos utilitários principais da política falha porque restorecond
o Makefile não consegue localizar algumas bibliotecas. Você precisa editar este Makefile para usar caminhos gerados dinamicamente por pkg-config
vez de codificados (não confunda backticks com aspas simples!):
sed -i 's/^CFLAGS ?= -g -Werror -Wall -W$/& `pkg-config --cflags --libs dbus-1 gtk+-2.0`/' \
$ANDROID_BUILD_TOP/external/selinux/policycoreutils/restorecond/Makefile
Sinta-se livre para abrir o Makefile com algum editor de texto para garantir que a modificação tenha sido levada em consideração corretamente.
E agora compile e instale:
cd $ANDROID_BUILD_TOP/external/bzip2/
make -f Makefile-libbz2_so
sudo make install
cd $ANDROID_BUILD_TOP/external/libcap-ng/libcap-ng-0.7/
./configure
make
sudo make install
cd $ANDROID_BUILD_TOP/external/selinux/
make -C ./libsepol/
sudo make -C /libsepol/ install
EMFLAGS=-fPIC make -C ./libselinux/
sudo make -C ./libselinux/ install
make -C ./libsemanage/
sudo make -C ./libsemanage/ install
make
sudo make install
make swigify
sudo make install-pywrap
sudo cp ./checkpolicy/test/{dispol,dismod} /usr/bin/
Atenção: Não perca aEMFLAGS=-fPIC
configuração da variável de ambiente ao construirlibselinux
. Ainda não gerará nenhum erro, mas na próxima etapa você não poderá construir o SETools. Caso você tenha perdido ou feito algo errado, basta emitir ummake clean
e reiniciar sua compilação.
Compilar e instalar ferramentas SELinux
As ferramentas SELinux são fornecidas em um formato pré-construído, que inclui:
- Scripts Python (e seus wrappers de script de shell) dentro do
$ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/
diretório
- Pacotes Python (incluindo
*.o
arquivos compilados) abaixo $ANDROID_BUILD_TOP/prebuilts/python/linux-x86/2.7.5/lib/python2.7/site-packages/
.
Eu esperava que o código fonte dessas ferramentas estivesse disponível abaixo $ANDROID_BUILD_TOP/external
, mas não está. Na verdade, não encontrei nenhum lugar em que o Google compartilhasse a versão exata do SETools que eles usavam (para sua informação, a GPL apenas exige o compartilhamento do código se ele tiver sido modificado), por isso teremos que adivinhar e tentar fazer o melhor que pudermos .
As ferramentas em si são scripts Python, essa é uma nova evolução do SETools 4 (no SETools 3, comandos como sesearch
executáveis binários codificados em C). No entanto, as próprias ferramentas ainda mostram uma versão do 3.3.8:
$ $ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/sesearch --version
3.3.8
Então, meu palpite é que o Google tirou um instantâneo de desenvolvimento inicial do SETools 4. Até o 4.0.0 beta, o SETools contava com o libsepol
versoin 2.4, com o lançamento do 4.0.0, eles começaram a confiar na versão 2.5 da biblioteca, que não é compatível com a versão do SELinux empacotado no Android 6.0 (você pode tentar compilar isso, apenas falhará).
Portanto, a escolha mais sábia parece ir com o SETools 4.0.0 Beta.
Instale dependências suplementares:
sudo apt-get install python-setuptools
Faça o download e extraia o código fonte:
cd ~/android/
wget https://github.com/TresysTechnology/setools/archive/4.0.0-beta.tar.gz
tar xzf 4.0.0-beta.tar.gz
cd ./setools-4.0.0-beta/
Devido a um bug que afeta o Flex 2.5, precisamos remover -Wredundant-decls
dos sinalizadores do compilador:
sed -i '/-Wredundant-decls/d' ./setup.py
E finalmente compile e instale:
python ./setup.py build
sudo python ./setup.py install
Procedimento genérico (ou "Como se libertar")
Caso o procedimento acima não funcione no seu caso, aqui está uma visão de nível superior sobre como tentar progredir.
Infelizmente, não existe mágica (e nenhum auxiliar :() por aqui: a única maneira de compilar esse código é a abordagem cíclica clássica, ainda que temida, de "experimentar e ver".
Tente compilar pela primeira vez, provavelmente falhará devido a algum *.h
arquivo não ser encontrado:
Procure no external/
diretório do Android :
find $ANDROID_BUILD_TOP/external -name filename.h
Se você encontrar o arquivo solicitado, isso significa que uma versão específica da biblioteca ou ferramenta correspondente foi agrupada no código-fonte do Android. Portanto, você não deve tentar instalá-lo a partir do sistema de pacotes do Ubuntu, mas compilar e instalar a versão incluída no código-fonte do Android.
Esteja ciente de que isso vai contra o conselho geral que você pode encontrar nos fóruns: "Sua compilação falhou devido à falta dessa biblioteca? Instale este pacote e tudo ficará bem!" , ao fazer isso, você provavelmente só enfrentará um problema pior: se uma versão específica estiver agrupada, provavelmente será necessária uma versão específica (devido a problemas de compatibilidade ou porque esta versão contém alterações específicas do Google).
BTW, se você está se perguntando: é claro que essa biblioteca ou ferramenta também pode ter dependências gerando erros devido a alguns *.h
arquivos não serem encontrados, e sim, você deve aplicar essa mesma abordagem cíclica de "experimentar e ver".
Pesquisa em todo o sistema:
find / -name filename.h 2>/dev/null
Se você encontrar "faltando" o arquivo já presente em seu sistema em algum local padrão da biblioteca compartilhada, isso significa que essa dependência provavelmente já foi atendida em seu ambiente, mas o Makefile que gerou o erro é burro demais para encontrá-lo.
Se você chamar manualmente diretamente esse Makefile, poderá ser possível definir alguma variável de ambiente corrigindo isso ( LIBDIR=/usr/lib make
por exemplo); caso contrário, poderá ser necessário modificar o próprio Makefile (o pkg-config
comando pode ser de uma ajuda preciosa para gerar automaticamente parâmetros de construção ausentes) .
Procure no sistema de embalagem:
apt-cache search filename-dev
Onde filename-dev
representa o nome do arquivo ausente em minúsculas com a .h
extensão substituída pelo -dev
sufixo (por exemplo, se Python.h
não for encontrado, procure python-dev
). Alguns ajustes no nome exato podem ser necessários para encontrar o pacote certo.
Se você permanecer parado e mesmo uma pesquisa rápida na Internet não fornecer uma resposta clara, apt-file
será o seu melhor amigo. apt-file
não está instalado por padrão, você precisa instalá-lo e gerar seu banco de dados:
sudo apt-get apt-file
sudo apt-file update
apt-file
permite procurar pacotes (mesmo os desinstalados) que fornecem um arquivo específico. Para evitar muito resultado, recomendo associá-lo grep
como abaixo:
apt-file search filename.h | grep -w filename.h
Se houver um pacote no repositório do Ubuntu fornecendo esse arquivo, você apt-file
poderá encontrá-lo.
Depois de encontrar o pacote certo, instale-o usando apt-get install packagename
onde packagename
está o nome do seu pacote.
Dica: Se você ferrou algo em seu sistema, o comando para reinstalar um pacote é esta:apt-get reinstall pkg_name
. Ele funcionará mesmo quando uma remoção e instalação clássica não for possível devido à quebra de dependências (o que é mais provável para as bibliotecas do sistema).
Ferramentas suplementares
Nesta etapa, agora você deve ter um ambiente limpo que permita investigar as regras SELinux do Android, tanto nos formatos compilados quanto nos de origem.
No entanto, a maioria das chances é de que, no final de sua investigação, você queira tomar alguma ação. Em sua forma atual, seu ambiente não permitirá que você modifique o sepolicy
arquivo de um dispositivo . Na verdade, esse arquivo não pode ser facilmente substituído: faz parte do diretório raiz do dispositivo e o conteúdo do diretório raiz é extraído no momento da inicialização de um arquivo de disco RAM, que por sua vez é armazenado na imagem de inicialização do dispositivo.
Então, você ainda perde duas coisas antes que seu ambiente esteja completo:
- Uma maneira de acessar e modificar a imagem de inicialização do dispositivo,
- Uma maneira de modificar seu
sepolicy
arquivo.
Felizmente, esses são precisamente o assunto das duas últimas seções deste post! :)
Buscar e atualizar a imagem de inicialização do dispositivo
As ferramentas para buscar e atualizar a imagem de inicialização dos dispositivos podem ser usadas para uma grande variedade de coisas, além da violação das regras do SELinux. Portanto, criei uma resposta dedicada , consulte-a.
Modificar regras SELinux do dispositivo
Você tem duas possibilidades principais aqui:
- Crie um novo
sepolicy
arquivo a partir das regras da sua árvore de origem (procure .te
arquivos para encontrá-los:, find $ANDROID_BUILD_TOP -name \*.te
eles estão espalhados em vários diretórios).
- Modifique o
sepolicy
arquivo usado atualmente pelo dispositivo.
A menos que você realmente precise criar suas regras do zero, o que é mais uma tarefa relacionada ao desenvolvimento e, portanto, fora do escopo aqui, a segunda opção parece de longe a mais segura, pois você tem certeza de que as únicas alterações serão as suas. explicitamente feito.
Houve um projeto para criar uma ferramenta que permite descompilar um sepolicy
arquivo em um formato recompilável, permitindo editar livremente as regras intermediárias. No entanto, este projeto foi abandonado em estado de prova de conceito. Você encontrará todas as informações no final deste post , o restante do artigo contém detalhes suficientes para permitir que qualquer pessoa interessada assuma o controle.
A maneira atualmente recomendada de alterar sepolicy
regras segue outra rota: modificando diretamente o sepolicy
arquivo binário. A ferramenta sepolicy-inject permite exatamente isso e é mantida ativamente.
Por uma questão de integridade, observe que existe uma bifurcação dessa ferramenta. Ele adiciona alguns recursos, alguns dos quais estão na lista de tarefas do autor original (como a possibilidade de remover uma regra), não me pergunte por que eles escolheram bifurcar-se em vez de contribuir ...
Para compilar e instalar sepolicy-inject
, basta fazer o seguinte:
cd ~/android/
git clone https://bitbucket.org/joshua_brindle/sepolicy-inject.git
cd ./sepolicy-inject/
LIBDIR=/usr/lib make
sudo cp ./sepolicy-inject /usr/bin/
Exemplo de caso de uso
Digamos, por exemplo, que você queira adicionar a autorização correspondente à seguinte mensagem de erro:
avc: denied { read } for pid=128 comm="file-storage"
path="/data/media/0/path/to/some/file"
dev="mmcblk0p28" ino=811035 scontext=u:r:kernel:s0
tcontext=u:object_r:media_rw_data_file:s0 tclass=file permissive=0
Você precisará buscar a imagem de inicialização do dispositivo e descompactá-la para obter acesso ao seu sepolicy
arquivo.
Uma verificação rápida usando sesearch
mostra que realmente não há regra de permissão (ainda!):
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
$
O comando não possui saída.
Em seguida, use o comando abaixo para adicionar a regra necessária (observe a semelhança entre sesearch
e sepolicy-inject
parâmetros):
sepolicy-inject -s kernel -t media_rw_data_file -c file -p read -P ./sepolicy
Agora podemos retornar nosso sesearch
comando:
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
allow kernel media_rw_data_file:file read;
$
sesearch
A saída mostra que a política foi atualizada corretamente.
Agora você pode reembalar o boot.img
arquivo do dispositivo e atualizá-lo novamente. Verificar a hora da última modificação do /sepolicy
arquivo é uma maneira fácil de garantir que seu dispositivo esteja executando o sepolicy
arquivo atualizado recentemente .
Conclusão
Agora você deve ter um ambiente completo que permita inspecionar e modificar livremente as políticas do SELinux de dispositivos Android. Desfrutar! :)
Como observação, também existem ferramentas que permitem analisar e modificar a política do SELinux diretamente do dispositivo .