Examine a política selinux do android (v30)


12

Estou tentando descobrir qual política é realmente aplicada pelo meu telefone usando o selinux. Você pensaria que isso seria fácil. Afinal, por segurança, é bom verificar se sua política corresponde às expectativas. Infelizmente, achei isso incrivelmente difícil de fazer, porque A) o Android parece usar uma versão bifurcada da política 30 e B) a cadeia de ferramentas da política parece ter um processo de compilação de qualidade muito baixa (muitos caminhos codificados, etc. .).

Aqui estão duas coisas que tentei que não funcionaram. Se eu tentar usar as ferramentas de configuração de prateleira (como o pacote fornecido para o fedora ou pode ser instalado no AUR com o arch linux), obtenho o seguinte (depois de puxar /sepolicypelo diretório raiz ou pela imagem de fábrica do telefone):

$ sedispol sepolicy 
Reading policy...
libsepol.policydb_read: policydb version 30 does not match my version range 15-29
sedispol:  error(s) encountered while parsing configuration
$ sesearch --all sepolicy 
ERROR: policydb version 30 does not match my version range 15-29
ERROR: Unable to open policy sepolicy.
ERROR: Success
$

Ok, então isso sugere que eu tenho que construir a versão android das bibliotecas selinux. A árvore de origem do AOSP vem com versões pré-compiladas de algumas ferramentas, mas elas dependem de bibliotecas compartilhadas antigas que eu não tenho (como libpcre3). De qualquer forma, é bastante chocante se a única maneira de verificar sua política de segurança é confiar em alguma biblioteca compartilhada binária que você sai da rede.

Então, aqui está o que eu fiz para criar as bibliotecas selinux do Android. No arch, eu tive que instalar a ustr-selinuxpartir do AUR, porque ustr usa inlineonde é agora necessário usar static inline. Ok, até agora tudo bem. Infelizmente, o processo de compilação é realmente grosseiro, mas consegui compilar e instalar o suficiente com o seguinte:

git clone https://android.googlesource.com/platform/external/selinux \
    android/external/selinux
export ANDROID_BUILD_TOP=$PWD/android
DESTDIR=$HOME/android_selinux
export LD_LIBRARY_PATH="$DESTDIR/lib:$DESTDIR/usr/lib"
cd android/external/selinux
sed -ie '/^LDLIBS.*(LIBDIR)/s/$/ ..\/lex.yy.o/' checkpolicy/test/Makefile
make install DESTDIR="$DESTDIR" \
     PREFIX='$(DESTDIR)/usr' \
     CFLAGS='-I$(PREFIX)/include' \
     -j20 -k
cp checkpolicy/test/dispol "$DESTDIR/usr/sbin/sedispol"
cp checkpolicy/test/dismod "$DESTDIR/usr/sbin/sedismod"

Neste ponto, sedispolfunciona uma política SElinux comum (como uma versão 29 policy.29do fedora), mas ainda não me mostra o que está acontecendo com o android:

$ ~/android_selinux/usr/sbin/sedispol sepolicy 
Reading policy...
libsepol.avtab_read_item: more than one specifier
libsepol.avtab_read: failed on entry 457 of 5582
/home/user/android_selinux/usr/sbin/dispol:  error(s) encountered while parsing configuration
$ 

Eu também tentei compilar as setools3ferramentas de baunilha nas bibliotecas do Android. Novamente, não é tão fácil, mas trabalhei com:

DESTDIR=$HOME/android_selinux
export LD_LIBRARY_PATH="$DESTDIR/lib:$DESTDIR/usr/lib"
git clone https://github.com/TresysTechnology/setools3.git
cd setools3
./configure --prefix=$DESTDIR/usr --with-sepol-devel=$DESTDIR/usr CPPFLAGS="-I$DESTDIR/usr/include -L$DESTDIR/usr/lib"
make -k -j20

Isso não cria totalmente, mas cria o suficiente da árvore de origem que eu posso executar secmds/sesearch. Esse tipo de funciona em um policy.29arquivo de baunilha (eu posso pesquisar -Ae -T, mas--all me fornece operation not supported). No entanto, ele falha completamente com um erro semelhante ao tentar examinar um arquivo da versão 30 do Android:

$ ./secmds/sesearch -A sepolicy 
ERROR: more than one specifier
ERROR: failed on entry 457 of 5582
ERROR: Unable to open policy sepolicy.
ERROR: Success
$ 

Neste ponto, minha mente está meio desconcertada, pois é difícil construir as ferramentas em torno de algo tão crítico quanto a política de segurança do sistema. Certamente eu devo estar fazendo algo errado. Alguém realmente conseguiu examinar uma política de segurança do Android sem depender de bibliotecas compartilhadas binárias distribuídas externamente?

Devo acrescentar que também tentei as técnicas sugeridas para reconstruir todas as ferramentas pré-construídas ( ndk/build/tools/download-toolchain-sources.she ndk/build/tools/rebuild-all-prebuilt.sh). No entanto, o download-toolchain-sources.shscript está quebrado no momento. Ele tenta verificar os diretórios da versão antiga que não estão mais nos repositórios e, de qualquer forma, não parece baixar nenhuma ferramenta relacionada ao selinux, apesar do fato de que prebuilts/pythoncontém o código relacionado ao selinux. Mais uma vez, estou chocado com a importância desses sistemas de construção e acho que deve haver uma maneira mais fácil. A pergunta: como posso obter ferramentas que permitam verificar minha política de selinux do Android?

Respostas:


8

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.imgarquivos. Em outras palavras, o CyanogenMod fornece uma ferramenta que permite acessar o sepolicyarquivo 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-geteste post para manter o menor denominador comum e manter todos felizes, você pode preferir usá-aptitudelo, 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, oaptitudecomando 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_TOParmazena sua localização de origem (o diretório em que você emitiu o repo synccomando). 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 restorecondo Makefile não consegue localizar algumas bibliotecas. Você precisa editar este Makefile para usar caminhos gerados dinamicamente por pkg-configvez 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=-fPICconfiguraçã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 *.oarquivos 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 sesearchexecutá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 libsepolversoin 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-declsdos 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 *.harquivo não ser encontrado:

  1. 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 *.harquivos não serem encontrados, e sim, você deve aplicar essa mesma abordagem cíclica de "experimentar e ver".

  2. 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 makepor exemplo); caso contrário, poderá ser necessário modificar o próprio Makefile (o pkg-configcomando pode ser de uma ajuda preciosa para gerar automaticamente parâmetros de construção ausentes) .

  3. Procure no sistema de embalagem:

    apt-cache search filename-dev
    

    Onde filename-devrepresenta o nome do arquivo ausente em minúsculas com a .hextensão substituída pelo -devsufixo (por exemplo, se Python.hnão for encontrado, procure python-dev). Alguns ajustes no nome exato podem ser necessários para encontrar o pacote certo.

  4. Se você permanecer parado e mesmo uma pesquisa rápida na Internet não fornecer uma resposta clara, apt-fileserá o seu melhor amigo. apt-filenã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-filepermite procurar pacotes (mesmo os desinstalados) que fornecem um arquivo específico. Para evitar muito resultado, recomendo associá-lo grepcomo abaixo:

    apt-file search filename.h | grep -w filename.h
    

    Se houver um pacote no repositório do Ubuntu fornecendo esse arquivo, você apt-filepoderá encontrá-lo.

    Depois de encontrar o pacote certo, instale-o usando apt-get install packagenameonde packagenameestá 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 sepolicyarquivo 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 sepolicyarquivo.

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 sepolicyarquivo a partir das regras da sua árvore de origem (procure .tearquivos para encontrá-los:, find $ANDROID_BUILD_TOP -name \*.teeles estão espalhados em vários diretórios).
  • Modifique o sepolicyarquivo 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 sepolicyarquivo 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 sepolicyregras segue outra rota: modificando diretamente o sepolicyarquivo 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 sepolicyarquivo.

Uma verificação rápida usando sesearchmostra 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 sesearche sepolicy-injectparâmetros):

sepolicy-inject -s kernel -t media_rw_data_file -c file -p read -P ./sepolicy

Agora podemos retornar nosso sesearchcomando:

$ 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.imgarquivo do dispositivo e atualizá-lo novamente. Verificar a hora da última modificação do /sepolicyarquivo é uma maneira fácil de garantir que seu dispositivo esteja executando o sepolicyarquivo 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 .


1
apenas uma nota - nunca faça "repo sync" a menos que você tenha bastante café para beber;) Use "repo sync -q -f --force-sync -c" em vez disso - você economizará muito tempo e espaço no disco rígido . -q está quieto, -f e --force-sync ajudaria você a prosseguir em caso de erros temporários na rede, -c buscaria apenas a ramificação atual. PS: Eu também uso sinalizadores "-d --prune" durante o desenvolvimento, quando preciso apagar totalmente as alterações locais e mudar para a versão do manifesto.
precisa

@Oleksandr: Obrigado pela sua informação, é útil saber. Eu testei com a -cbandeira, mas não notei nenhuma grande diferença: ainda há muitos dados para o computador baixar (25 GB), ainda há muita cafeína para eu beber;). Eu sou um pouco cauteloso com a -fbandeira, pois, pelo meu entendimento, isso forçará repoa ignorar quando falhar ao baixar parte do código-fonte e ainda considerar o resultado final como um sucesso. Prefiro reservar o estado "sucesso" a uma busca completa e evitar me encontrar em uma situação desconhecida em que os arquivos podem estar ausentes aleatoriamente.
WhiteWinterWolf

2

Você deve primeiro criar uma versão mais antiga do libsepol a partir do código AOSP (como o que corresponde à versão 6.0) e, em seguida, vincular sepolicy-inject, dispol, etc. Esta receita funcionou para mim no debian jessie:

cd /to/the/aosp/dir 
[repo init, etc]
repo sync external/selinux
cd external/selinux
git checkout android-6.0.0_r1^
cd libsepol
make
libsepol=`pwd`
cd /to/the/selinux-inject-source-dir
make LIBDIR=$libsepol

diferente do sepolicy-injetar vinculado ao libsepol do sistema, este funciona bem com o / sepolicy da imagem 6.0 incluída no android sdk:

$ sepolicy-inject -Z shell -P /tmp/sepolicy -o /tmp/sepolicy 
libsepol.policydb_read: policydb version 30 does not match my version range 15-29
error(s) encountered while parsing configuration
Could not load policy
$ ./sepolicy-inject -Z shell -P /tmp/sepolicy -o /tmp/sepolicy 
libsepol.policydb_index_others: security:  1 users, 2 roles, 525 types, 0 bools
libsepol.policydb_index_others: security: 1 sens, 1024 cats
libsepol.policydb_index_others: security:  87 classes, 4767 rules, 0 cond rules

Para as ferramentas incluídas na distribuição selinux, o truque é construí-las com o mesmo DESTDIR:

cd libsepol
make DESTDIR=/some/dir install
cd ../checkpolicy
make DESTDIR=/some/dir
# here you have a working 'dispol' in the 'test' subdir

Obrigado. Isso me deu uma versão do sedispol que parece funcionar, mas ainda não consigo compilar a pesquisa. A pesquisa morre procurando pelo arquivo de inclusão <apol/policy.h>(de outro policy.harquivo). Você sabe qual módulo contém apol?
user3188445

@ user3188445: O arquivo apol/policy.hé fornecido pelo pacote libapol-dev(pelo menos é este nos sistemas Ubuntu). Consulte a minha resposta para obter informações mais detalhadas.
precisa saber é o seguinte

1

Para as pessoas que enfrentam o problema com:

policydb version 30 does not match my version range 15-29

enquanto trabalhava com código AOSP.

Supondo que o seu código AOSP tenha check-out em ~ / android / source dir:

cd ~/android/source
source build/envsetup.sh
export ANDROID_BUILD_TOP=$(pwd)

E agora você está livre para usar o utilitário audit2allow incluído :

./external/selinux/prebuilts/bin/audit2allow

PS Além disso, gostaria de abordar o comentário Examine a política selinux do Android (v30)

Sesearch morre procurando o arquivo de inclusão (de outro arquivo policy.h). Você sabe qual módulo contém apol?

Criar o kit de ferramentas do selinux a partir de fontes https://github.com/SELinuxProject/selinux não é muito trivial (a menos que você esteja usando o Fedora). No Ubuntu, você precisa instalar (supondo que você já tenha instalado ferramentas básicas de desenvolvimento, como bison e compilador C) libglib2.0-dev, libcap-ng-dev, xmlto, libsemanage1-dev, libustr-dev, libaudit-dev, libsepol1 -dev

Mas no final ainda não consegui compilá-lo por causa de https://bugs.launchpad.net/ubuntu/+source/glib2.0/+bug/793155 e não tenho idéia de como resolvê-lo


1
Eu também encontrei esse glibconfig.herro que você está vinculando no final de sua postagem. Ele foi criado pelo restorecondMakefile porque os caminhos incorretos foram codificados nele. Você precisa modificá-lo para permitir que ele resolva dinamicamente os caminhos usando pkg-config. Veja minha resposta para mais detalhes.
precisa saber é o seguinte


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.