首先确定权限类型详见各个判定方法
- selinux
- 驱动节点权限
- linux capabillty权限
selinux处理思路
判定方案
查询tag:avc或者selinux的报错信息 譬如:
[com][2021/08/06][17:43:55-557]01-01 08:00:19.616 3244 3244 D MTK_KL : 38,3858,35335082,-;type=1400 audit(1577836819.607:1976): avc: denied { ioctl } for pid=2946 comm=6C69676874446576696365206D616E path="/dev/mik!iic" dev="tmpfs" ino=10505 ioctlcmd=0x1d05 scontext=u:r:jasdemo:s0 tcontext=u:object_r:mstar_mik_iic_device:s0 tclass=chr_file permissive=1
解决方法
step1. 先关闭selinux cmd :setenforce 0 确定是否功能正常
step2. 在对应的te文件中添加
如上avc报错例子在jasdemo.te中添加
allow jasdemo mstar_mik_iic_device:chr_file { ioctl read write open };
规则allow scontext tcontext:tclass {denied }
step3.编译selinux
mmm system/sepolicy
step4
编译通过
将下列文件替换至机器中重启测试,如果有问题则继续观察是否还缺少其他权限
out/target/product/xxx/system/etc/selinux
out/target/product/xxx/vendor/etc/selinux
未编译通过
确认失败原因,目前有遇到的
- te文件内容出错,原因是te文件结尾缺少回车,导致与下一个te文件重合,可以查看对应的vendor(system)/etc/selinux下的.cil文件,加的selinux是否出现此问题
- 可find关键词 neverallow看是否违反规则,如果违反说明该scontext对tcontext没有权限
查看scontext/tcontext可以用命令ls -Z在机器中查询。
如果遇到此问题,可以通过更改成不违反neverallow的context解决
修改文件在对应的contexts中,如在property_contexts中更改某个prop
persist.vendor.xxx u:object_r:powerctl_prop:s0
根据经验powerctl_prop的权限大部分scontext都可以拿到,满足中间件和app同时控制的要求
如果无法找到解决neverallow的方法则建议更改流程方案
驱动节点权限
判定方案
简单来说就是在中间层(硬件抽象层)(hal)open ioctl等操作节点失败。可以通过以下方法确认是否是该问题对节点chmod 777 如chmod 777 /dev/video0
后节点可以正常打开就是该问题
解决方法
step1和基本信息
首先可以通过ls-l命令确认节点权限,如
crwx------ 1 root root 4, 64 2020-01-01 08:00 ttyS0
其中第一个字符为设备类型 b为块设备 c为字符设备 d目录,
后面的9位rw-------为其权限,r代表具有可读权限; w代表具有可写权限;x代表具有可执行权限,-为无权限。其中每三个为一组rwx,其次为
u: User,即文件或目录的拥有者;
g: Group,即文件或目录的所属群组;
o: Other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围;
从上可以得到,上述ttyS0是一个字符设备,拥有者有全部权限,而Group和Other都无权限
chmod命令简介
chmod后面的777就依次是ugo权限,其中:
r: 读取权限,数字代号为“4”;
w: 写入权限,数字代号为“2”;
x: 执行或切换权限,数字代号为“1”;
-:不具任何权限,数字代号为“0”;
所以chmod 777就是给了全部的权限,而正常解决的时候,肯定不能这么做,other的权限太高会导致系统不安全
或者也可以通过chown命令完成 chown 格式是 选项 用户:组 文件
step2解决问题
方法一:
更改主动调用设备的user或group
在对应service的启动文件中修改user或group满足被调接口给出的权限
service jasdome /vendor/bin/jasdome
user root
group system root media audio drmrpc camera inet
capabilities DAC_READ_SEARCH
方法二:
修改被调用节点的权限
- 在driver节点创建时候修改,如static struct attribute
.mode = 0666
等 - 在user空间通过
chmod(path,0664);或chown()
直接修改底层节点权限组
capabillty权限
简介
在以往的UNIX系统上,为了做进程的权限检查,把进程分为两类:特权进程(有效用户ID是0)和非特权进程(有效用户ID是非0)。特权进程可以通过内核所有的权限检查,而非特权进程的检查则是基于进程的身份(有效ID,有效组及补充组信息)进行。
从linux内核2.2开始,Linux把超级用户不同单元的权限分开,可以单独的开启和禁止,称为能力(capability)。可以将能力赋给普通的进程,使其可以做root用户可以做的事情。
此时内核在检查进程是否具有某项权限的时候,不再检查该进程的是特权进程还是非特权进程,而是检查该进程是否具有其进行该操作的能力。例如当进程设置系统时间,内核会检查该进程是否有设置系统时间(CAP_SYS_TIME)的能力,而不是检查进程的ID是否为0;
判定方法
可以通过** 查询tag:avc或者selinux的报错信息**得知
但是注意的是不能通过修改te文件来解决否者会一直报neverallow
典型的报错
denied { READ_SEARCH } scontext=u:r:jasdemo:s0 tcontext=u:object_r:jasdemo:s0 tclass= capabilltypermissive=1
解决方法
在在对应service的启动文件中修改capabilities
如:
service jasdome /vendor/bin/jasdome
user root
group system root media audio drmrpc camera inet
capabilities DAC_READ_SEARCH
下面是capability.h定义的全部capability
#define CAP_CHOWN 0
#define CAP_DAC_OVERRIDE 1
#define CAP_DAC_READ_SEARCH 2
#define CAP_FOWNER 3
#define CAP_FSETID 4
#define CAP_FS_MASK 0x1f
#define CAP_KILL 5
#define CAP_SETGID 6
#define CAP_SETUID 7
#define CAP_SETPCAP 8
#define CAP_LINUX_IMMUTABLE 9
#define CAP_NET_BIND_SERVICE 10
#define CAP_NET_BROADCAST 11
#define CAP_NET_ADMIN 12
#define CAP_NET_RAW 13
#define CAP_IPC_LOCK 14
#define CAP_IPC_OWNER 15
#define CAP_SYS_MODULE 16
#define CAP_SYS_RAWIO 17
#define CAP_SYS_CHROOT 18
#define CAP_SYS_PTRACE 19
#define CAP_SYS_PACCT 20
#define CAP_SYS_ADMIN 21
#define CAP_SYS_BOOT 22
#define CAP_SYS_NICE 23
#define CAP_SYS_RESOURCE 24
#define CAP_SYS_TIME 25
#define CAP_SYS_TTY_CONFIG 26
#define CAP_MKNOD 27
#define CAP_LEASE 28
#define CAP_AUDIT_WRITE 29
#define CAP_AUDIT_CONTROL 30
#endif