- 1:SELinux
- 1.1:SELinux mode
- 1.2:SELinux Policy文件路径
- 1.3:无权限时Log
- 2:解决问题
最近,需要在hardware的摄像头采集进程mtk_hal_camera中接入usb camera驱动,在接入libusb、libuvc完成后,发现在打开SELinux后,会出现不能初始化和不能找到设备等错误。本文将记录解决该问题的具体方法。
SELinux
Android 5.0以后完全引入了 SEAndroid/SELinux 安全机制,这样即使拥有 root 权限或 chmod 777 ,仍然无法访问内核节点。
SEAndroid 安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中,例如我们经常接触的文件就是分布文件子系统中的。实际上,系统中需要保护的资源非常多,除了前面说的文件之外,还有进程、socket 和 IPC 等等。对于 Android 系统来说,由于使用了与传统 Linux 系统不一样的用户空间运行时,即应用程序运行时框架,因此它在用户空间有一些特有的资源是需要特别保护的,例如系统属性的设置等,具体内容可以参考官网。
SELinux mode
SELinux 分为两种模式,Android 5.0 后所有进程都使用 enforcing mode。
- 宽容模式(permissive) - 仅记录但不强制执行 SELinux 安全政策。
- 强制模式(enforcing) - 强制执行并记录安全政策。如果失败,则显示为 EPERM 错误。
在开发过程中,为了开发效率,我们经常关闭SELinux进行开发,0为关闭1为打开:
adb shell setenforce 0
可以通过如下命令获取当前的状态:
adb shell getenforce
SELinux Policy文件路径
Google 原生目录
external/sepolicy
厂家目录,高通将 mediatek 换为 qcom
alps\device\mediatek\common\sepolicy
alps\device\mediatek\<platform \sepolicy
编译时将以合并的方式将厂家policy追加到Google原生。
无权限时Log
avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类型 permissive=0
在某个进程无操作某节点的权限时,会在Logcat中看到如上报错。
SELinux Sepolicy中添加权限
修改相应源类型.te文件(基本以源进程名命名),添加如下一行语句:
allow 源类型 目标类型:访问类型 {操作权限}; // 注意分号
解决问题
在接入Usb Camera时,需要访问/dev/bus/usb/*下的字符设备,由于该路径已经在file_contexts文件中定义过,如果是自己创建的新节点需要自己定义域和规则,参考官网。
/dev/bus/usb(.*)? u:object_r:usb_device:s0
在打开SELinux会看到如下信息:
avc: denied { ioctl } for path="/dev/bus/usb/001/003" dev="tmpfs" ino=55762 ioctlcmd=0x550d scontext=u:r:mtk_hal_camera:s0 tcontext=u:object_r:usb_device:s0 tclass=chr_file permissive=1
avc: denied { read } for name="devices" dev="sysfs" ino=18772 scontext=u:r:mtk_hal_camera:s0 tcontext=u:object_r:sysfs:s0 tclass=dir permissive=1
avc: denied { open } for path="/sys/bus/usb/devices" dev="sysfs" ino=18772 scontext=u:r:mtk_hal_camera:s0 tcontext=u:object_r:sysfs:s0 tclass=dir permissive=1
avc: denied { search } for name="usb" dev="tmpfs" ino=55061 scontext=u:r:mtk_hal_camera:s0 tcontext=u:object_r:usb_device:s0 tclass=dir permissive=0
我们可以根据上面的规则来在mtk_hal_camera.te中添加足够的权限:
# Allow cameraserver to talk to usb device
allow mtk_hal_camera usb_device:chr_file { open read write ioctl };
allow mtk_hal_camera usb_device:dir { search open read write ioctl };
allow mtk_hal_camera usb_device:file { read write getattr setattr open create };
allow mtk_hal_camera sysfs:chr_file { open read ioctl};
allow mtk_hal_camera sysfs:dir { search open read ioctl};
修改完成然后make installclean,重新编译后,在SELinux开启状态会如预料一样正常工作。
你的这个界面是怎么弄的阿?自己弄的?还是花钱的阿?