需要权限才能访问 /dev/diag

Needed permission to access /dev/diag

我正在尝试使用 JNI 作为 open("/dev/diag", O_RDWR | O_LARGEFILE | O_NONBLOCK); 打开 /dev/diag 但返回 errno: 13 Permission denied

要完成这项工作应该怎么做?

当使用命令 ls -l /dev/diag 检查 /dev/diag 的所有权时,它 returns 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

所以我认为问题与所有权有关?

Update: Based on @HamidShatu answer

我尝试将 SELinux 设置为宽容,但没有成功。

我尝试了命令 su 0 setenforce 0 它 returns OK 如果立即使用 getenforce 命令检查仍然是 Enforcing

我什至尝试更改 prop.build:这个文件不存在而不是 prop.build.bak 这样做,所以我复制它修改 SELinux 为 0 而不是 1 并在没有 .烤扩展。即使我检查了修改 prop.build 的外部应用程序,其中 SELinux 设置为 0,但是当使用 getenforce 命令检查时,它仍然返回 Enforcing

这里是 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"

提示:我正在使用可以成功访问 /dev/diag 的 Play 商店中的应用程序。

对于understand/analyze你的问题,也许我们可以先看看你在这里发布的内容。

I am trying to open the /dev/diag using JNI as open("/dev/diag", O_RDWR | O_LARGEFILE | O_NONBLOCK); but returning errno: 13 Permission denied.

根据我的经验,errno: 13 Permission denied 表明您的代码存在一些 SELinux 违规行为。

When checking the ownership of the /dev/diag using the command ls -l /dev/diag it returns crw-rw-rw- system qcom_diag 244, 0 2015-01-14 01:47 diag and when trying to use the command id, I get uid=0(root) gid=0(root) groups=0(root) context=u:r:init:s0

这部分清楚地表明 /dev/diag 目录属于 Qualcomm。根据AndroidTreble重新架构,主要有3个分区属于:

  1. Android系统(Google/AOSP)
  2. 供应商(芯片制造商)&
  3. OEM(设备制造商)

所以,根据你的分析,/dev/diag属于Vendor分区。

So I thought the problem is related to ownership?

这个问题的答案差不多:是的。

What should be done to make this work?

您需要添加 SELinux 权限才能使其正常工作。 正如 crw-rw-rw- system qcom_diag 244, 0 2015-01-14 01:47 diag 行所建议的,您需要添加 SELinux 权限才能从 system 访问 qcom_diag for 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