Advertisement

AndroidとSELinux

Apr. 25, 2015
Advertisement

More Related Content

Slideshows for you(20)

Advertisement

Recently uploaded(20)

Advertisement

AndroidとSELinux

  1. Android と SELinux @androidsola
  2. 自己紹介 • twitter @androidsola • blog http://blog.sola-dolphin-1.net/ • AndroidベースのカスタムROM(JCROM)を開発して ます https://sites.google.com/site/jcromproject/ ※サーバ移行中なので一部リンク切れてます SELinuxにはJCROMの開発で遭遇。
  3. 本日の内容 • SELinuxとは • Platform開発者がやること • 開発で遭遇したこと
  4. SELinuxとは
  5. SELinuxとは • Linuxインストール時や直後によく無効化されるやつ
  6. SELinuxとは(Wikipediaより) • SELinux(Security-Enhanced Linux : エスイーリナッ クス)は、アメリカ国家安全保障局がGPL下で提供し ているLinuxのカーネルに強制アクセス制御(MAC)機 能を付加するモジュールの名称。名前から勘違いされ ることが多いが Linuxディストリビューションの一つ ではない。
  7. SELinuxとは • SELinuxの効果 • SELinuxの特徴
  8. SELinuxの効果
  9. SELinuxを使用しない場合 Process A Linux Kernel File A File B File C -rw-r--r–- hoge hoge (省略)File A -rw-r---–- hoge hoge (省略)File B -rw------– hoge hoge (省略)File C sola solaは管理者権限を持たない一般ユーザ hogeのグループには属していない solaがProcess Aを実行してFile A, File B, File Cにアクセス(read)する例。
  10. SELinuxを使用しない場合 Process A Linux Kernel File A File B File C -rw-r--r–- hoge hoge (省略)File A -rw-r---–- hoge hoge (省略)File B -rw------– hoge hoge (省略)File C sola solaは管理者権限を持たない一般ユーザ hogeのグループには属していない 乗っ取られてProcess Aがroot権限を持ってしまった時は、 File A, File B, File C全てにアクセスされる。 乗っ取り
  11. SELinuxを使用した場合 Process A Linux Kernel File A File B File C -rw-r--r–- hoge hoge (省略)File A -rw-r---–- hoge hoge (省略)File B -rw------– hoge hoge (省略)File C sola solaは管理者権限を持たない一般ユーザ hogeのグループには属していない SELinuxを使用するとパーミッションによるアクセス制御の他に、 セキュリティポリシーによる制御が行われる。 SELinux Security policy File B, File Cはrootで あってもアクセス出来な いようにSecurity policy を定義する
  12. SELinuxを使用した場合 Process A Linux Kernel File A File B File C -rw-r--r–- hoge hoge (省略)File A -rw-r---–- hoge hoge (省略)File B -rw------– hoge hoge (省略)File C sola solaは管理者権限を持たない一般ユーザ hogeのグループには属していない 乗っ取られてProcess Aがroot権限を持ってしまっても Security policyの定義に従うので、File BやFile Cを守れる。 SELinux Security policy File B, File Cはrootで あってもアクセス出来な いようにSecurity policy を定義する 乗っ取り
  13. SELinuxの特徴
  14. SELinuxの特徴 • TE(Type Enforcement) • ドメイン遷移(Domain transition) • RBAC(Role Base Access Control)
  15. TE(Type Enforcement) • プロセスがアクセスできるリソースを制限するための 仕組み。 • プロセスには「ドメイン」、リソースには「タイプ」 といったラベルをそれぞれ付与する。 • 「ドメイン」が「タイプ」に対して、どのような操作 を実行できるのかを設定する。 • 設定する操作は「アクセスベクタ」と呼ぶ。
  16. TE(Type Enforcement) TE の記述例 allow ドメインA タイプA アクセスベクタA; allow ドメインA タイプB アクセスベクタB; ドメインA がタイプA を read することを許可 ドメインA がタイプB を write することを許可 ドメインA (プロセス) タイプA (リソース) タイプB (リソース) アクセスベクタA(例:read) アクセスベクタB(例:write) • 簡単に表現すると、プロセスがファイル等のリソース に対して出来る事を定義するもの
  17. ドメイン遷移 • 遷移元ドメイン(親プロセス)から遷移先ドメイン (子プロセス)に遷移する時、異なるドメインを割り 当てる仕組み。 • 親から子へは権限を引き継ぐのが通常だが、このドメ イン遷移の仕組みより、異なる権限を与える事が出来 る。
  18. RBAC(Role Base Access Control) • RBAC は「ロール」と呼ばれるいくつかのドメインを 束ねたものを設定し、それをユーザに付与する仕組み。 • ユーザは付与されたロール内のドメインの権限でのみ ファイルにアクセス可能。この機能により各ユーザ毎 に細かく権限を付与、制限することが可能。
  19. Platform開発者がやること
  20. Platform開発者がやること • Linux Kernelの確認 • Filesystemの確認 • Security Policyの作成
  21. Linux Kernelの確認 • Linux KernelでSELinuxの機能を有効にする kernel configでCONFIG_SECURITY_SELINUXをyにする。 Linux Kernelに入っている機能なので、kernel config で有効にするだけで使用することが出来る。 BSPとして提供された環境では最初は有効になってな いこともあるので、確認する。
  22. Filesystemの確認 • SELinuxを使用するには拡張ファイル属性(xattr)が 必要。 ext4の場合、kernel configでCONFIG_EXT4_FS_XATTR とCONFIG_EXT4_FS_SECURITYをyにする。 SELinuxを使用しない場合は不要なので無効になってい ることがある。SELinuxを使う場合は確認する。 • 商用のFilesystemを使用する場合、拡張ファイル属性 (xattr)が実装されてるか確認すること。
  23. Security Policyの作成 • AOSP(Android Open Source Project)に無いものを 自分で作成する ターゲット毎に異なるデバイス(/dev/***など) 独自の機能(アプリやサービス) • AOSPにあるSecurity Policyは(基本的に)変更しない 自分のデバイスツリー配下に追加する (Nexus5だとdevice/lge/hammerhead配下) vendor配下に置くものはvendor配下に追加する
  24. AOSPのSecurity Policy • AOSPのSecurity Policyはexternal/sepolicyにある https://android.googlesource.com/platform/external /sepolicy/
  25. AOSPのSecurity Policy
  26. Security Policyの多くはTE
  27. TEの読み方(初級編) • タイプの設定 • TEの記述 • ドメイン遷移の記述 • 便利なマクロ
  28. bootanimationのSecurity Policy bootanim.te type bootanim, domain; type bootanim_exec, exec_type, file_type; init_daemon_domain(bootanim) binder_use(bootanim) binder_call(bootanim, surfaceflinger) allow bootanim gpu_device:chr_file rw_file_perms; allow bootanim oemfs:dir search; allow bootanim oemfs:file r_file_perms; allow bootanim audio_device:dir r_dir_perms; allow bootanim audio_device:chr_file rw_file_perms;
  29. タイプの設定 bootanim.te type bootanim, domain; type bootanim_exec, exec_type, file_type; init_daemon_domain(bootanim) binder_use(bootanim) binder_call(bootanim, surfaceflinger) allow bootanim gpu_device:chr_file rw_file_perms; allow bootanim oemfs:dir search; allow bootanim oemfs:file r_file_perms; allow bootanim audio_device:dir r_dir_perms; allow bootanim audio_device:chr_file rw_file_perms;
  30. タイプの設定 書き方 type ラベル, タイプ... 例1 type bootanim, domain; bootanimというドメイン名の定義(bootanimationのこと) 例2 type bootanim_exec, exec_type, file_type; bootanim_execは実行可能ファイルであることの定義。 タイプ...には複数記述出来る。 (実行可能ではない)通常のファイルの場合はfile_typeのみにす る。
  31. TEの記述 bootanim.te type bootanim, domain; type bootanim_exec, exec_type, file_type; init_daemon_domain(bootanim) binder_use(bootanim) binder_call(bootanim, surfaceflinger) allow bootanim gpu_device:chr_file rw_file_perms; allow bootanim oemfs:dir search; allow bootanim oemfs:file r_file_perms; allow bootanim audio_device:dir r_dir_perms; allow bootanim audio_device:chr_file rw_file_perms;
  32. TEの記述 書き方 allow ドメイン タイプ:オブジェクトクラス アクセスベクタ; ドメインはプロセス タイプ:オブジェクトクラスはリソース アクセスベクタはプロセスがリソースに対して行える操作 例 allow bootanim gpu_device:chr_file rw_file_perms; bootanimがGPUデバイス(gpu_device:chr_file)に対して読み書 きする(rw_file_perms)のを許可する(allow)ルール。
  33. TEの記述 例 allow bootanim gpu_device:chr_file rw_file_perms; bootanimがGPUデバイス(gpu_device:chr_file)に対して読み書 きする(rw_file_perms)のを許可する(allow)ルール。 gpu_device:chr_file gpu_deviceはfile_contextsというファイルで定義。 AOSPでは/dev/pvrsrvkmというデバイスファイルを指す。 ※ターゲット毎に変更する必要有り。方法は後述。 chr_fileはsecurity_classesというファイルで定義。 chr_fileはキャラクタデバイス用。 ブロックデバイスだとblk_fileとなる。
  34. TEの記述 例 allow bootanim gpu_device:chr_file rw_file_perms; bootanimがGPUデバイス(gpu_device:chr_file)に対して読み書 きする(rw_file_perms)のを許可する(allow)ルール。 捕捉 allowで始まるルールは許可するものを書く。 許可したくないものは何も書かないか、neverallowを使用する。 neverallowを書いてるのにもかかわらずallowを書いていた場合、 コンパイル時にエラーとなる。
  35. 便利?なマクロ type bootanim, domain; type bootanim_exec, exec_type, file_type; init_daemon_domain(bootanim) binder_use(bootanim) binder_call(bootanim, surfaceflinger) allow bootanim gpu_device:chr_file rw_file_perms; allow bootanim oemfs:dir search; allow bootanim oemfs:file r_file_perms; allow bootanim audio_device:dir r_dir_perms; allow bootanim audio_device:chr_file rw_file_perms;
  36. 便利?なマクロ init_daemon_domain(bootanim)はマクロ define(`init_daemon_domain', ` domain_auto_trans(init, $1_exec, $1) tmpfs_domain($1) ') domain_auto_transもマクロ define(`domain_auto_trans', ` domain_trans($1,$2,$3) type_transition $1 $2:process $3; ') domain_transもマクロ(以下省略) これらはte_macrosに定義があります。
  37. ドメイン遷移の記述 書き方 type_transition 遷移元 ラベル 遷移先; 遷移元は遷移元のドメイン ラベルは実行ファイルに設定されたラベル 遷移先は遷移先のドメイン 例 type_transition init bootanim_exec:process bootanim; initからbootanimが起動する。 このルールがあるとbootanimはbootanimドメインで動作する。
  38. 便利なマクロ ここで前に出てきたマクロが便利に感じるかもしれない。 (記述の簡略化と見た目の分かりやすさ) type_transitionを使用する場合 type_transition init bootanim_exec:process bootanim; domain_auto_transを使用する場合 domain_auto_trans(init, bootanim_exec, bootanim) initデーモンであれば更に簡略化 init_daemon_domain(bootanim)
  39. 作成したSecurity Policyの格納 • 全体の設定(ここは変更しない) external/sepolicy • 各ターゲット毎の設定 device/xxx/zzz/sepolicyに置く 置き場は自由に決められる Nexus5の例 device/lge/hammerhead/sepolicy
  40. 作成したSecurity Policyの組込み • Security Policyはビルド時にテキストから専用の形式に 変換される。 • ビルド時に以下4つの変数を参照する。 BOARD_SEPOLICY_DIRS BOARD_SEPOLICY_REPLACE BOARD_SEPOLICY_UNION BOARD_SEPOLICY_IGNORE
  41. BOARD_SEPOLICY_DIRS Security Policyの格納場所を定義する。 次のようにしてターゲット毎の格納場所を定義する。 使用例(Nexus5の場合) BOARD_SEPOLICY_DIRS += ¥ device/lge/hammerhead/sepolicy 場所はBOARD_SEPOLICY_DIRSで自由に決められるが、Nexus5の 例のようにして格納するのが分かりやすくて良いと思います。
  42. BOARD_SEPOLICY_REPLACE Security Policyの置き換えに使用する。 全体の設定を使用せずに、自分で作成したSecurity Policyを使いた い場合は定義する。 使用例 BOARD_SEPOLICY_REPLACE += ¥ app.te ¥ device.te ¥ te_macros
  43. BOARD_SEPOLICY_UNION Security Policyの追加に使用する。 全体の設定に対して、自分で作成したSecurity Policyを追加したい 場合に使用する。 使用例 BOARD_SEPOLICY_UNION += ¥ app.te ¥ device.te ¥ te_macros Nexus5ではこれを使用してSecurity Policyを追加している。使用 するのはほぼこれだと思います。
  44. BOARD_SEPOLICY_IGNORE Security Policyにフィルターをかける。 全体の設定から削除したいSecurity Policyを定義する。 使用例 BOARD_SEPOLICY_IGNORE += ¥ app.te ¥ device.te ¥ te_macros
  45. Nexus5用のSecurity Policy ターゲット用のSecurity Policyの例としてNexus5。 Nexus5用だけでもこれだけあります。
  46. Nexus5用のSecurity Policy bootanimationのTEファイルで出てきたgpu_deviceをNexus5用に 定義するところを確認します。 BOARD_SEPOLICY_DIRS += ¥ device/lge/hammerhead/sepolicy BOARD_SEPOLICY_UNION += ¥ file_contexts file_contextsの内容(GPU deviceのところだけ) # GPU device /dev/kgsl-3d0 u:object_r:gpu_device:s0 /dev/kgsl u:object_r:gpu_device:s0
  47. Security Policyの作成(まとめ) • AOSPで用意されている全体のSecurity Policyは変更し ない • ターゲット毎に必要なSecurity Policyはデバイスツリー (例:device/xxx/zzz/sepolicy)に格納する • Security Policyの記述は単純だが、数が多くて全体の把 握&漏れが無いかの確認が大変。全体を把握できる人 が必要だと思う。
  48. 開発で遭遇したこと
  49. JCROM開発での例 • 遭遇した問題 • 問題への対処
  50. 遭遇した問題 • JCROMは見た目のカスタマイズを出来るようにしてい る。(bootanimationやサウンドも変更出来る) テーマ選択 テーマ反映
  51. 遭遇した問題 • KitKatからLollipopにバージョンアップした時、インス トールしたテーマに含まれるbootanimationが表示さ れなかった。
  52. 問題の原因調査 • 動作を追いかけると、bootanimation.zip(ブートアニ メーションで使用するファイル)にアクセス出来ない というエラーが返ってきている • bootanimation.zipを読み込むためのパーミッションは 問題無いので、何故?となる shell@jcrom:/ # ls -l /data/theme/ drwxrwxr-x system system 2015-04-25 00:00 bootanime shell@jcrom:/ # ls -l /data/theme/bootanime/ -rw-r--r-- system system 1337396 2015-04-25 00:00 bootanimation.zip
  53. 問題の原因調査 • 解析時の基本、ログの調査。 (dmesg、logcatで同じログが出るので、どちらか) <36>[ 0.997773] type=1400 audit(1429875733.980:4): avc: denied { open } for pid=1017 comm="BootAnimation" name="bootanimation.zip" dev="mtdblock1" ino=21154 scontext=u:r:bootanim:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=0 <36>[ 0.997963] type=1400 audit(1429875733.980:5): avc: denied { read } for pid=1017 comm="BootAnimation" name="bootanime" dev="mtdblock1" ino=21155 scontext=u:r:bootanim:s0 tcontext=u:object_r:system_data_file:s0 tclass=dir permissive=0
  54. 問題の原因調査 • ログに出てきている拒否の部分「avc: denied」等を キーワードに検索してみると、SELinuxにたどり着く。
  55. SELinuxが原因かの切り分け • ログからSELinuxが怪しいと分かったので、SELinuxか どうかを切り分ける。 • 切り分けのため、SELinuxを無効にしてみる。
  56. SELinuxを無効にする方法 • コマンドで有効、無効を切り替える • Linux KernelでSELinuxを無効化して、Kernelを差し替 える • Linux Kernelのブートパラメータで有効、無効を指定 する
  57. SELinuxを無効にする方法 • コマンドラインからsetenforceを実行する。 root権限が必要(userビルド環境では不可) 無効化 # setenforce 0 これは厳密には有効のまま。ログにアクセス拒否のログが出るだけ で、実際にはアクセス拒否はしない。 この状態はPermissiveモードと言います。 有効化 # setenforce 1 有効な状態はEnforcingモードと言います。
  58. SELinuxを無効にする方法 • Linux KernelでSELinuxを無効化はconfigで無効化する だけなので方法は省略 • 無効化したLinux Kernelを用意しておいて、切り替え るのが楽。
  59. SELinuxを無効にする方法 • Linux Kernelのブートパラメータで指定する。 開発時にはこれが便利。 無効化 CONFIG_CMDLINE="androidboot.selinux=disabled" 有効化 androidboot.selinuxにdisabledが設定されていなければ有効
  60. SELinuxが原因かの切り分け • SELinuxを無効化したところ、インストールしたテーマ に含まれるbootanimationが表示された。 • SELinuxが原因と判明したので、Security Policyの定義 を見直す。
  61. bootanimationのSecurity Policy • KitKatとLollipopを比較したところ、KitKatには bootanimation用のSecurity Policyの定義は無かった。 • 無い≒アクセス制限されない。 KitKatで動いていた理由はこれで、Lollipopでは真面目 にSecurity Policyの定義をされてしまったので拒否され ていた。 • KitKat→LollipopではSecurity Policyの定義が厳しく なっているので、こういうケースは実は結構あるかも しれない。
  62. bootanimationのSecurity Policy bootanim.teの内容 type bootanim, domain; type bootanim_exec, exec_type, file_type; init_daemon_domain(bootanim) binder_use(bootanim) binder_call(bootanim, surfaceflinger) allow bootanim gpu_device:chr_file rw_file_perms; allow bootanim oemfs:dir search; allow bootanim oemfs:file r_file_perms; allow bootanim audio_device:dir r_dir_perms; allow bootanim audio_device:chr_file rw_file_perms; ※/data/theme配下へのアクセス許可が存在しないので拒否される
  63. 問題への対処 • Security Policyの追加 JCROMでは/data/theme配下にテーマデータをインス トールするので、テーマデータにアクセスするプロセ スからアクセス出来るようにする。
  64. 必要なSecurity Policy • /data/theme配下へのアクセス許可 /data/theme 配下のファイルを読めれば良い。 • 変更するファイルは次の4つ file.te file_contexts domain.te bootanim.te
  65. file.teとfile_contextsの追加 file.te theme_data_fileという名前の定義を作る。 # /data/theme type theme_data_file, file_type, data_file_type; file_contexts /data/themeを定義する。 ここでtheme_data_fileという名前を使う。 /data/theme(/.*)? u:object_r:theme_data_file:s0
  66. domain.teとbootanim.teの追加 theme_data_fileのアクセスを追加する。 必要なのは読み込みなので、書き込みは許可しない。 domain.te # Read files already opened under /data/theme. allow domain theme_data_file:dir { search getattr }; allow domain theme_data_file:file { getattr read }; allow domain theme_data_file:lnk_file r_file_perms; bootanim.te allow bootanim theme_data_file:dir r_dir_perms; allow bootanim theme_data_file:file r_file_perms;
  67. 応用編 • 新しい機能の追加した時のSecurity Policyを作成
  68. 新しい機能の追加 kassy_kzというサービスを作る。 出来ることは「ユーザデータ(/data)を読んでXXXを実行する」 サービス起動に関しては、init.rcに以下を定義 service kassy_kz /system/bin/kassy_kz disabled oneshot コマンドラインから起動方法は、 「/system/bin/setprop ctl.start kassy_kz」
  69. Security Policyを作らない場合 Security Policyを作れとログが出るだけ。 <3>init: Warning! Service kassy_kz needs a SELinux domain defined; please fix! この状態でkassy_kzが乗っ取られたりすると危険。
  70. Security Policyを作成する bootanimの時同様Security Policyの定義が無いのが原因なので、 kassy_kz.teを作成する。内容は以下の通り。 # kassy_kz oneshot service type kassy_kz, domain; type kassy_kz_exec, exec_type, file_type; init_daemon_domain(kassy_kz) file_contextsにラベルを追加。 /system/bin/kassy_kz u:object_r:kassy_kz_exec:s0 まずは、ほとんど何も許可してない状態にします。
  71. 効果の確認 /system/bin/kassy_kzを起動した結果 <4>type=1400 audit(1399014089.820:28): avc: denied { open } for pid=1987 comm=“kassy_kz” name=“cocoa_chino.jpg” dev=“mtdblock1” ino=412 scontext=u:r:kassy_kz:s0 tcontext=u:object_r:system_data_file:s0 tclass=file permissive=0 /data/picture/gochiusa/cocoa_chino.jpgを覗きに行ったけど、 SELinuxによってアクセスが拒否されたので、Security Policyの設定 に成功した事になります。 この後、必要な操作だけallowを追加していきます。
  72. 開発で役立ったこと
  73. 開発で役立ったこと • ls -Z • ps –Z • loadpolicy
  74. ls -Z lsの結果にラベル表示してくれる。 shell@jcrom:/ # ls –Z drwxrwx--x system system u:object_r:system_data_file:s0 data -rwxr-x--- root root u:object_r:rootfs:s0 init -rwxr-x--- root root u:object_r:rootfs:s0 init.rc drwxr-x--x root sdcard_r u:object_r:rootfs:s0 storage
  75. ps -Z psの結果にラベル表示してくれる shell@jcrom:/ # ps -Z LABEL USER PID PPID NAME u:r:init:s0 root 1 0 /init u:r:shell:s0 shell 66 1 /system/bin/sh u:r:adbd:s0 shell 67 1 /sbin/adbd u:r:kernel:s0 root 139 2 kworker/0:2 u:r:system_server:s0 system 376 55 system_server
  76. loadpolicy Security Policyを読み込む。 開発時にSecurity Policyを修正して確認する時に楽。 shell@jcrom:/ # loadpolicy policy-file loadpolicyの引数にSecurity Policyを指定する。 場所は(読めるところなら)どこでも良い。
  77. 今後
  78. 今後 • 今回はSELinuxの概要とAndroidでの簡単なポリシー作 成まで • SELinuxの実装によりAndroidにどのような変更が入っ てるのか、より細かいSecurity Policyの作成はどうする のか...はどこか(ブログか横浜PF部あたり)で公開し ます
Advertisement