1. ホーム
  2. アンドロイド

SELinuxのポリシールールの設定方法は?カーネルログに "avc: denied "と表示された場合、どうすればよいですか?

2022-02-24 22:21:34
[説明]をクリックします。



android KK 4.4 以降、Google はデフォルトで SELinux を有効にし、SELinux のレビュー例外をカーネルログまたは android ログ (L 版) に、 "avc: denied" または "avc: denied& というキーワードに対応して出力するようになりました。



もし、LOGの行が



<5>[ 17.285600]. (0)[503:idmap]type=1400 audit(1356999072.320:202): avc: denied { create } for pid=503 comm="idmap" name="overlays.list" scontext=u:r:zygote:s0 tcontext=u:object_r:resource_cache_data_file:s0 tclass=file
つまり、zygoteのソースコンテキストを使用したプロセスidmapが、/data/resource_cacheディレクトリにアクセスし、SELinuxでアクセスを拒否されているファイルを作成していることを示しています。







[キーワード]



アンドロイド、SELinux、avc: 拒否、監査







[解決方法]
つまり、netd, installd, zygote, vold とその直接フォークした子プロセスのみで、zygoteからフォークした通常のアプリには適用されません。



L版では、GoogleがSELinuxを完全に有効化し、ほぼすべてのプロセスで強制モードが使用されるため、非常に広い範囲で影響があります。







すべてのSELinuxチェックの失敗には、対応する "avc: denied" または "avc: denied" LOGがカーネルログまたはアンドロイドログ(Lバージョン以降)に記録されるようになりました。翻って、このLOGがあるからといって直接失敗するわけではなく、その時のSELinuxのモードがenforcing modeなのかpermissve modeなのかを確認する必要があります。
まず、対応するプロセスがシステムリソースに正しくアクセスしているか、必要なものかどうかを確認します。もし、アクセス自体が異常で違法であれば、アクセス自体を排除する。



次に、必要かつ正常なアクセスであれば、該当するプロセス/ドメインに新しいポリシーを追加します。




1). 手法の簡略化



 1.1 avcのLOGを全て抽出する。例:adb shell "cat /proc/kmsg | grep avc" > avc_log.txt



 1.2 audit2allow ツールを使用して、ポリシーを直接生成します。 audit2allow -i avc_log.txt は、生成されたポリシーを自動的に出力します。



 1.3 対応するポリシーを selinux ポリシールールに追加します。MTK ソリューションに対応するには、以下のように KK: mediatek/custom/common/sepolicy, L: device/mediatek/common/sepolicy に追加すればよいでしょう。



  zygote resource_cache_data_file:dir rw_dir_perms を許可します。



  zygote resource_cache_data_file:file create_file_perms を許可します。



  ===> mediatek/custom/common/sepolicy/zygote.te (KK)



  ===> device/mediatek/common/sepolicy/zygote.te (L)



 audit2allowは、あなたの行動の真意を知ることなく、自動的に機械的にLOGをポリシーに変換するため、パーミッション増幅の問題がある可能性があることに注意してください。







2). オンデマンド確認方式



 この方法は、SELinuxの基礎とSELinux Policy Languageに関する技術的な知識が必要です。 



 2.1 どのプロセスがどのリソースにアクセスしているのか、またどのようなアクセス権が必要なのかを特定します(read ? write ? exec ? create ? search ?



 2.2 現在のプロセスは、すでにポリシーファイルを作成しているか?そうでなく、その親プロセスであるソースコンテキストが対応するリソースにアクセスする必要がない場合、新しいテファイルが作成されます。



     L版では、Googleは重要なセキュリティコンテキストを一意に保つことを要求しており、例えばzygote, netd, installd, vold, ueventdなどの重要なプロセスは、他のプロセスと同じセキュリティコンテキストを共有することはできません。



 2.3 ファイル作成後、その実行ファイルを file_contexts で関連付ける。



  例えば、/system/bin/idmap は /system/bin/idmap u:object_r:idmap_exec:s0 となります。



 2.4 関連するteファイルにポリシーを記入する



  元の親プロセスのteファイルを使用する場合は、直接追加する。



  新しいファイルであれば、まず。



  #==============================================



  # 型宣言



  # ==============================================



  タイプ idmap, domain;



  idmap_exec、exec_type、file_typeの各タイプを指定します。







  #==============================================



  # Android ポリシールール



  #==============================================



  #permissive idmap;



  domain_auto_trans(zygote, idmap_exec, idmap);







  次に、新しいポリシーを追加します。







  # 新ポリシー



  idmap resource_cache_data_file:dir rw_dir_perms を許可します。



  idmap resource_cache_data_file:file create_file_permsを許可します。







3). パーミッション増幅ケース処理



  SELinux Policy を avc: denied LOG に従って直接変換すると、権限増幅の問題が発生することが多い。例えば、SELinux Labelを細かく設定していないデバイスにアクセスしたい場合、このようなことが起こる可能性があります。



  <7>[11281.586780] avc: denied { read write } for pid=1217 comm="mediaserver" name="tfa9897" dev="tmpfs" ino=4385 scontext=u:r:mediaserver:S0 tcontext=u:object_r:device:S0 tclass=chr_file permissive=0



  このLOGをそのままSELinux Policyに変換すると、allow mediaserver device:chr_file {read write};となり、全てのデバイスに対するmediaserverの読み込み、書き込みアクセスが解放されます。これを防ぐために、Googleはneverallow文を使って制約をかけ、これなしではsepolicyをコンパイルできないようにしています。
  このような特権の増幅を避けるためには、オブジェクトにアクセスするためのSELinuxラベルを洗練させ、オンデマンドで要求できるようにする必要がある。これは通常3つのステップからなる



  3.1 関連する SELinux タイプを定義する。



   例えば、上記の場合、device/mmediatek/common/sepolicy/device.teに、以下のように追加します。



   タイプ tfa9897_device, dev_type;



  3.2 ファイルをSELinuxの型にバインドする。



   例えば、上記の場合、device/mmediatek/common/sepolicy/file_contextsに、以下のように追加します。



   /dev/tfa9897(/. *)? u:object_r:tfa9897_device:s0を指定します。



  3.3 対応するプロセス/ドメインにアクセス権を追加する。



   例えば、上記の場合、device/mmediatek/common/sepolicy/mediaserver.teに以下を追加します。



   mediaserver tfa9897_device:chr_file { open read write } を許可します。
  では、どのアクセスオブジェクトが通常このタイプに遭遇するのでしょうか?(L版を例にとると)



    * デバイス  



  -- 型定義:external/sepolicy/device.te;device/mmediatek/common/sepolicy/device.te 



  -- タイプバインディング:external/sepolicy/file_contexts;device/mmediatek/common/sepolicy/file_contexts







  * ファイルの種類です。 



  -- 型定義:external/sepolicy/file.te;device/mmediatek/common/sepolicy/file.te



  -- バインディングタイプ: external/sepolicy/file_contexts;device/mediatek/common/sepolicy/file_contexts
  * 仮想ファイルの種類です。 



  -- 型の定義:external/sepolicy/file.te;device/mmediatek/common/sepolicy/file.te



  -- バインディングタイプ: external/sepolicy/genfs_contexts;device/mediatek/common/sepolicy/genfs_contexts
  * サービスタイプ。



  -- タイプ定義:external/sepolicy/service.te; device/mediatek/common/sepolicy/service.te



  -- バインディングタイプ: external/sepolicyservice_contexts; device/medek/common/sepolicy/service_contexts
  * プロパティの種類を指定します。



  -- 型の定義:external/sepolicy/property.te;device/mmediatek/common/sepolicy/property.te



  -- バインディングタイプ: external/sepolicy/property_contexts;device/mediatek/common/sepolicy/property_contexts.Binding Type: external/sepolicy/property_contexts;
  通常、私たちはgoogleのデフォルトポリシーを更新することを強く反対しています。







[関連FAQ】をご覧ください。]



[FAQ11414] android KK 4.4以降、ユーザーのsu権限が極端に制限される問題



[FAQ11485] パーミッション拒否の問題で、Selinuxの制約が原因であることを確認するには?



[FAQ11484] 確認用selinuxモードの設定方法について



[FAQ11483] SELinuxポリシーの問題を迅速にデバッグする方法