Android 在 SElinux下 如何获得对一个内核节点的访问权限

本文介绍如何在Android5.0系统中通过SEAndroid/SElinux安全机制配置特定内核节点的访问权限。以自定义节点/dev/wf_bt为例,详细说明了修改file_contexts.be和device.te文件的方法,以及如何在system_server.te中授予system_server进程对该节点的读写权限。


Android 5.0下,因为采取了SEAndroid/SElinux的安全机制,即使拥有root权限,或者对某内核节点设置为777的权限,仍然无法在JNI层访问。

本文将以用户自定义的内核节点 /dev/wf_bt为例,手把手教会读者如何在JNI层获得对该节点的访问权限。

第一步:找到需要访问该内核节点的进程(process),笔者自己这个节点由 system_server进程来访问

第二步:打开文件AndroidL/android/external/sepolicy/ file_contexts.be
仿照这个文件里的写法,为你的节点定义一个你想要的名字:
[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /dev/tegra.* u:object_r:video_device:s0  
  2. /dev/tf_driver u:object_r:tee_device:s0  
  3. /dev/tty u:object_r:owntty_device:s0  
  4. /dev/tty[0-9]* u:object_r:tty_device:s0  
  5. # We add here  
  6. /dev/wf_bt              u:object_r:wf_bt_device:s0  
wf_bt_device是自定义,其他左右两边的内容都和上面的范例一致。

第三步:打开文件AndroidL/android/external/sepolicy/ device.te
仿照这个文件里的写法,将刚刚第二步写的wf_bt_device声明为dev_type:
[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # Device types  
  2. type device, dev_type, fs_type;  
  3. type alarm_device, dev_type, mlstrustedobject;  
  4. type adb_device, dev_type;  
  5. type ashmem_device, dev_type, mlstrustedobject;  
  6. type audio_device, dev_type;  
  7. type binder_device, dev_type, mlstrustedobject;  
  8. type block_device, dev_type;  
  9. # We add here  
  10. type wf_bt_device, dev_type;  

第四步:
AndroidL/android/external/sepolicy/目录下 很多.te文件都是以进程名来结尾的,比如有针对surfaceflinger进程的surfaceflinger,有针对vold进程的vold.te,
刚刚从第一步得到,这个节点是由system_server进程来访问,所以,我们找到 system_server.te打开,加入允许这个进程对/dev/wf_bt的读写权限,

[python] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. # Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid.  
  2. allow system_server qtaguid_proc:file rw_file_perms;  
  3. allow system_server qtaguid_device:chr_file rw_file_perms;  
  4.   
  5. # chr_file表示字符设备文件,如果是普通文件用file,目录请用dir  
  6. # rw_file_perms代表读写权限  
  7. allow system_server wf_bt_device:chr_file rw_file_perms;  // 允许system_server进程拥有对wf_bt_device的这个字符设备的读写权限;
这句话的意思是:允许system_server进程拥有对wf_bt_device的这个字符设备的读写权限。
改了这些之后,你就可以make installclean;make -j16编译image来验证权限是否获取成功。

fd =open(“/dev/wf_bt”,O_RDONLY | O_NOCTTY); 绝对成功!!!!!

=====================================

allow system_server wf_bt_device:chr_file rw_file_perms; //允许system_server进程拥有对wf_bt_device的这个字符设备的读写权限。






转自: http://blog.youkuaiyun.com/wh_19910525/article/details/45170755
<think>好的,我现在需要帮助用户解决在Androidnative层读取内核节点信息的问题。首先,用户的问题涉及到底层开发,可能需要涉及Linux内核、文件系统操作以及JNI的知识。用户之前提供的引用中提到了native方法声明和输入子系统的相关内容,这应该和读取内核节点有关。首先,我应该回顾一下用户提供的引用。引用[2]展示了如何在Java层声明native方法,比如write_node_file和read_node_file,这些方法可能在native层实现。引用[3]提到用户层获取/dev/input/event0节点数据,这可能涉及到打开设备文件、读取数据等操作。因此,用户的问题应该是在Android的native层(C/C++代码)中如何访问这些内核节点,比如/dev下的设备文件。 接下来,我需要考虑Android系统中访问设备文件的权限问题。通常,设备节点位于/system、/dev等目录下,普通应用可能没有权限访问。因此,在native层可能需要提升权限或者应用程序具有足够的权限(比如系统应用或root权限)。此外,可能需要使用Linux的系统调用,如open、read、write、close等函数来操作设备文件。然后,我需要考虑如何在native层实现这些操作。通常,这会涉及编写JNI代码,将Java的native方法映射到C/C++函数。例如,用户提到的read_node_file方法,对应的JNI函数需要打开指定的文件,读取内容,并返回给Java层。需要注意的是文件路径的正确性,以及错误处理,比如文件不存在或权限不足的情况。 另外,用户可能还需要了解如何在Android.mk或CMakeLists.txt中配置native库的编译,以及如何确保生成的so库被正确加载。此外,还需要考虑不同Android版本的可能差异,比如对SELinux策略的影响,这可能会限制对某些节点的访问。用户可能遇到的问题包括权限不足、文件路径错误、缓冲区处理不当等。因此,在回答中需要强调权限管理和错误检查的重要性。同时,可能需要给出代码示例,展示如何在native层使用open和read函数,并将数据返回给Java层。最后,根据用户的要求,生成相关问题,帮助用户进一步学习。可能的问题包括如何提升权限、如何处理不同设备节点、如何进行错误处理等。</think>在Android Native层读取内核节点信息需要结合Linux系统编程和JNI技术实现,具体步骤如下: ### 一、核心实现方法 1. **权限配置** - 内核节点文件通常位于`/dev`或`/sys`目录下 - 在`AndroidManifest.xml`中添加`android:sharedUserId="android.uid.system"`声明系统权限 - 设备需要签名或root权限才能访问部分敏感节点[^3] 2. **Native层文件操作** 使用Linux标准文件操作函数: ```c #include <fcntl.h> #include <unistd.h> JNIEXPORT jstring JNICALL Java_com_example_NodeAccess_readNodeFile( JNIEnv *env, jobject obj, jstring jPath) { const char *path = (*env)->GetStringUTFChars(env, jPath, 0); char buffer[256]; int fd = open(path, O_RDONLY); ssize_t count = read(fd, buffer, sizeof(buffer)-1); close(fd); (*env)->ReleaseStringUTFChars(env, jPath, path); return (*env)->NewStringUTF(env, buffer); } ``` 3. **JNI接口绑定** Java层声明native方法: ```java public class NodeAccess { static { System.loadLibrary("nodeaccess"); } public native String readNodeFile(String path); } ``` ### 二、关键注意事项 1. **线程安全** 建议在独立线程中执行I/O操作,避免阻塞UI线程 2. **错误处理** ```c if(fd < 0) { __android_log_print(ANDROID_LOG_ERROR, "NODE_ACCESS", "打开节点失败 errno=%d", errno); return NULL; } ``` 3. **缓冲区管理** 使用动态内存分配处理大数据: ```c char *buffer = malloc(MAX_SIZE); free(buffer); ``` ### 三、典型应用场景 1. 传感器数据读取(如`/dev/input/eventX`) 2. 系统状态监控(如`/sys/class/power_supply/battery/voltage_now`) 3. 硬件寄存器访问(需内核驱动支持)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值