SEAndroid 解决案例
来源:互联网 发布:什么软件有耽美动漫 编辑:程序博客网 时间:2024/04/30 06:24
都是从网络上摘抄的总结下来备用,有些链接丢失了
通过system server service 或者 init 启动的service 读写, 然后app 通过binder/socket 等方式连接APP 访问. 此类安全可靠, 并且可以在service 中做相关的安全审查, 推崇这种方法.
自Android L版本,Google对源码环境普遍启用SELinux安全访问机制,APP及framework层默认情况下再无权限访问设备节点如(sys/xxx,proc/xxx)
下面以三种常用操作角度阐述为system app进程或system server进程开放权限的方法
1) SEAndroid 为sys设备文件结点开放访问(读或写)权限的方法(如:/sys/class/leds/green/brightness)
2) SEAndroid 为proc设备文件结点开放访问(读或写)权限的方法(如:/proc/touchscreen_feature/gesture_data)
3) SEAndroid 为SystemProperties的自定义属性开放set(写)权限的方法
一、 SEAndroid 为sys设备文件结点开放访问(读或写)权限的方法 (如:/sys/class/leds/green/brightness)
如绿灯:/sys/class/leds/green/brightness,为APP层system app进程开放该节点访问权限(读或写)
/sys/class/leds/green/brightness //快捷方式/sys/devices/soc.0/gpio-leds.66/leds/green/brightness //实际节点
MTK:alps/device/mediatek/common/sepolicy
QCOM:android/device/qcom/sepolicy/common
1.1 在android/device/qcom/sepolicy/common/file.te,定义selinux type:sysfs_wingtk_leds,如下:
type sysfs_wingtk_leds, fs_type, sysfs_type;
1.2 在android/device/qcom/sepolicy/common/file_contexts,绑定sysfs_wingtk_leds到对应的实际节点,注意是实际节点
获取实际节点可以通过 , ll -Z 命令就可以查到。
root@K31-t7:/sys/class/leds # ll -Zlrwxrwxrwx root root u:object_r:sysfs:s0 flashlight -> ../../devices/soc.0/flashlight.64/leds/flashlightlrwxrwxrwx root root u:object_r:sysfs:s0 green -> ../../devices/soc.0/gpio-leds.66/leds/greenlrwxrwxrwx root root u:object_r:sysfs:s0 lcd-backlight -> ../../devices/soc.0/1a00000.qcom,mdss_mdp/qcom,mdss_fb_primary.124/leds/lcd-backlightlrwxrwxrwx root root u:object_r:sysfs:s0 mmc0:: -> ../../devices/soc.0/7824900.sdhci/leds/mmc0::lrwxrwxrwx root root u:object_r:sysfs:s0 mmc1:: -> ../../devices/soc.0/7864900.sdhci/leds/mmc1::lrwxrwxrwx root root u:object_r:sysfs:s0 red -> ../../devices/soc.0/gpio-leds.66/leds/redlrwxrwxrwx root root u:object_r:sysfs:s0 torch-light0 -> ../../devices/soc.0/qcom,camera-led-flash.65/leds/torch-light0root@K31-t7:/sys/class/leds #
/sys/devices/soc.0/gpio-leds.66/leds/green/brightness u:object_r:sysfs_wingtk_leds:s0/sys/class/leds/green/brightness u:object_r:sysfs_wingtk_leds:s0PS:可以把/sys/class/leds/green/brightness也声明下,该句不是必须的:
1.3 在android/device/qcom/sepolicy/common/system_app.te,申请权限:
allow system_app sysfs_wingtk_leds:file rw_file_perms;
PS:也可以为其他process申请相关的权限,如:system_server,在android/device/qcom/sepolicy/common/system_server.te
allow system_server sysfs_wingtk_leds:file rw_file_perms;
1.4 在AndroidManifest.xml,配置:android:sharedUserId=”android.uid.system”,该步时必须的,因为第三步是:
allow system_app sysfs_wingtk_leds:file rw_file_perms; //仅允许system_app进程访问.
经过以上四步,APP层就可以正常读写:/sys/class/leds/green/brightness为了更好地控制访问权限,如果存在APP层和framework层都要访问某个设备节点,笔者认为最好以此式来访问设备节点,即不让system_app进程访问,仅仅允许system_server进程来访问,如
allow system_server sysfs_wingtk_leds:file rw_file_perms;
缺点:
需要在framework层添加随系统启动的service,增加代码量
优点:
1.可以自由控制哪些应用可以访问,哪些应用禁止访问已经开放的设备节点,可以更好的保护安全问题
2.framework层和APP层都可以访问该设备节点.不用再另外进行权限申请
二、 proc设备文件结点开放访问(读或写)权限的方法(如:/proc/touchscreen_feature/gesture_data),以MTK平台为例
2.1在alps/mediatek/common/sepolicy/file.te 定义selinux type: proc_quick_gesture,如下:
type proc_quick_gesture, fs_type;
2.2在 alps/mediatek/common/sepolicy/genfs_contexts,绑定proc_quick_gesture到对应的实际节点
genfscon proc /touchscreen_feature/gesture_data u:object_r:proc_quick_gesture:s0
2.3 在alps/mediatek/common/sepolicy/common/system_app.te,申请权限
2.4 AndroidManifest.xml,配置:android:sharedUserId=”android.uid.system”, 设置为system_app进程就具备权限(读或写)访问/proc/touchscreen_feature/gesture_data等节点啦
三、 SystemProperties的自定义属性开放set(写)权限的方法( 问题描述 SystemProperties对自定义属性没有写权限,即set时提示没有权限,导致写不成功)
以”persist.backgrounddata.enable”为例介绍开放属性权限方法
以QCOM平台为例3.1 android/device/qcom/sepolicy/common/property.te type persist_backgrounddata_prop, property_type;3.2 android/device/qcom/sepolicy/common/property_contexts persist.backgrounddata.enable u:object_r:persist_backgrounddata_prop:s03.3 android/device/qcom/sepolicy/common/system_app.te,为system_app进程开放权限 allow system_app persist_backgrounddata_prop:property_service set;3.4 在AndroidManifest.xml,配置:android:sharedUserId="android.uid.system"
代码中就可以使用SystemProperties.set(“persist.backgrounddata.enable”“, xx)设置属性了。
延伸阅读
如果通过以上步骤正确配置之后,你仍没有权限读写sys或proc节点,是不是DAN都碎了。再告诉你下,你需要到init.rc里面配置: chown system system 文件结点,然后chmod下文件结点。两个平台配置路径,项目不同略有差异
MTK:alps/device/mediatek/mt6735/init.mt6735.rc
QCOM:xx/xx/init.target.rc
四、 SEAndroid 访问 dev 节点
1. 首先确定需要访问该内核节点的进程(process),目前为我们是用 system_server访问 2. 打开文件AndroidL/android/external/sepolicy/file_contexts.be /dev/wf_bt u:object_r:wf_bt_device:s0 wf_bt_device是自定义,其他左右两边的内容都和上面的范例一致。 3.:打开文件AndroidL/android/external/sepolicy/device.te 仿照这个文件里的写法,将刚刚第二步写的wf_bt_device声明为dev_type: type wf_bt_device, dev_type; 4.AndroidL/android/external/sepolicy/目录下很多.te文件都是以进程名来结尾的,比如有针对surfaceflinger进程的surfaceflinger,有针对vold进程的vold.te, 刚刚从第一步得到,这个节点是由system_server进程来访问,所以,我们找到system_server.te打开,加入允许这个进程对/dev/wf_bt的读写权限, 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);
五、为执行脚本进程添加权限
http://blog.csdn.net/jiuxiaoyunwu/article/details/51220477
5.1 init.rc 或者 其他 init.project.rc
on post-fs-data //在此节点下添加如下代码 chmod 0777 /system/bin/cloudtestsuited on init // 在此节点下添加如下代码 service cloudtestsuited /system/bin/cloudtestsuited class main oneshot disabled 或者可以在init.rc中在声明service 前 添加一行代码,on property:sys.service.silead=enabled然后再apk中就可以执行如下代码,前提是apk具有platform签名,system权限
oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在–如果可执行程序被杀死,则会重新启动。
disabled 表示禁用服务,此服务开机时不会自动启动,但是可以在应用程序中手动启动它。
5.2添加对应的selinux权限
在device\mediatek\common\sepolicy\file_contexts 文件中添加bin服务对应的权限:
/system/bin/cloudtestsuited u:object_r:fpsvcd_exec:s0 //此行设定所属域
5.3 在device\mediatek\common\sepolicy\system_app.te 文件中添加bin服务对应的权限,
允许系统 app do:add for fp.apk create file under ‘/data/silead/’ file path
allow system_app fpsvcd_data_file:dir { create write add_name remove_name read open search}; allow system_app fpsvcd_data_file:file { unlink getattr create write open read }; add for starting cloudtestsuited in apk allow system_app fpsvcd_tmpfs:file { read write open getattr }; allow system_app fpsvcd_exec:file { getattr read execute open execute_no_trans }; allow system_app fpsvcd:dir { read open }; allow system_app tmpfs:dir { read write getattr };
5.4 在device\mediatek\common\sepolicy\ 目录下新增一个权限文件fpsvcd.te:
type fpsvcd_exec , exec_type, file_type; type fpsvcd ,domain; init_daemon_domain(fpsvcd) ......
5.5 启动服务
SystemProperties.set("sys.service.silead","enabled"); 或者 private void startCloudServer() { new Thread(new Runnable() { @Override public void run() { try { Log.v(Const.TAG_LOG, TAG + " startCloudServer->getRuntime cloudtestsuited"); //String[] cmd = new String[] { "su", "-c", "cloudtestsuited" }; String[] cmd = new String[] { "sh", "-c", "cloudtestsuited" }; //Process proc = Runtime.getRuntime().exec(cmd); //proc.waitFor(); excuteCmd_multiThread(cmd); } catch (Exception e) { Log.e(Const.TAG_LOG, TAG + " startCloudServer occurs exception, ", e); } try { Log.v(Const.TAG_LOG, TAG + " startCloudServer->SystemProperties cloudtestsuited"); //SystemProperties.set("ctl.start", "ztstartsileadcloudtest"); } catch (Exception e) { Log.e(Const.TAG_LOG, TAG + " startCloudServer occurs exception, ", e); } } }).start(); } private void excuteCmd_multiThread(String[] cmd) { try { Process proc = Runtime.getRuntime().exec(cmd); Thread errorThread = new Thread(new InputStreamRunnable( proc.getErrorStream(), "ErrorStream")); errorThread.start(); Thread outputThread = new Thread(new InputStreamRunnable( proc.getInputStream(), "OutputStream")); outputThread.start(); proc.waitFor(); } catch (InterruptedException e) { Log.e(Const.TAG_LOG, TAG + " excuteCmd_multiThread occurs InterruptedException, ", e); } catch (IOException e) { Log.e(Const.TAG_LOG, TAG + " excuteCmd_multiThread occurs IOException, ", e); } } private class InputStreamRunnable implements Runnable { BufferedReader bReader = null; String type = null; public InputStreamRunnable(InputStream is, String typeCode) { try { type = typeCode; bReader = new BufferedReader(new InputStreamReader( new BufferedInputStream(is), "UTF-8")); } catch (Exception e) { Log.e(Const.TAG_LOG, TAG + " InputStreamRunnable occurs exception, ", e); } } @Override public void run() { String line; int lineNum = 0; try { while ((line = bReader.readLine()) != null) { if ("ErrorStream".equals(type)) { Log.e("FpCloudServer ERROR", line); } else if ("OutputStream".equals(type)) { Log.i("FpCloudServer Output", line); } else { Log.v("FpCloudServer debug", line); } lineNum++; } if (bReader != null) { bReader.close(); } } catch (Exception e) { Log.e(Const.TAG_LOG, TAG + " InputStreamRunnable run occurs exception, ", e); } } }
六、 recovery 操作 download 目录
6.1 recovery.te 中的定义
neverallow recovery data_file_type:file { no_w_file_perms no_x_file_perms }; neverallow recovery data_file_type:dir no_w_dir_perms;
6.2我们再来看下system_data_file在file_contexts.te中的定义
/data(/.*)? u:object_r:system_data_file:s0
6.3 而在file.te定义了system_data_file文件属于data_file_type类型,因此recovery也是不能操作data下面的文件
file.te:56:type system_data_file, file_type, data_file_type;
6.4 解决办法:在我们可以自己定义自己的file类型,我们可以定义data/download属于download_data_file类型
(1) filecontext.te 定义/data/download(/.*)? u:object_r:download_data_file:s0 (2)然后在file.te中定义download_data_file类型 type download_data_file, file_type; (3) 然后在recovery.te中增加对download_data_file的权限allow recovery download_data_file:dir { write search remove_name }; allow recovery download_data_file:file { read getattr unlink }; (4)另外我们还需在一个systemapp中先下载升级包,所以需要在system_app.te中增加对如下权限:allow system_app download_data_file:dir { search write add_name getattr remove_name }; allow system_app download_data_file:file { create read write open getattr unlink }; (5)但是最后还是失败了,为什么呢,因为一开始没有data/download这个目录,而是我们再app中自己下载的时候创建的目录,所以是system_data_file类型的。那么我们就需要在一开始就有data/download目录,所以在init.rc中添加如下代码:mkdir /data/download 0771 system system (6)最后我们还需要在uncrypt.te中增加如下,因为data目录有可能需要进行加密处理。allow uncrypt download_data_file:dir { search getattr }; allow uncrypt download_data_file:file { getattr read open };
七、添加 device type 操作
http://blog.csdn.net/lushengchu_luis/article/details/52775740
无意中看到网上这篇文章,在device.te加入type serial_device, dev_type, mlstrustedobject;这一行,问题迎刃而解
第三方签名APP,在SElinux下,如何获得对一个内核节点的访问权限
在android6.0中,出于安全考虑,不允许第三方签名的app被分配mlstrustedsubject:
7.1 在external/sepolicy/untrusted_app.te文件中:
# Do not allow untrusted_app to be assignedmlstrustedsubject.# This would undermine the per-user isolation model being# enforced via levelFrom=user in seapp_contexts and the mls# constraints. As there is no direct way tospecify a neverallow# on attribute assignment, this relies on the fact that fork# permission only makes sense within a domain (hence should# never be granted to any other domain withinmlstrustedsubject)# and untrusted_app is allowed fork permission to itself.neverallow untrusted_app mlstrustedsubject:process fork;
7.2 所以在使用第三方签名app时,希望第三方签名app某个进程能够对内核节点进行操作,可按如下修改:
1.在device/sprd/scx20/common/sepolicy/file_contexts 文件中添加:/dev/abc u:object_r:abc_device:s0 2.在device/sprd/scx20/common/sepolicy/device.te 文件中添加:type abc_device, dev_type, mlstrustedobject;
7.3 在device/sprd/scx20/common/sepolicy/untrusted_app.te 文件中添加:
allow untrusted_app adc_device:chr_fileoperate;
operate为赋予的权限。
注:
mlstrustedsubject:这一attribute包含了所有能越过MLS检查的主体domain。
mlstrustedobject:这一attribute包含了所有能越过MLS检查的客体type。
- SEAndroid 解决案例
- SEAndroid 解决案例
- SEAndroid
- 如何排查并解决SEAndroid 的审计不通过
- librarycachelock的解决案例
- 解决内存泄漏案例
- seandroid初始化
- seandroid官网
- SEAndroid策略
- SEAndroid概述
- 激活SEAndroid
- SEAndroid策略
- SEAndroid策略
- SEAndroid策略
- SEAndroid策略
- SEAndroid简介
- SEAndroid策略
- SEAndroid架构
- Camera Path Animator
- MATLAB数字图像处理基本概念及图像文件读取
- 把某个js时间转化为几天前,几小时前,几分钟前
- java中的异常处理机制
- 九度OJ-题目1034 寻找大富翁
- SEAndroid 解决案例
- [模拟](JZOJ)【普及模拟】蚂蚁
- Spring mvc interceptor拦截器
- 矩阵的链乘 (动态规划)
- Java中的存储过程
- 小米6渲染图曝光 边框惊艳 国产曲面旗舰要发黑色版
- mysql的建表规范
- iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
- CSS字体水平垂直居中