简体   繁体   English

如何在 android 中永久注入 SELinux 策略?

[英]How to inject SELinux policies permanently in android?

I have a rooted android device and I need to inject following policies into it:我有一个扎根的 android 设备,我需要向其中注入以下策略:

sepolicy-inject -s init -t su -c process -p transition -l
sepolicy-inject -s su -t system_file -c file -p entrypoint -l
sepolicy-inject -s init -t su -c process -p rlimitinh -l
sepolicy-inject -s init -t su -c process -p siginh -l
sepolicy-inject -s su -t shell_exec -c file -p read -l
sepolicy-inject -s su -t shell_exec -c file -p execute -l
sepolicy-inject -s su -t shell_exec -c file -p getattr  -l
sepolicy-inject -s su -t vendor_toolbox_exec -c file -p execute_no_trans -l
sepolicy-inject -s init -t su -c process -p noatsecure -l
sepolicy-inject -s su -t toolbox_exec -c file -p getattr -l
sepolicy-inject -s su -t toolbox_exec -c file -p execute -l
sepolicy-inject -s su -t system_file -c file -p execute_no_trans -l
sepolicy-inject -s su -t storage_file -c dir -p search -l
sepolicy-inject -s su -t storage_file -c lnk_file -p read -l
sepolicy-inject -s su -t tmpfs -c dir -p search -l
sepolicy-inject -s su -t mnt_user_file -c dir -p search -l
sepolicy-inject -s su -t mnt_user_file -c lnk_file -p read -l
sepolicy-inject -s su -t sdcardfs -c dir -p search -l
sepolicy-inject -s su -t sdcardfs -c file -p append -l
sepolicy-inject -s su -t toolbox_exec -c file -p read -l
sepolicy-inject -s su -t toolbox_exec -c file -p open -l
sepolicy-inject -s su -t sdcardfs -c file -p read -l
sepolicy-inject -s su -t sdcardfs -c file -p write -l

As you can see, I am using sepolicy-inject commands to inject the required policies.如您所见,我正在使用sepolicy-inject命令来注入所需的策略。 I am facing a problem where on reboot these policies not exists anymore.我面临一个问题,重新启动这些策略不再存在。

As per my understanding the new policies are injected at /sys/fs/selinux/policy location and this is not persistent storage.据我了解,新策略是在/sys/fs/selinux/policy位置注入的,这不是持久存储。 Also, there is a file on root partition /sepolicy which contain these policy rules.此外,根分区/sepolicy上还有一个文件,其中包含这些策略规则。

I found ./sepolicy in boot.img .我在boot.img中找到./sepolicy I have a A/B partition device so, the ./sepolicy in boot.img is for recovery only.我有一个 A/B 分区设备,所以boot.img中的./sepolicy仅用于恢复。

Now, I am not able to understand how to inject the required policies permanently to the device because of following reason:现在,由于以下原因,我无法理解如何将所需的策略永久注入设备:

  1. /sys/fs/selinux/policy and /sepolicy are not on permanent storage partition. /sys/fs/selinux/policy/sepolicy不在永久存储分区上。
  2. boot.img only contain SELinux policies that are available on recovery only. boot.img仅包含仅在恢复时可用的 SELinux 策略。

Please suggest how can I achieve my goal.请建议我如何实现我的目标。

"/sepolicy" is a ramdisk so it's temporarily. "/sepolicy" 是一个 ramdisk,所以它是暂时的。 You can solve it by put that command in some "init" script that will run "sepolicy-inject ..." commands at bootup ;)您可以通过将该命令放在一些“init”脚本中来解决它,该脚本将在启动时运行“sepolicy-inject ...”命令;)

I know the question was asked quite some time ago, but since I tried doing something similar recently and this post was one of the top hits on Google, I want to share my recent experience to help others.我知道这个问题是很久以前提出的,但是由于我最近尝试做类似的事情并且这篇文章是谷歌的热门文章之一,我想分享我最近的经验来帮助其他人。

As I believe the answer answer your questions, here is a shameless copy/paste of my answer to this question :因为我相信答案可以回答您的问题,所以这是我对这个问题的回答的无耻复制/粘贴:

Note that this answer will focus solely on Android 9 to 13 and Treble devices.请注意,此答案将仅关注 Android 9 至 13 和 Treble 设备。

If we want to know how to modify the SELinux policies, I believe it is good to first understand how the policies are loaded in the first place.如果我们想知道如何修改 SELinux 策略,我相信最好先了解策略是如何加载的。

SELinux in the boot process启动过程中的 SELinux

At an early stage of the Android boot process and after mounting most of the partitions, init will attempt to load the SELinux policies from a monolithic sepolicy file found at either /odm/etc/selinux/precompiled_sepolicy or /vendor/etc/selinux/precompiled_sepolicy .在 Android 引导过程的早期阶段和挂载大部分分区后, init将尝试从位于/odm/etc/selinux/precompiled_sepolicy/vendor/etc/selinux/precompiled_sepolicy的单一 sepolicy 文件加载 SELinux 策略. If init notices that the device is updated out of sync, init will instead recompile the SELinux policies based on .cil files that can be found on several locations.如果init注意到设备更新不同步, init将改为根据可以在多个位置找到的.cil文件重新编译 SELinux 策略。

You can find all the details in the comments of the init/selinux.cpp source file and by looking at the implementation, but here is a summary of the exact steps taken by init :您可以在init/selinux.cpp源文件的注释和查看实现中找到所有详细信息,但这里是init所采取的确切步骤的摘要:

  1. Find the sepolicy file to use:找到要使用的 sepolicy 文件:
    • if /odm/etc/selinux/precompiled_sepolicy exists, use it as the sepolicy file to use如果/odm/etc/selinux/precompiled_sepolicy存在,则将其作为 sepolicy 文件使用
    • else, if /vendor/etc/selinux/precompiled_sepolicy exists, use it as the sepolicy file to use否则,如果/vendor/etc/selinux/precompiled_sepolicy存在,则将其作为 sepolicy 文件使用
    • else if neither of the above exists, stop here, recompile the policies based on the .cil files and load the newly compiled sepolicy file.否则,如果以上都不存在,则停在这里,根据.cil文件重新编译策略并加载新编译的 sepolicy 文件。
  2. Check if device was updated out of sync:检查设备是否更新不同步:
    • Compare /(odm|vendor)/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 and /system/etc/selinux/plat_sepolicy_and_mapping.sha256比较/(odm|vendor)/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256/system/etc/selinux/plat_sepolicy_and_mapping.sha256
    • Compare /(odm|vendor)/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 and /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256比较/(odm|vendor)/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256/system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256
    • Compare /(odm|vendor)/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 and /product/etc/selinux/product_sepolicy_and_mapping.sha256比较/(odm|vendor)/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256/product/etc/selinux/product_sepolicy_and_mapping.sha256
    • (On Android 13) Compare /(odm|vendor)/etc/selinux/precompiled_sepolicy.apex_sepolicy.sha256 and /dev/selinux/apex_sepolicy.sha256 (在 Android 13 上)比较/(odm|vendor)/etc/selinux/precompiled_sepolicy.apex_sepolicy.sha256/dev/selinux/apex_sepolicy.sha256
    • if any of the above pair of files do not match, stop here, recompile the policies based on the .cil files and load the newly compiled sepolicy file.如果上述任何一对文件不匹配,请在此处停止,根据.cil文件重新编译策略并加载新编译的 sepolicy 文件。
  3. If everything is ok, load the precompiled sepolicy file ( /odm/etc/selinux/precompiled_sepolicy or /vendor/etc/selinux/precompiled_sepolicy )如果一切正常,加载预编译的 sepolicy 文件( /odm/etc/selinux/precompiled_sepolicy/vendor/etc/selinux/precompiled_sepolicy

The compilation of the policies based on the .cil files is as follows:基于.cil文件的策略编译如下:

  1. Get the latest version of the policies that are compatible with the vendor version ( /vendor/etc/selinux/plat_sepolicy_vers.txt , note that init does not look at the file in the /odm partition)获取与vendor版本兼容的策略的最新版本( /vendor/etc/selinux/plat_sepolicy_vers.txt ,注意init不会查看/odm分区中的文件)
  2. Gather the .cil files to compile:收集.cil文件进行编译:
    • /system/etc/selinux/mapping/{vendor_version}.cil
    • /system/etc/selinux/mapping/{vendor_version}.compat.cil
    • /system_ext/etc/selinux/system_ext_sepolicy.cil
    • /system_ext/etc/selinux/mapping/{vendor_version}.cil
    • /product/etc/selinux/product_sepolicy.cil
    • /product/etc/selinux/mapping/{vendor_version}.cil
    • /vendor/etc/selinux/plat_pub_versioned.cil
    • /vendor/etc/selinux/vendor_sepolicy.cil or if it does not exist: /vendor/etc/selinux/nonplat_sepolicy.cil /vendor/etc/selinux/vendor_sepolicy.cil或者如果它不存在: /vendor/etc/selinux/nonplat_sepolicy.cil
    • /odm/etc/selinux/odm_sepolicy.cil
  3. Compile the above files with secilc to /dev/sepolicy.XXXXXX将上述文件用secilc编译到/dev/sepolicy.XXXXXX
  4. Load policies from /dev/sepolicy.XXXXXX/dev/sepolicy.XXXXXX加载策略

Modifying SELinux policies permantently永久修改 SELinux 策略

Now that we understand how init loads the policies, it is easy to see how one could permanently add new policies to the system:现在我们了解了init如何加载策略,很容易看出如何将新策略永久添加到系统中:

  • Directly add the policies to /odm/etc/selinux/precompiled_sepolicy or /vendor/etc/selinux/precompiled_sepolicy with sepolicy-inject :使用sepolicy-inject直接将策略添加到/odm/etc/selinux/precompiled_sepolicy/vendor/etc/selinux/precompiled_sepolicy
     sepolicy-inject -s su -t system_file -c file -p entrypoint -P /vendor/etc/selinux/precompiled_sepolicy -o /vendor/etc/selinux/precompiled_sepolicy
  • Make init thinks the device is updated out of sync (By modifying one of the above .sha256 files, or deleting the precompiled sepolicy files) and modify one of the above .cil files make init认为设备更新不同步(通过修改上述.sha256文件之一,或删除预编译的 sepolicy 文件)并修改上述.cil文件之一

Note that in both cases, you will need to have a read-write access to the partition you want to modify ( /vendor , /odm , and/or /system ).请注意,在这两种情况下,您都需要对要修改的分区( /vendor/odm和/或/system )具有读写访问权限。 These partitions are normally mounted as read-only, so you will have to either:这些分区通常以只读方式挂载,因此您必须:

  • Remount them as read-write if you have root access (either because your device is rooted, or using adb root on a userdebug Android build)如果您具有 root 访问权限,则将它们重新挂载为读写(因为您的设备已获得 root 权限,或者在userdebug Android 版本上使用adb root
  • Boot in recovery mode, mount the partitions as read-write and modify them in recovery以恢复模式启动,将分区挂载为读写并在恢复中修改它们

If you do not want to have to remount the partitions every time you want to change the SELinux policies, you can add some SELinux rules to allow init to load new policies, and then create an init script that will load new policies.如果您不想每次更改 SELinux 策略时都必须重新挂载分区,您可以添加一些 SELinux 规则以允许init加载新策略,然后创建一个将加载新策略的init脚本。 You can find which SELinux rules are needed by searching for SELinux violations (avc errors) in the device logs on startup:您可以通过在启动时在设备日志中搜索 SELinux 违规(avc 错误)来找到需要哪些 SELinux 规则:

adb logcat | grep avc

With this, you will be able to have an init script that loads new policies with sepolicy-inject .有了这个,您将能够拥有一个使用sepolicy-inject加载新策略的init脚本。

只需将 selinux 设置为 permissive 即可禁用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM