zoukankan      html  css  js  c++  java
  • android中SELINUX规则分析和语法简介【转】

    本文转载自:https://blog.csdn.net/LoongEmbedded/article/details/62430039

    1. SELINUX是可以理解为一种Android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统
    我们可以通过配置SELINUX的相关policy,来定制自己的手机的一些权限,比如,我们可以完全让root用户没有任何的权限和user一样
    2. 在android里面,有两个类型,一种是文件,一种是进程。
       针对这两种类型,我们可以先来看看他们的不同。
       在android上面,adb shell之后进入手机,ps -Z可以查看当前进程所拥有的selinux的权限。

       举例:

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. LABEL                          USER     PID   PPID  NAME  
    2. u:r:init:s0                    root      1     0     /init  
    3. u:r:kernel:s0                  root      2     0     kthreadd  
    4. ...  
    5. u:r:kernel:s0                  root      258   2     irq/322-HPH_R O  
    6. u:r:logd:s0                    logd      259   1     /system/bin/logd  
    7. u:r:healthd:s0                 root      260   1     /sbin/healthd  
    8. u:r:lmkd:s0                    root      261   1     /system/bin/lmkd  
    9. u:r:servicemanager:s0          system    262   1     /system/bin/servicemanager  
    10. u:r:vold:s0                    root      263   1     /system/bin/vold  
    11. u:r:surfaceflinger:s0          system    264   1     /system/bin/surfaceflinger  
    12. u:r:tctd:s0                    root      265   1     /system/bin/tctd  
    13. u:r:rfs_access:s0              system    268   1     /system/bin/rfs_access  
    14. u:r:tee:s0                     system    271   1     /system/bin/qseecomd  
    15. u:r:kernel:s0                  root      280   2     kworker/3:1H  
    16. u:r:kernel:s0                  root      290   2     kauditd  
    17. u:r:rmt_storage:s0             nobody    291   1     /system/bin/rmt_storage  
    18. u:r:shell:s0                   shell     292   1     /system/bin/sh  
    19. u:r:netd:s0                    root      295   1     /system/bin/netd  
    20. u:r:debuggerd:s0               root      296   1     /system/bin/debuggerd  
    21. u:r:tee:s0                     system    297   271   /system/bin/qseecomd  

        在这个例子中,我们可以进行分析。
        在android中,只定义了一个user即为u. 另外,如果是进程的话,都会统一定义为r,如果是文件的话,会被定义为object_r. 第三个是这个进程type,在andorid里面,定义了100多个type.按照目前我的理解,这个是进程所属的>类型。第四个是s0,这个是一个安全的等级。但是暂时还没有接触到配置这个的地方。

        另外就是文件,文件想要查看相关SELINUX权限的话,需要去执行ls -Z

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. drwxr-x--x root     sdcard_r          u:object_r:rootfs:s0 storage  
    2. drwx--x--x root     root              u:object_r:tmpfs:s0 synthesis  
    3. dr-xr-xr-x root     root              u:object_r:sysfs:s0 sys  
    4. drwxr-xr-x root     root              u:object_r:system_file:s0 system  
    5. drwxrwxr-x system   tctpersist          u:object_r:tct_persist_file:s0 tctpersist  
    6. lrwxrwxrwx root     root              u:object_r:rootfs:s0 tombstones -> /data/tombstones  
    7. -rw-r--r-- root     root              u:object_r:rootfs:s0 ueventd.qcom.rc  
    8. -rw-r--r-- root     root              u:object_r:rootfs:s0 ueventd.rc  

        在这个例子中,结合上面的分析,我们知道了object_r是代表的文件,u是android的唯一的用户,rootfs是这个文件所对应的类型,s0是一个安全的等级限制。

    3. 如何配置selinux
       首先,按照Google的官方文档:
       需要linux内核首先是支持selinux的,另外需要android的selinux的配置文件,也就是extern/sepolicy里面的内容。
       然后就是修改BoardConfig.mk
       Google的nexus的sepolicy的支持就放在了device/lge/mako/sepolicy
       首先会包含厂商定制的sepolicy的文件夹:BOARD_SEPOLICY_DIRS
       然后将规则添加到了sepolicy中:BOARD_SEPOLICY_DIRS

      这样的话,我们编译出来的image其实就是具有了selinux的功能。
      其实如果没有厂商定制的话,也是会编译到external/sepolicy的,这样的话,就是使用andriod所有默认的sepolicy(It defines the domains and types for the AOSP services and apps common to all devices. )

        然后理解了这个之后,我们可以看到其实很多的厂商也是有自己的配置规则在device/***/***/sepolicy下面的.

    4. selinux的配置规则:
       首先要了解sepolicy的结构:
       a. App进程 -> mac_permissions.xml
       b. App数据文件 -> seapp_contexts
       c. 系统文件  ->  file_contexts
       d. 系统属性 -> property_contexts

       在te文件中,我们一般遇到的语法是这样的:
       rule_name source_type target_type:class perm_set
       解读为: 为source_type设置一个rule_name的规则,规则是对target_type的class 进行 perm_set的操作。

       然后是一些特殊的配置文件:
       a. external/sepolicy/attributes -> 所有定义的attributes都在这个文件
       b. external/sepolicy/access_vectors -> 对应了每一个class可以被允许执行的命令
       c. external/sepolicy/roles  -> Android中只定义了一个role,名字就是r,将r和attribute domain关联起来
       d. external/sepolicy/users  -> 其实是将user与roles进行了关联,设置了user的安全级别,s0为最低级是默认的级别,mls_systemHigh是最高的级别
       e. external/sepolicy/security_classes -> 指的是上文命令中的class,个人认为这个class的内容是指在android运行过程中,程序或者系统可能用到的操作的模块
       f. external/sepolicy/te_macros -> 系统定义的宏全在te_macros文件
       g. external/sepolicy/***.te  -> 一些配置的文件,包含了各种运行的规则

       另外,selinux有两种工作模式:
        “permissive”:所有操作都被允许(即没有MAC),但是如果有违反权限的话,会记录日志
        “enforcing”:所有操作都会进行权限检查

       最后,type的命令如下:
       type type_id [alias alias_id,] [attribute_id]   # 将type_id(别名为alias)关联到attribute. 这样的话,方便用attribute来管理不同的type中包含相同的属性的部分。

       class命令的格式为:
       class class_name [ inherits common_name ] { permission_name ... }
       inherits表示继承了common定义的权限,然后自己额外实现了permission_name的权限

       在te文件中常见的四种命名的规则:
       allow:赋予某项权限。
       allowaudit:audit含义就是记录某项操作。默认情况下是SELinux只记录那些权限检查失败的操作。allowaudit则使得权限检查成功的操作也被记录。注意,allowaudit只是允许记录,它和赋予权限没关系。赋予权限必须且只能使
    用allow语句。
       dontaudit:对那些权限检查失败的操作不做记录。
       neverallow:前面讲过,用来检查安全策略文件中是否有违反该项规则的allow语句。如例子5所示:

       举例:

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. type init, domain;  

       将init关联到domain,即将domain设置为init类型的属性

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow init unlabeled:filesystem mount;  

       允许init类型对unlabeled类型的filesystem进行mount的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow init fotad:unix_stream_socket { bind create };  

       允许init类型对fotad类型的unix_stream_socket 进行bind和create的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow appdomain anr_data_file:dir search;  
    2. allow appdomain anr_data_file:file { open append };  

       首先appdomain是定义在te_macros里面的一个宏,很多的app规则会使用类似app_domain(shell)的命令将其添加进去
       这两句话的意思是:1. 允许app去对anr_data_file类型的目录进行查找的操作
       2. 允许app对anr_data_file类型的file进行打开和添加操作   其实就是规定了出现anr时候,app往/data/anr/里面写入的权限限制

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. neverallow { appdomain -unconfineddomain } kmem_device:chr_file { read write };  

       绝对不允许app(除了有unconfineddomain属性的app)对kmem_device类型的字符设备进行读写的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. neverallow { appdomain -unconfineddomain } self:capability2 *;  

       绝对不允许除了unconfineddomain以外的app对self类型的capability2进行任何的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. type httpd_user_content_t, file_type, httpdcontent;  

        声明一个httpd_user_content_t的类型,具有file_type和httpdcontent的属性

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. type httpd_user_content_t;  
    2. typeattribute httpd_user_content_t file_type, httpdcontent;  

       声明一个httpd_user_content_t的类型
       定义httpd_user_content_t具有file_type, httpdcontent的属性

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow appdomain self:rawip_socket create_socket_perms;  

       所有可以设置类型的地方其实都可以设置为属性。
       比如这个例子,我们允许所有具有app属性的内容可以去对self属性的rawip_socket进行create的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow {user_t domain} {bin_t file_type sbin_t}:file execute ;  

       允许user_t和domain属性的类对bin_t, file_type, sbin_t类型的file进行可执行的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow user_t user_t:process signal;  
    2. allow user_t self:process signal;  

       这两条语句的表述其实是一致的,其实self指的是目标的类型和发起人的类型是一致的
       所以不能声明一个类型或者属性叫做self

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. allow user_t bin_t:file ~{ write setattr ioctl };  

       允许user_t对bin_t类型的file进行除了write setattr ioctl相关的操作

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    1. type_transition system wifi_data_file:sock_file system_wpa_socket;  

       当一个类型为system的类别去进行wifi_data_file类型的sock_file访问时,类型默认切换到system_wpa_socket

       如果下面这条语句想要执行成功
       type_transition init_t apache_exec_t:process apache_t;
       至少首先声明下面的三条规则:
       allow init_t apache_exec_t:file execute;
       allow init_t apache_t:process transition;
       allow apache_t apache_exec_t:file entrypoint;

       type_transition和type_change的语法规则是一样的, type_change规则的影响不会在内核中生效,而是依赖于用户空间应用程序,如login或sshd

    5. 生成方法:

        下面介绍一下最简单的安全策略(se-policy)添加方法,各组碰到SELinux导致的访问禁止问题,可以参考用这种方法确认和解决。

        1) 安装pc上的工具,用于自动生成安全策略

    $ sudo apt-get install policycoreutils

        2),刷userdebug/eng软件,先将SELinux设置成Permissive模式,只输出警告不阻止操作

     使用getenforce命令查看当前模式:$ adb shell getenforce

    Enforcing

    在Enforcing模式下,除安全策略允许外的操作都会被阻止;使用setenforce命令更改当前模式(root权限需要):

    $ adb root

    restarting adbd as root
    $ adb shell setenforce 0
    $ adb shell getenforce
    Permissive


    开发如果碰到怀疑是SELinux 可以通过这种方法关闭SELiunx( setenforce 0),以确认是不是SELinux引起的

        3),按照流程完成整个操作,抓取log,过滤出警告信息

    • 如果log较多,可以先用grep工具过滤一下:

    $ grep "avc: *denied" log.txt > denied.txt
    $ cat denied.txt
    <14>[  389.521062] avc:  denied  { set } for property=audio.ftm.rcv_reverse scontext=u:r:system_
    app:s0 tcontext=u:object_r:default_prop:s0 tclass=property_servic

        4),使用pc工具生成安全策略

    • 命令audit2allow用来一次性生成所有安全策略,输入为前面抓取的 log

    $ audit2allow -i denied.txt

  • 相关阅读:
    Linux系统介绍(二)文件系统结构
    为Docker Swarm添加调度策略
    Docker 三剑客之 Docker Swarm
    Hadoop中文文档
    hadoop 学习笔记:mapreduce框架详解
    Java进阶-- GUI
    ceph(8)--关于Ceph PGs
    今天在学习NTP时发现了2个网站
    开始学红帽的RHCE课堂有2次课了,要记下自己的学习经历
    Switch能否用string做参数
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/10369039.html
Copyright © 2011-2022 走看看