【Linux驱动调试技巧】在SElinux 如何获得对一个内核节点的访问权限?

Android 5.0下,因为采取了SEAndroid/SElinux的安全机制,即使拥有root权限,或者对某内核节点设置为777的权限,仍然无法在JNI层访问。
本文将以用户自定义的内核节点/dev/wf_bt为例,手把手教会读者如何在JNI层获得对该节点的访问权限。

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

第二步:打开文件AndroidL/android/external/sepolicy/file_contexts.be 仿照这个文件里的写法,为你的节点定义一个你想要的名字:

在CODE上查看代码片派生到我的代码片

   /dev/tegra.* u:object_r:video_device:s0 
   /dev/tf_driver u:object_r:tee_device:s0 
   /dev/tty u:object_r:owntty_device:s0 
   /dev/tty[0-9]* u:object_r:tty_device:s0 
   # We add here 
   /dev/wf_bt u:object_r:wf_bt_device:s0 
wf_bt_device是自定义,其他左右两边的内容都和上面的范例一致。

第三步:打开文件AndroidL/android/external/sepolicy/device.te 仿照这个文件里的写法,将刚刚第二步写的wf_bt_device声明为dev_type:

在CODE上查看代码片派生到我的代码片

   # Device types 
   type device, dev_type, fs_type; 
   type alarm_device, dev_type, mlstrustedobject; 
   type adb_device, dev_type; 
   type ashmem_device, dev_type, mlstrustedobject; 
   type audio_device, dev_type; 
   type binder_device, dev_type, mlstrustedobject; 
   type block_device, dev_type; 
   # We add here 
   type wf_bt_device, dev_type; 

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

在CODE上查看代码片派生到我的代码片

   # Read/Write to /proc/net/xt_qtaguid/ctrl and and /dev/xt_qtaguid. 
   allow system_server qtaguid_proc:file rw_file_perms; 
   allow system_server qtaguid_device:chr_file rw_file_perms; 
     
   # chr_file表示字符设备文件,如果是普通文件用file,目录请用dir 
   # rw_file_perms代表读写权限 
   allow system_server wf_bt_device:chr_file rw_file_perms; 
这句话的意思是:允许system_server进程拥有对wf_bt_device的这个字符设备的读写权限。 改了这些之后,你就可以make installclean;make -j16编译image来验证权限是否获取成功。

fd =open("/dev/wf_bt",O_RDONLY | O_NOCTTY); 就可以成功访问了。

在framework写一个文件,比如:cache/hideapp.txt 但是在launcher2里是不能访问的,会报一个FileNotFoundException的异常。 这也是没权限访问的原因。 因此接下来就添加权限 在AndroidL/android/external/sepolicy/目录下, 首先在file_contexts里添加

/cache/hideapp.txt u:object_r:meig_pub_file:s0
然后再在file.te里添加

type meig_pub_file, file_type;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 Linux驱动与模块 1.1 Linux的模块 驱动程序为了与外设硬件进行交互,必须调用Linux内核提供的内存管理、文件系统等 多种功能函数。而用户态的程序只能通过系统调用来使用有限的内核功能,因此驱动程序在 linux系统中被安排在内核态运行,也即可以访问所有的内核功能。 但是为了把内核通用功能与这些驱动程序区分开来,Linux 通常要求驱动程序作为一个 模块(module)在内核空间运行,并且由内核进行管理。当然,实际上模块并非只能用来编写 驱动程序,模块可以作为任何一个独立的功能块,操作内核函数并通过特定接口向应用程序 提供服务。 1.2 模块的编写要求 模块的代码中,必须加入以下头文件,才能正确地引用模块机制的若干函数: #include <linux/module.h> #include<linux/init.h> 当然,如果编写的模块是驱动程序,则还需要加入与驱动程序相关的内存管理、设备注 册、中断管理等头文件。 模块与通常的应用程序不同,并没有一个main函数,而是一些相互作用的函数的集合。 当然,这些集合中必须有一个首先调用的初始化函数,以及一个退出函数。 初始化函数:在模块加载时被调用,负责申请并初始化模块运行时必须的数据结构,此 后这些结构有可能在模块存续期间一直存在。 退出函数:在模块卸载时被调用,卸载后模块内任何数据结构都不该继续存在,因此退 出函数必须仔细的把模块运行带来的所有数据结构释放掉,否则将会造成内存泄露。 为了使内核知道模块中初始化函数和退出函数的函数名,必须用以下两个宏来定义: module_init(s3c_ts_init); module_exit(s3c_ts_exit); 上例中s3c_ts_init被定义为模块的初始化函数,s3c_ts_exit被定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值