1、Linux用户权限
Linux 系统中采用三位十进制数表示权限,如0755, 0644。
ABCD
A-0, 表示十进制
B-用户
C-组用户
D-其他用户
权限 | 配置数字 | 含义 |
---|---|---|
— | 0 | (no excute , no write ,no read) |
–x | 1 | excute, (no write, no read) |
-w- | 2 | write |
-wx | 3 | write, excute |
r– | 4 | read |
r-x | 5 | read, excute |
rw- | 6 | read, write |
rwx | 7 | read, write , excute |
0755->即用户具有读/写/执行权限,组用户和其它用户具有读写权限;
0644->即用户具有读写权限,组用户和其它用户具有只读权限;
2、新增节点添加权限
(1)添加读、写、可执行权限
//device/mediatek/mtXXXX/init.mtXXXX.rcon boot
chmod 0777 /sys/devices/platform/1100f000.i2c3/i2c-3/3-005a/fm_speaker_switch
(2)添加节点的selinux权限
//关闭selinux
adb shell setenforce 0
(A)通过audit2allow来添加简单权限
通过avc来查看selinux权限:adb logcat | grep avc
如:
I FmRadioServiceT: type=1400 audit(0.0:1339): avc: denied { getattr } for path="/sys/devices/platform/1100f000.i2c3/i2c-3/3-005a/fm_speaker_switch" dev="sysfs" ino=32552 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.android.fmradio
通过audit2allow来添加简单权限
adb shell "cat /proc/kmsg | grep avc" > avc.txt
audit2allow -i avc.txt
如:
#============= priv_app ==============
allow priv_app system_file:file execmod;
(B)添加neverallow的avc权限
以如下这个权限为例:
I FmRadioServiceT: type=1400 audit(0.0:1339): avc: denied { getattr } for path="/sys/devices/platform/1100f000.i2c3/i2c-3/3-005a/fm_speaker_switch" dev="sysfs" ino=32552 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1 app=com.android.fmradio
怎么通过查看avc log 来添加selinux权限?主要看以下几个属性:
denied { getattr } ,path=?, dev="sysfs", scontext ,tcontext, tclass.
(a)在device/mediatek/sepolicy/basic/non_plat/file.te中添加文件类型(根据需求添加type)。
type xxx_fm_radio, fs_type, sysfs_type, mlstrustedobject;
备注:从12.0开始如果在platform_app中使用,在avc log中的scontext属性中有c512、c768,则要加上mlstrustedobject。
(b)在device/mediatek/sepolicy/basic/non_plat/file_contexts中添加如下内容。
/sys/devices/platform/1100f000.i2c3/i2c-3/3-005a/fm_speaker_switch u:object_r:xxx_fm_radio:s0
(c)对应app的te文件添加权限(platform_app、system_app、untrusted_app、radio、service)。
在device/mediatek/sepolicy/basic/non_plat/ platform_app.te文件中添加,具体在哪个te文件中添加,可以查看avc log中的scontext属性,比如例子中的scontext=u:r:platform_app:s0:c512,c768,就应该在platform中添加。
allow platform_app xxx_fm_radio:file { write read getattr open };
(3)确认添加那种权限
(A)确认节点路径是否为有效路径
这是驱动提供的节点路径:sys/bus/i2c/drivers/aw36515/5-0063/onoff
adb shell 进入手机内,然后进入sys目录直接find此节点,得到的路径为该节点实际路径,如果跟驱动提供的不一样,以find到的路径为准,操作如下
XXX:/sys # find -name onoff
./devices/platform/soc/11005000.i2c6/i2c-6/6-0063/onoff
(B)确认需要添加哪些权限
目前遇到的最多需要添加三种权限:avc权限、chmod权限、chown权限,默认所有新增节点都是需要avc权限,所以只需确认手否需要添加另两种权限。
通过第一步拿到有效节点路径后,通过手动操作此节点来确认需要哪些权限,然后再添加权限代码,这样一次就可以加上所有权限:
Unlock后 adb root adb shell 然后cd到节点路径,首先查看节点值:
XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # cat onoff
0
默认值为0,写为1即为打开状态,然后手动写节点值:
XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # echo 1 > onoff
/system/bin/sh: can't create onoff: Permission denied
如果写入成功,说明只需要avc权限;结果为上面显示就说明需要添加chmod权限,直接手动添加:
XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # chmod 666 onoff
然后再次手动写入:
XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # echo 1 > onoff
如果还是未能写入成功,说明还需要chown权限,继续手动写入
XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # chown system:system onoff(说明:system,radio,root都可以)XXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # ls -lZ
-rwxrwxrwx 1 system system u:object_r:sysfs:s0 4096 2023-02-09 04:52 onoffXXX:/sys/devices/platform/soc/11005000.i2c6/i2c-6/6-0063 # echo 1 > onoff
这时候应该就可以写入成功,即可判断需要哪些权限。
(C)添加权限
(a)selinux权限添加
设置Permissive模式后(adb shell setenforce 0),运行读取此节点的上层代码,adb logcat|grep avc即可查出所有需要添加的selinux权限,具体添加方法参考前面说明。
(b)chmod权限/chown权限
在device/mediatek/mtXXXX/init.mtXXXX.rc
chmod 0666 /sys/devices/platform/soc/11016000.i2c5/i2c-5/5-0063/onoff
chown system system /sys/devices/platform/soc/11016000.i2c5/i2c-5/5-0063/onoff
(D)读写节点代码
//读节点
public static String getFileString(String path){String version = null;try {FileReader fr = new FileReader(path);BufferedReader br = new BufferedReader(fr);String readString = null;while ((readString = br.readLine())!=null){if(readString == null)break;version = readString;}br.close();} catch (Exception ex) {Log.e("CampingLight","Exception ex="+ex);return null;}return version;}//写节点
private void writeFile(String path, String value) {try {FileOutputStream outputStream = new FileOutputStream(path);outputStream.write(value.getBytes());outputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();Log.e("CampingLight", "file not found, error = " + e.toString());} catch (IOException e) {e.printStackTrace();Log.e("CampingLight", "io error, error = " + e.toString());}}