まず、「これは驚くほど難しいことだ」という声明に完全に同意することを認めなければなりません。Googleは主に消費者の観点からAndroidを設計しましたが、パワーユーザー向けではありません。その結果、最新のFacebookアプリを使用したり、Candy Crushで遊んだりする以外のことをしたいとすぐに、開発者のような知識を変更する必要があった2000年初頭のLinuxの領域にすぐに戻ることになります。単純な設定であるべきもの。Androidシステムが成熟するにつれて状況は急速に変化すると信じていますが、今のところは、私たちが持っているものに関係しています...
あなたが言ったように、独自のSELinuxツールセットをコンパイルする必要がある理由は2つあります。
- システムが提供するツールセットは、通常、背後のバージョンです。AndroidのSELinuxはポリシーDBバージョン30に依存していますが、現在のLinuxボックスは通常29までのバージョンのみを処理します。
- たとえ最新であっても、実際にはアップストリームコードからSELinuxを構築することは(少なくともアップストリームの推奨事項に従って、少なくともFedoraマシン上で)事実上、システムがポリシーDBバージョン30を処理できるようになりますが、AndroidのSELinuxはAndroidのSELinuxを処理しようとすると、構文と解析エラーが原因で失敗するため、大幅に変更されています(Googleのドキュメントではいくつかの変更が強調されています)。
したがって、AndroidのSELinux分析の探求を続けるには、できるだけきれいな方法で手を汚さなければなりません。
- まず、健全な環境をセットアップし、
- これが完了したら、AndroidのSELinuxライブラリと最初のツールをコンパイルします。
- それらの上に、SELinuxツールを構築し、
- 最後に、いくつかの補助ユーティリティを追加します。
適切な環境をセットアップする
環境プロパティ
最も確実に推奨される、おそらくおそらく確実に機能する方法は、Androidの作業に環境を割り当てることです。
仮想マシンは完全に問題ありません(最良のオプションではない場合)。USBを介して電話をゲストシステムに接続する必要があるため、VMwareを使用することをお勧めします。無料の代替Qemuは、そのようなタスクをうまく処理できないようです。私は他の仮想化ソフトウェアを試しませんでした。
64ビットシステムである必要があります。そうしないと、整数のサイズが間違っているため、コードが単純にコンパイルされません。
Ubuntuシステムを使用することを強くお勧めします。おそらく必須です。XFCEのより軽いデスクトップ環境を好む場合は、代わりにXubuntuを自由に使用してください。これにより、システムのコアと利用可能なパッケージは変更されず、Android関連の作業に影響はありません(この手順でUbuntuについて述べたことはXubuntuにも適用されます)。AndroidのSELinuxソースツリーには、代わりにFedoraの使用を推奨するReadMeファイルがあります。これらのファイルはアップストリームNSAのSELinuxプロジェクトから継承され、そのコンテンツは必ずしもGoogleのAndroidと一致しません。
使用するUnbuntuの正確なバージョンは、ビルドするAndroidのバージョンによって異なります。Android 6.0の場合、Ubuntu 14.04(Trusty)が推奨されます。詳細については、Googleの要件ページをご覧ください。
十分なディスク容量が必要になります(SELinux関連の調査のみを計画する場合は少なくとも50GB、Androidの完全なビルドを計画する場合は少なくとも100GB)。CPUとメモリの関連性は低く、フルビルドの時間にのみ影響し、SELinux関連のタスクには実際の影響はありません。
Ubuntuを使用すると、主に2つの利点があります。
推奨されるシステムを使用することにより、よく知られ、十分にテストされた環境で作業しています。システムライブラリ、ツール、およびパッケージは、プロジェクトで期待されるバージョンと場所にあります。
より具体的には、現在のケースでは、Ubuntu自体はSELinuxの代替であるAppArmorに依存しており、SELinuxは使用していません。幸いなことに、システムの信頼性を変更するリスクを冒すことなく、AndroidのSELinuxツールとバイナリをシステム全体にインストールできます。
環境のインストール手順
Ubuntuを本格的なライブDVDから開始する従来の方法でインストールできますが、より高速な代替手段は、ネットブートインストール(テキストモードインストール)を使用し、最後に好みのデスクトップ環境を選択することです。そうすることで、古いパッケージを最初にインストールする代わりに、最新のパッケージバージョンを直接インストールし、最初の起動時に389の保留中の更新を適用するよう求めることで、初期更新時間を節約できます。
Ubuntu / Xubuntu 14.04のISO(同じISO)ネットブートインストーラーは、こちらから入手できます。
VMwareの面倒な「簡単インストール」機能をスキップするには、「後でオペレーティングシステムをインストールします」オプションを選択して開始するのが良い習慣です。
選択してくださいLinuxの場合、Ubuntuの64ビットゲストOSとして。
VMには次のリソースが必要です。
- 必須:ディスク容量は最低でも 40GB である必要があります(デフォルトの20GB では十分ではありません。ソースコードだけではそれ以上の容量が必要です)。フルビルドには最低100 GBのディスクが必要です。これは通常私が取る値です。この設定は単なる最大制限であることを忘れないでください。VMが使用する実際のサイズは、ゲストの要求に応じて動的に増加します。
- 条件的:RAMを1024から少なくとも2048以上に増やします(ホストの容量に応じて、4096を使用します)。
- 条件的:プロセッサコアの数を1から2以上に増やします(ホストの容量に応じて、3を使用します)。
- CD-RomはインストールISOファイルを指している必要があります。
- USBをデフォルトの1.1から2.0に切り替えると、デバイスを接続したときに前者が警告を出す場合があります。使用状況に応じて、「新しいUSBデバイスを自動的に接続する」および「Bluetoothデバイスを仮想マシンと共有する」のチェックを安全に解除することもできます。
- 環境によっては、ディスプレイ設定を微調整する必要があります(3Dを無効にし、画面サイズを強制します)。
注意:
- ネットブートインストールを選択した場合、ソフトウェア選択画面に到達するときにデスクトップ環境(UbuntuデスクトップまたはXubuntuデスクトップ)を選択することを忘れないでください。そうしないと、最小限のテキストのみの環境になってしまいます。
- 最初の起動時に、最新リリースへのアップグレードを拒否します。ここでのポイントは、14.04にとどまることです!
最初の起動時に、最初に行うことの1つは、Linuxゲストツールのインストールです。
sudo apt-get install open-vm-tools
このパケットは起動時トリガーを置くため、ゲストの再起動後にのみインストールが完了します。
Androidソースコードを取得する
同様ですが、手順の詳細は選択したROMによって異なります。
- CyanogenModの場合は、デバイスを検索し(最初にベンダーを選択)、[ CyanogenModの構築方法 ] リンクをクリックして、デバイスに適合した指示を取得します。
- AOSPの場合は、ここから始まる手順に従ってください。
CyanogeModがソースツリーにboot.img
ファイルを展開できるツールをバンドルしていることは注目に値します。別の言い方をすれば、CyanogenModはsepolicy
、デバイスとROMアーカイブに保存されているファイルにアクセスできるツールを提供します。GoogleのAOSPはそのようなツールを提供していないため、CyanogenModのソースツリーを使用する他の命令がない場合は最も便利な選択肢になる可能性があります。
ここでは、CyanogenMod 13.0(Android 6.0)の手順に従っています。使用されるコマンドの説明は、上記のリンク先のページで入手できます。それらをお読みください、以下のタイプスクリプトは参照目的でのみ提供されています。
ヒント:私apt-get
はこの投稿で最も一般的な分母に固執してすべての人を幸せにするために使用aptitude
していますが、より良い方法で依存関係を処理するため、代わりに使用することをお勧めします(いくつかの依存関係のインストールを必要とするパッケージを削除するとき) 、これらの依存関係も削除され、システムがよりきれいになります)。私の知る限り、aptitude
コマンドはUbuntuにインストールする必要がありますが、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
これで、クリーンでほぼ完全なソースツリーができました。プロプライエタリのブロブはありませんが、SELinux関連のタスクには必要ありません。
ヒント:ソースの取得は退屈なプロセスです。今すぐVMのスナップショットまたはバックアップを行う価値があります。
AndroidのSELinuxツールセットとライブラリをコンパイルしてインストールする
今、旅行の面白い部分が始まります;)!
これまで、手順は非常に簡単でした。目標は、主に私と同じ環境を確保することでした。そうした場合、続編も単純なままにする必要があります。
内部では、Googleはバージョン間でAndroidのソースコードに深い変更を適用することをheしません。そのため、正確なコンパイル手順はバージョンに依存します(たとえば、AOSPマスターはsepolicy/
ディレクトリが移動されることを示します)。
まず、AndroidのSElinuxライブラリとツールセットをコンパイルしてインストールする正確な手順を共有しますが、時間の経過とともにこの投稿の関連性を維持するために、ほとんどのコンパイルの問題を解決するために従うべき一般的なアプローチに関するメモを追加します。
段階的な手順
AndroidのSELinuxライブラリは、上位層ソフトウェアがAndroid固有のSELinuxポリシーファイルを処理できるようにする抽象化層を提供します。したがって、最初にそれらをコンパイルしてインストールする必要があります(それ自体、ここで問題が発生した場合、実際にコアを表します)。
その後、SELinuxツールをビルドしてインストールできます。後でわかるように、幸いなことにこれらはAndroid固有である必要はなく、SELinuxライブラリのバージョンと一致する必要があるだけです。
この手順は、CyanogenModとAOSPソースコードツリーの両方を使用してテストされています。
Android SELinuxライブラリと最初のツールをコンパイルしてインストールする
最初のインストールの依存関係:
sudo apt-get install libapol-dev libaudit-dev libdbus-glib-1-dev libgtk2.0-dev \
libustr-dev python-dev python-networkx swig xmlto
この投稿では、変数$ANDROID_BUILD_TOP
はソースの場所(repo sync
コマンドを発行したディレクトリ)を保存します。自由に名前を変更してください。
ANDROID_BUILD_TOP=~/android/system
cd $ANDROID_BUILD_TOP
source ./build/envsetup.sh
デフォルトでは、restorecond
Makefileが一部のライブラリを見つけることができないため、ポリシーコアutilsのコンパイルは失敗します。pkg-config
ハードコードされたパスの代わりに動的に生成されたパスを使用するには、このMakefileを編集する必要があります(バッククォートを一重引用符と混同しないでください!):
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
テキストエディターでMakefileを開いて、変更が正しく考慮されていることを確認してください。
そして、コンパイルしてインストールします:
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/
重要:EMFLAGS=-fPIC
ビルド時に環境変数の設定をお見逃しなくlibselinux
。エラーはまだ生成されませんが、次のステップではSEToolsをビルドできません。あなたがそれを見逃したか、何か他の間違ったことをした場合には、単に発行してmake clean
、コンパイルを再開してください。
SELinuxツールをコンパイルしてインストールする
SELinuxツールは、以下を含むビルド済みの形式で提供されます。
$ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/
ディレクトリ内のPythonスクリプト(およびそのシェルスクリプトラッパー)
- 以下のPythonパッケージ(
*.o
コンパイル済みファイルを含む)$ANDROID_BUILD_TOP/prebuilts/python/linux-x86/2.7.5/lib/python2.7/site-packages/
。
これらのツールのソースコードは以下$ANDROID_BUILD_TOP/external
で入手できると予想していましたが、入手できませんでした。実際、使用したSEToolsの正確なバージョンをGoogleが共有する場所は見つかりませんでした(FYI GPLはコードが変更された場合にのみコードを共有することを義務付けています)。 。
ツール自体はPythonスクリプトであり、これはSETools 4からの新しい進化です(SETools 3では、コマンドsesearch
はCでコーディングされたバイナリ実行可能ファイルでした)。ただし、ツール自体にはまだバージョン3.3.8が表示されます。
$ $ANDROID_BUILD_TOP/external/selinux/prebuilts/bin/sesearch --version
3.3.8
したがって、GoogleはSETools 4から初期開発スナップショットを取得したと推測します。4.0.0beta SEToolsはlibsepol
versoin 2.4に依存し、4.0.0リリースでは、 Android 6.0にバンドルされているSELinux(これをコンパイルしようとすると、失敗するだけです)。
そのため、最も賢明な選択はSETools 4.0.0 Betaに合うようです。
追加の依存関係をインストールします。
sudo apt-get install python-setuptools
ソースコードをダウンロードして抽出します。
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/
起因するバグのFlex 2.5に影響を与える、我々は削除する必要がある-Wredundant-decls
コンパイラのフラグから:
sed -i '/-Wredundant-decls/d' ./setup.py
最後にコンパイルしてインストールします:
python ./setup.py build
sudo python ./setup.py install
一般的な手順(または「スタックを解除する方法」)
上記の手順があなたのケースでうまくいかなかった場合、ここに進行を試みる方法のより高いレベルのビューがあります。
悲しいことに魔法はありません(そしてヘルパー:()もありません:このコードをコンパイルする唯一の方法は、古典的で恐ろしい周期的な "試してみる"アプローチです。
最初にコンパイルしてみてください。*.h
ファイルが見つからないために失敗する可能性が高くなります。
Androidのexternal/
ディレクトリで検索:
find $ANDROID_BUILD_TOP/external -name filename.h
要求されたファイルが見つかった場合、これは、対応するライブラリまたはツールの特定のバージョンがAndroidソースコード内にバンドルされていることを意味します。したがって、Ubuntuのパッケージシステムからインストールするのではなく、Androidソースコードにバンドルされているバージョンをコンパイルしてインストールする必要があります。
これは、フォーラムで見られる一般的なアドバイスに反することに注意してください:「このライブラリが見つからないため、コンパイルは失敗しますか?このパッケージをインストールすれば問題ありません!」、これを行うことにより、おそらく最悪の問題に陥ります:特定のバージョンがバンドルされている場合、それはおそらく特定のバージョンが必要なためです(互換性の問題またはこのバージョンにはGoogleからの特定の変更が含まれているため)。
ところで、あなたが疑問に思っているなら:もちろん、このライブラリまたはツールには依存関係があり、いくつかの*.h
ファイルが見つからないためにエラーが発生する可能性があります。
システム全体を検索:
find / -name filename.h 2>/dev/null
システムの一部の標準共有ライブラリの場所にファイルがすでに存在しないことがわかった場合、これはおそらくこの依存関係が環境ですでに満たされていることを意味しますが、エラーを発生させたMakefileはそれを見つけるにはあまりにも愚かです。
このMakefileを手動で直接呼び出す場合、これを修正する環境変数を設定できるLIBDIR=/usr/lib make
場合があります(たとえば)、そうでない場合は、Makefile自体を変更する必要がある場合があります(pkg-config
コマンドは、欠落しているビルドパラメーターを自動的に生成するために役立つ場合があります) 。
パッケージングシステムで検索します。
apt-cache search filename-dev
where filename-dev
は、不足しているファイルの名前を小文字で表し、.h
拡張子を-dev
サフィックスに置き換えます(たとえば、Python.h
見つからない場合はを検索しますpython-dev
)。適切なパッケージを見つけるには、正確な名前を微調整する必要がある場合があります。
行き詰まっていて、インターネットでのクイック検索でも明確な答えが得られなかった場合は、apt-file
親友になります。apt-file
デフォルトではインストールされません。インストールしてデータベースを生成する必要があります。
sudo apt-get apt-file
sudo apt-file update
apt-file
特定のファイルを提供するパッケージ(アンインストールされたものも含む)を検索できます。結果が多すぎるのを避けるためにgrep
、以下のように関連付けることをお勧めします。
apt-file search filename.h | grep -w filename.h
このファイルを提供するUbuntuのリポジトリにパッケージがある場合、それapt-file
を見つけることができるはずです。
適切なパッケージが見つかったら、パッケージ名のapt-get install packagename
場所を使用してインストールしpackagename
ます。
ヒント:システムに何かをねじ込んだ場合、パッケージを再インストールするコマンドは次のとおりapt-get reinstall pkg_name
です。依存関係が壊れているために古典的な削除とインストールができない場合でも動作します(システムのライブラリの場合が最も多いです)。
補助ツール
このステップで、コンパイルされた形式とソース形式の両方でAndroidのSELinuxルールを調査できるクリーンな環境ができました。
ただし、ほとんどの場合、調査の最後に何らかのアクションを実行する必要があります。現在の形状では、ご使用の環境では、デバイスのsepolicy
ファイルを変更できません。実際、このファイルは簡単に置き換えることはできません。これはデバイスのルートディレクトリの一部であり、ルートディレクトリの内容は、起動時にRAMディスクファイルから抽出され、デバイスのブートイメージに格納されます。
したがって、環境が完成する前にまだ2つのことを見逃しています。
- デバイスのブートイメージにアクセスして変更する方法、
sepolicy
ファイルを変更する方法。
幸いなことに、これらはこの投稿の最後の2つのセクションの主題です。:)
デバイスのブートイメージを取得して更新する
デバイスのブートイメージを取得および更新するツールは、SELinuxルールの改ざん以外にも、さまざまな用途に使用できます。したがって、私は専用の回答を作成しました。それを参照してください。
デバイスのSELinuxルールを変更する
ここには主に2つの可能性があります。
sepolicy
ソースツリーのルールから新しいファイルを.te
作成します(ファイルを検索してそれらを見つけます:find $ANDROID_BUILD_TOP -name \*.te
、それらはいくつかのディレクトリに分散されています)。
sepolicy
デバイスが現在使用しているファイルを変更します。
ルールをゼロから構築する必要がある場合を除き、これは開発関連のタスクであるため、ここでは範囲外ですが、2番目の選択肢は、唯一の変更があなたの明示的に作られた。
sepolicy
ファイルを再コンパイル可能な形式に逆コンパイルし、その間のルールを自由に編集できるツールを作成するプロジェクトがありました。しかし、このプロジェクトは概念実証状態で放棄されました。このブログ投稿の最後にすべての情報があります。記事の残りの部分には、他の人が引き継ぐのに十分な詳細が含まれています。
現在推奨されているsepolicy
ルールを変更する方法は、別のルートをsepolicy
使用します。バイナリファイルを直接変更することです。sepolicy-injectツールはそれを可能にし、積極的に維持されます。
完全を期すために、このツールのフォークが存在することに注意してください。それはいくつかの機能を追加します、それらのいくつかは元の作者のto-doリストにあります(ルールを削除する可能性など)、彼らが貢献する代わりにフォークすることを選んだ理由を聞かないでください...
コンパイルしてインストールするにはsepolicy-inject
、次の手順を実行します。
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/
ユースケースの例
たとえば、次のエラーメッセージに一致する自動化を追加するとします。
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
デバイスのブートイメージを取得し、それを解凍してsepolicy
ファイルにアクセスする必要があります。
を使用しsesearch
て簡単に確認すると、実際には許可ルールはありません(まだ!):
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
$
コマンドには出力がありません。
次に、以下のコマンドを使用して必要なルールを追加します(パラメーターsesearch
とsepolicy-inject
パラメーターの類似性に注意してください):
sepolicy-inject -s kernel -t media_rw_data_file -c file -p read -P ./sepolicy
これで、sesearch
コマンドをコールバックできます。
$ sesearch -A -s kernel -t media_rw_data_file -c file -p read ./sepolicy
allow kernel media_rw_data_file:file read;
$
sesearch
出力は、ポリシーが正しく更新されたことを示しています。
これで、デバイスのboot.img
ファイルを再パックして、デバイスにフラッシュバックできます。/sepolicy
ファイルの最終変更時間を確認することは、デバイスが新しく更新されたsepolicy
ファイルを実行していることを確認する簡単な方法です。
結論
これで、AndroidデバイスのSELinuxポリシーを自由に検査および変更できる完全な環境ができました。楽しい!:)
サイドノートとして、デバイスから直接 SELinuxポリシーを分析および変更できるツールもあります。