首页 > 解决方案 > 设置 shell 脚本 Android SELinux 策略以在系统启动时启动它已完成

问题描述

我在为具有以下内容的 sh 脚本 (init.myservice.sh) 创建 SELinux 策略时遇到了麻烦:

#!/system/bin/sh
/system/bin/am force-stop 'com.myapp.apptest'
/system/bin/tinymix 'Headphone Volume' 35;tinymix 'Capture Input' ADC;tinymix 'DMIC Mux' DMIC2;
/system/bin/am start -n ' com.myapp.apptest/ com.myapp.apptest.MainActivity' -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
/system/bin/my_board_service &

如您所见,此脚本执行以下操作:

我在“init.rc”文件中添加了以下几行:

on property:sys.boot_completed=1
    start init-myservice

service init-myservice /system/bin/sh /system/bin/init.myservice.sh
    class main
    user root
    group root system
    disabled
    oneshot

我可以在路径“/system/bin”下看到构建系统中的脚本和具有正确权限(755)的二进制文件,如果我手动启动它,它运行良好。但我无法在系统启动时启动它,因为(没有设置任何策略)我在 shell 上收到此错误:

命令 'start init-myservice' action=sys.boot_completed=1 (/vendor/etc/init/hw/init.freescale.rc:334) 耗时 5ms 失败:无法启动服务:文件 /system/bin/init. myservice.sh(labeled "u:object_r:system_file:s0") 的标签不正确或没有从 u:r:init:s0 到定义的另一个 SELinux 域的域转换。您是否正确配置了服务? https://source.android.com/security/selinux/device-policy#label_new_services_and_address_denials

所以我试图在没有任何运气的情况下生成服务策略。我尝试了以下方法:我的 .te 文件的内容如下:

# foo service
type foo, domain;
type foo_exec, exec_type, file_type;
init_daemon_domain(foo)

我在此位置下的“file_contexts”文件中添加了以下行:“android_build/device/variscite/imx8m/dart_mx8mm/sepolicy/”

/system/bin/init\.myscript\.sh      u:object_r:foo_exec:s0

当我构建我的 AOSP 项目时,我很少遇到这样的错误:

失败:out/target/product/dart_mx8mm/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 /bin/bash -c "(out/host/linux-x86/bin/treble_sepolicy_tests -l
out/host/linux-x86/lib64/libsepolwrap.so -f out/target/product/dart_mx8mm/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/dart_mx8mm/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out /target/product/dart_mx8mm/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/dart_mx8mm/obj/ETC/treble_sepolicy_tests_28.0_intermediates/28.0_mapping.combined.cil -o out/target/product/dart_mx8mm/obj/ ETC/treble_sepolicy_tests_28.0_intermediates/built_28.0_plat_sepolicy -p out/target/product/dart_mx8mm/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/dart_mx8mm/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble ) && (touch out/target/product/dart_mx8mm/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 )" 以下域必须与“coredomain”属性相关联,因为它们是在 /system 之外执行的:foo

标签: androidshellandroid-sourceselinux

解决方案


我最近能够得到你所描述的工作,但我们的方法存在一些差异。我所有的更改都在目标的“/vendor”中。我不确定您的 init.rc 更改在哪里,但您将脚本描述为安装在“/system”中。

否则,您所描述的大部分内容都很熟悉,包括在编译 SELinux 策略时遇到问题。最后,对我有用的政策看起来像这样:

# foo service
type foo, domain;
type foo_exec, exec_type, vendor_file_type, file_type;

init_daemon_domain(foo)

# followed by all the particulars of my service.

如果您设置在“系统”而不是“供应商”中安装服务,则错误消息的措辞似乎是在告诉您将您的域与“核心域”相关联。我认为这意味着您的策略应在“init_daemon_domain”之前的某处包含以下行:

typeattribute foo coredomain;

您还应该知道,我已经看到它说有一个 SELinux 政策禁止将“供应商”与“系统”混合。我不确定,但我认为这意味着如果你修改了 /vendor 文件系统中的 init.rc 来运行你的脚本,那么你只能使用 /vendor 文件系统中的“stuff”。上面的示例显示了使用 /system/bin/sh 的脚本,因此如果您修改 /vendor 文件系统中的 init.rc 以启动该脚本,我认为这将是违规行为。


推荐阅读