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。

1 0
原创粉丝点击