以root身份运行的二进制文件执行exec()时出现权限拒绝错误

4

我有一个在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源代码中找不到此文本。


你使用Java应用程序来运行C代码吗? - Michele Lacorte
二进制文件是从一个Java应用程序调用的共享库启动的。再次澄清一下,二进制文件被授予了root权限,并且可以调用exec()函数,在某些设备上会失败,但不是所有设备。 - 3c71
也许是清单文件上的显式权限问题?尝试添加 WRITE_EXTERNAL_STORAGE。 - Michele Lacorte
该应用程序已经拥有此权限。二进制文件位于/data/local下,所有权限均已设置为所需的状态,也尝试过使用777权限,但没有任何区别。 - 3c71
1个回答

7
在谷歌上搜索“Restricted making process”后,我偶然发现了三星S5和S6的内核(而不是S7)。
if(CHECK_ROOT_UID(current))
    if(sec_restrict_fork())
    {
        PRINT_LOG("Restricted making process. PID = %d(%s) "
                        "PPID = %d(%s)\n",
            current->pid, current->comm,
            current->parent->pid, current->parent->comm);
        return -EACCES;
    }

而sec_restrict_fork()包含以下内容:

if (sec_check_execpath(current->mm, "/data/")) {
    ret = 1;
    goto out;
}

因此,只有三星设备出现了故障,其他设备没有问题。

感谢您分享这个! - Mygod
据我所见,目前这个问题也影响到一些非三星设备,例如 Nexus 5。 - Mygod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接