我正试图使用JNI作为open("/dev/diag", O_RDWR | O_LARGEFILE | O_NONBLOCK);
打开/dev/diag,但返回errno: 13 Permission denied
。
应该做些什么才能使它发挥作用?
使用命令ls -l /dev/diag
检查/dev/diag的所有权时,返回crw-rw-rw- system qcom_diag 244, 0 2015-01-14 01:47 diag
并且当尝试使用命令id
时,我得到uid=0(root) gid=0(root) groups=0(root) context=u:r:init:s0
所以我认为问题与所有权有关?
更新:基于@HamidShatu回答
我试图将SELinux设置为permission,但没有成功。
我尝试了命令su 0 setenforce 0
,如果立即使用getenforce
命令进行检查,它将返回OK
,同时仍然是Enforcing
。
我甚至试图更改prop.build:这个文件不存在,取而代之的是prop.build.bak,所以我复制了它,将SELinux修改为0而不是1,并在没有.bak扩展名的情况下推送它。即使我检查了修改prop.build的外部应用程序,其中SELinux设置为0,但当使用getenforce命令检查时,它仍然返回Enforceing
这是dmesg:的摘录
[18177.676603] [0: servicemanager: 743] avc: received setenforce notice (enforcing=1)
[18182.768070] [1: servicemanager: 743] avc: received setenforce notice (enforcing=1)
[18183.231867] [0: init: 1] avc: received setenforce notice (enforcing=1)
[18183.232006] [0: init: 1] avc: received setenforce notice (enforcing=1)
我甚至试图通过添加到Manifest:<application--> android:sharedUserId="android.uid.system"
来使应用程序作为系统应用程序运行
提示:我正在使用play store中的应用程序,这些应用程序可以成功访问/dev/diag。
要了解/分析您的问题,也许我们可以先查看您在这里发布的内容。
我试图使用JNI作为
open("/dev/diag", O_RDWR | O_LARGEFILE | O_NONBLOCK);
打开/dev/diag
,但返回errno: 13 Permission denied
。
根据我的经验,errno: 13 Permission denied
表明您的代码正在执行一些SELinux违规行为。
当使用命令
ls -l /dev/diag
检查/dev/diag
的所有权时,它返回crw-rw-rw- system qcom_diag 244, 0 2015-01-14 01:47 diag
,当尝试使用命令id
时,我得到uid=0(root) gid=0(root) groups=0(root) context=u:r:init:s0
这部分清楚地表明/dev/diag
目录属于高通公司。根据AndroidTreble重新架构,有3个主要分区属于:
- 安卓系统(Google/AOSP(
- 供应商(芯片制造商(&
- OEM(设备制造商(
因此,根据您的分析,/dev/diag
属于供应商分区。
所以我认为问题与所有权有关?
这个问题的答案基本上是:是的。
应该做些什么来实现这一点?
您需要添加SELinux权限才能执行此操作。正如crw-rw-rw- system qcom_diag 244, 0 2015-01-14 01:47 diag
行所建议的那样,您需要添加SELinux权限才能从system
访问qcom_diag
以获得diag
。
有一点是,任何类型的diag
权限都只在Debug版本中授予,而不是在User构建中授予。因为在User版本中为diag
授予SELinux权限会引起安全问题。它可以通过将重要信息打印在日志中来泄露这些信息。
经过几天的努力,我能够通过以下操作绕过问题:
-
我没有将C代码用作共享库,因为我很难打开/dev/diag,而是使用Cmake将其作为可执行的C(.C文件应该有一个主函数(,如下所示:
cmake_minimum_required(VERSION 3.4.1) file(GLOB SRC_FILES src/main/cpp/*.c) add_executable( mylib.so ${SRC_FILES} )
-
在Java中创建一个新命令,该命令可以使用root权限执行mylib,如下所示:
new String[]{"su", "-c", "exec " + context.getApplicationInfo().nativeLibraryDir + "/" + "mylib.so"}
-
使用流程生成器执行命令
process = new ProcessBuilder(command) .start();
可执行文件能够毫无错误地使用open("/dev/diag", O_RDWR | O_LARGEFILE | O_NONBLOCK);
!
原因是即使在SU模式下,应用程序在执行功能时也会降级到正常模式,但在SU模式中执行库将确保其在SU 中运行