我有一个在Android中使用root用户运行的C二进制文件(su -c binary_path)。
一切正常,直到该二进制文件尝试使用exec*()函数执行另一个二进制文件。虽然在大多数设备上都能正常工作,但在某些设备上会出现EACCES错误。
实际上,这个C二进制文件是通过以下方式启动的:
execlp("su","su","-c",binary_path,NULL);
在某个时刻,二进制文件将尝试进行以下调用(简化):
fork();
...
// child here
execlp("sh","sh","-c",script,NULL);
在不同的Android 6.0设备上进行了测试,包括Nexus 9和S7。Nexus 9正常,S7失败。
因此我检查了以下内容的所有权限和安全上下文,并未发现任何差异:
/system/bin
/system/bin/sh
/system/bin/ls
<library_path>
/su/bin/su
我检查了二进制文件在两个设备上的运行UID/GID = 0,结果都是正确的。
在logcat中,我没有看到任何关于缺少权限或安全策略违规的审计记录。
编辑:刚刚验证了二进制文件正在运行的安全上下文:
$ps -Z
u:r:init:s0 root ...
无论exec()是否起作用,这两个设备相同。
编辑2: 在执行失败的设备上,尝试使用exec()时,/proc/kmsg包含以下内容:
Restricted making process. PID = 8868(<binary>) PPID = 8340(<binary>)
SELinux没有AVC信息,而且在AOSP源代码中找不到此文本。