Time:20210829
Question:在Android的kernel中,libxxx库中用system函数调用cmd命令,但是无法执行cmd。
Root cause:查看log,用关键字“avc:”发现对应的selinux权限不足。
验证方法:
adb root
adb shell # 进入手机
getenforce # 查看对应的权限设置enforcing表示拦截,permission表示允许
setenforce 0 # 设置为permission
setenforce 1 # 设置为enforcing
如果设置为permission可以正确调用system函数执行cmd,那么说明是selinux权限问题。

allow添加权限

然后开始解决selinux权限问题。将log中被denied的权限,添加到对应的xxx.te文件中,allow该权限。举个例子:
log:

avc: denied  { connectto } for  pid=2671 comm="ping" path="/dev/socket/dnsproxyd"
scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
  • 上方的 { connectto } 表示执行的操作。根据它和末尾的 tclass (unix_stream_socket),您可以大致了解是对什么对象执行什么操作。在此例中,是操作方正在试图连接到 UNIX 信息流套接字。
  • scontext (u:r:shell:s0)表示发起相应操作的环境,在此例中是 shell中运行的某个程序。
  • tcontext (u:r:netd:s0) 表示操作目标的环境,在此例中是归 netd 所有的某个 unix_stream_socket。
  • 顶部的 comm="ping" 可帮助您了解拒绝事件发生时正在运行的程序。在此示例中,给出的信息非常清晰明了。

然后在对应的xxx.te文件(例子中根据shell,应该在shell.te文件)中添加权限。

allow shell netd:unix_stream_socket { connectto };

添加权限的模板:

allow scontext tcontext:tclass permission;

permission表示执行的操作。

添加file的execute等权限

一般的权限问题以上方法就可以解决,但是**如果要添加file的executeexecute_no_trans等权限,需要将vendor_executes_system_violators属性在对应的xxx.te文件中type出来。

typeattribute xxx vendor_executes_system_violators;

然后再编译,如果没问题,就可以了。但现实很残酷,编译报错,说vendor_executes_system_violators仍然neverallow。
经过排查,需要确认下vendor_executes_system_violators属性是否打开,即被设置为true
attribute文件中:

# All vendor domains which violate the requirement of not executing
# system processes
# TODO(b/36463595)
attribute vendor_executes_system_violators;
expandattribute vendor_executes_system_violators false;

从中可以看到vendor_executes_system_violators属性被设置为false,将其改为true。再编译,应该就可以解决问题了。

解决selinux问题的方向

  1. 查看log中avc:关键字中被denied的操作
  2. setenforce 0看是否为selinux权限问题
  3. 确认权限问题后,在对应的xxx.te文件中allow对应的权限
  4. source build/envsetup.shlunch。在system/sepolicy路径下,mma -j32编译
  5. 如果报错,切记一定要仔仔细细地分析mma编译的错误,然后再看.te文件的注释的,check权限的代码。根据错误来修改,这是通往正确的最快路径。
  6. 然后可以将对应的文件adb push到手机,验证是否修改生效。