精华内容
下载资源
问答
  • SEAndroid

    2018-08-21 17:39:56
    SEAndroid安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中,例如我们经常接触的文件就是分布文件子系统中的。 实际上,系统中需要保护的资源非常多,除了前面说的文件之外,还有进程、socket和...

    SEAndroid安全机制所要保护的对象是系统中的资源,这些资源分布在各个子系统中,例如我们经常接触的文件就是分布文件子系统中的。
    实际上,系统中需要保护的资源非常多,除了前面说的文件之外,还有进程、socket和IPC等等。

    在用户空间中,SEAndroid包含有三个主要的模块,分别是安全上下文(Security Context)、安全策略(SEAndroid Policy)和安全服务(Security Server)

    例子:
    init.rc u:object_r:rootfs:s0 init.rc
    init.rc这个文件的SELinux用户、SELinux角色、类型和安全级别分别为u、object_r、rootfs和s0。

    mac_permissions.xml

    文件mac_permissions.xml给不同签名的App分配不同的seinfo字符串,例如,在AOSP源码环境下编译并且使用平台签名的App获得的seinfo为“platform”,使用第三方签名安装的App获得的seinfo签名为”default”。

    这个seinfo描述的其实并不是安全上下文中的Type,它是用来在另外一个文件external/sepolicy/seapp_contexts中查找对应的Type的

    设置ROM中的文件的安全上下文

    以system.img为例,生成system.img的命令在build/core/Makefile文件中:

    BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
    ..........
    $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS)$(INSTALLED_FILES_FILE)
        $(callbuild-systemimage-target,$@)

    可见system.img是由build-systemimage-target命令生成的。

    再看build-systemimage-target的定义:

    define build-systemimage-target
      @echo "Target system fs image: $(1)"
      $(call create-system-vendor-symlink)
      @mkdir -p $(dir $(1))$(systemimage_intermediates) && rm -rf$(systemimage_intermediates)/system_image_info.txt
      //call generate-userimage-prop-dictionary
      $(call generate-userimage-prop-dictionary,$(systemimage_intermediates)/system_image_info.txt, \
         skip_fsck=true)
      $(hide) PATH=$(foreachp,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
         ./build/tools/releasetools/build_image.py \
         $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt$(1) \
         || ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): "1>&2 ;\
              du -sm $(TARGET_OUT) 1>&2;\
              echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576)) MB." 1>&2 ;\
              mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE)$(DIST_DIR)/installed-files-rescued.txt; \
              exit 1 )
    endef
    

    这里执行了两个命令:

    第一个命令:generate-userimage-prop-dictionary,用来生成一个属性文件system_image_info.txt。它的第一个参数就是system_image_info.txt。

    这里面存储一下变量供mkuserimg.sh使用

    比如

    fs_type=ext4
    system_size=
    userdata_size=
    selinux_fc=...

    查看这个命令的定义,可以发现这个命令依靠一系列的echo命令来将keyvalue格式的配置写入到文件system_image_info.txt当中。该命令的定义中有一行:

    $(hide) echo "selinux_fc=$(SELINUX_FC)" >> $(1)

    查看变量SELINUX_FC的赋值:
    SELINUX_FC :=$(TARGET_ROOT_OUT)/file_contexts。即OUT/root/file_context,这个文件就是根据external/sepolicy/file_contexts来生成的。

    第二个命令:./build/tools/releasetools/build_image.py,是一个python脚本,用来制作system.img镜像文件。而且这个命令将会使用到第一个命令里生成的属性文件/system_image_info.txt。

    查看该命令的入口函数:

      def main(argv):
      if len(argv) != 3:
        print__doc__
       sys.exit(1)
    
      in_dir = argv[0]
     glob_dict_file =argv[1]
     out_file =argv[2]
    
     glob_dict =LoadGlobalDict(glob_dict_file)
     image_filename =os.path.basename(out_file)
      mount_point = ""
      if image_filename == "system.img":
        mount_point= "system"
      elif image_filename == "userdata.img":
        mount_point= "data"
      elif image_filename == "cache.img":
        mount_point= "cache"
      elif image_filename == "vendor.img":
        mount_point= "vendor"
      elif image_filename == "oem.img":
        mount_point= "oem"
      else:
        print>> sys.stderr, "error: unknown image file name ",image_filename
       exit(1)
    
      image_properties = ImagePropFromGlobalDict(glob_dict,mount_point)
      if not BuildImage(in_dir,image_properties, out_file):
        print>> sys.stderr, "error: failed to build %s from %s" %(out_file, in_dir)
       exit(1)

    参数argv[1]指向的就是我们上面提到的属性文件system_image_info.txt,最终保存在本地变量glob_dict_file中。另外一个参数argv[2]指向的要输出的system.img文件路径,最终保存在本地变量out_file中。

    函数LoadGlobalDict用来打开属性文件system_image_info.txt,并且将它每一行的key和value提取出来,并且保在字典glob_dict中。注意,这个字典glob_dict包含有一个key等于selinux_fc、value等于file_contexts文件路径的项。

    接下来再通过os.path.basename将输出的文件路径out_file的最后一项提取出来,就可以得到image_filename的值为”system.img“,因此再接下来就会得到本地变量mount_point的值为”system“,表示我们现在正在打包的是system.img文件。

    函数ImagePropFromGlobalDict用来从字典glob_dict中提取与安装点mount_point相关的项,并且保存在另外一个字典中返回给调用者,在它的实现中有:

      common_props = (
         "extfs_sparse_flag",
         "mkyaffs2_extra_flags",
         "selinux_fc",
         "skip_fsck",
         "verity",
         "verity_key",
         "verity_signer_cmd",
         "transparent_compression_method"
         )
      for p in common_props:
        copy_prop(p,p)
    
    if fc_config is not None:
         build_command.append(fc_config)
        elif"selinux_fc" in prop_dict:
         build_command.append(prop_dict["selinux_fc"])
    ..............
    if "selinux_fc" in prop_dict:
         build_command.append(prop_dict["selinux_fc"])
         build_command.append(prop_dict["mount_point"])

    通过这些命令,系统会编译出一个关联有安全上下文的system.img镜像文件。

    mkuserimg.sh

    mkuserimg.sh 调用make_ext4fs
    -s就是生成ext4的S模式制作;
    -a system“,是指这个img用于android系统,挂载点是/system,使用这个参数,make_ext4fs会根据private/android_filesystem_config.h里定义好的权限来给文件夹里的所有文件重新设置权限,如果你刷机以后发现有文件权限不对,可以手工修改android_filesystem_config.h来添加权限,重新编译make_ext4fs,
    也可以不使用 “-a system”参数,这样就会使用文件的默认权限。
    如果不使用-a参数,则可。

    展开全文
  • SEAndroid使用

    千次阅读 2016-12-15 17:24:18
    SEAndroid

    SEAndroid是Security Enhancement for Android的简称,这是将SElinux一直到Android的项目,这是它的官方网站http://seandroid.bitbucket.org/

    1 SELinux

    SELinux的全称是security enhancement for Linux的,它是美国国安局在Linux社区的帮助下开发的一种强制访问控制体系(MAC),在这种体系的控制下,进程只能访问那些规定可以访问的文件和资源。

    1.1 安全机制

    DAC:自主访问控制机制,Linux传统的安全机制,主要对各分组权限访问进行控制,分为用户,同组用户,其他用户三组,只能控制这三组的读写和执行权限。
    MAC:强势访问控制机制,它将系统中的资源分为密级和类别进行控制,只有明确授权可以访问的资源,用户才能够访问。
    MAC的两个重要概念:主体和客体。主体,主要指用户或用户运行的进程;客体,主要包括系统的文件,目录,socket等资源。但是,当进程1被进程2访问时,进程2是主体,进程1是客体。
    在MAC机制中,主体和客体都被设置了安全上下文,配合系统中存在的安全规则库使用。

    1.2LSM框架

    早期的SELinux是以Linux系统补丁集的方式实现的,他实现了自己的一套安全框架,后来随着Linux内核的发展,开发出了一套通用的安全框架LSM(Linux security module),它将安全策略和实现分离出来,允许安全模块载入内核中,从而更加严格的控制安全性。通常用户进程在访问系统资源前都会进行DAC检查,在DAC检查之后,调用LSM提供的钩子函数进行更严格的权限检查。

    Created with Raphaël 2.1.0用户进程系统调用查找节点错误检查DAC检查LSM检查(调用LSM安全模块)访问节点

    1.3 SELinux架构

    SELinux主要有三部分组成:

    • SELinux虚拟文件系统:SELinux内核和用户进程间的数据交换接口
    • 安全服务模块:包含SELinux的安全策略,它根据区安全策略生成访问规则,其访问规则保存在访问向量缓存中,以提高速度
    • 访问向量缓存:缓存之前的访问规则,以提高性能,如果客体的请求没有在缓存中找到,则会把请求递交到安全服务模块中,有安全服务模块响应请求,并更新缓存。

    1.4 安全上下文

    安全上下文的格式:
    USER:ROLE:TYPE[:LEVEL]
    其主要有四部分组成,第四项为可选项。

    • USER:指定用户,常用的3种用户类型,user_u(普通用户,限制权限),system_u(系统级别进程),root(root用户)
    • ROLE:指定角色,不同的角色有不同的权限。文件,目录,socket等客体角色通常是object_r,主体进程的角色通常是r。一个用户通常有多个角色,但同一时间只能使用一个。
    • TYPE:定义客体和主体所属类型。对于进程而言,他的类型也成为domain。类型是安全上下文最重要的内容,后续会深入介绍。
    • LEVEL:定义安全等级,只用于mls策略中,可能值是s0-s15。

    在安全上下文中,最重要的定义是TYPE,无论是主体或客体的类型,都是通过policy文件type语句定义的类型,type语法如下:

    type 类型名称 [,属性]

    type语法中的属性值都是预定义好的,有特别的含义。如domain表示域,通常主体的type具有domain属性,因此我们也把主体的type成为domain。fs_type表示文件,通常用于客体的类型表示中,SELinux定义的类型在system/sepolicy/attribute文件中。

    1.5 访问规则

    除了安全上下文之外,SELinux还定义了主体对客体访问规则,这种访问规则一般存放在te文件中。目前SELinux策略语言支持4种类型的访问规则:

    • allow:表示允许主体对客体执行指定的操作
    • dontaudit:表示不记录某条违反规则的决策信息
    • auditallow:记录决策信息,通常SELinux只记录失败的决策信息,应用这条规则后也会记录成功的决策信息
    • neverallow:表示不允许主体对客体执行指定的操作

    访问规则语法:
    allow source_type target_type:class Permission

    • 源类型(source type):通常是某种属性为domain的类型,代表主体
    • 目标类型(target type):允许访问的客体的类型,目标类型可以同时指定多个
    • 客体类别(object class):对客体目标类型进行限制,目标类型可能涵盖file,dir,socket等多个类别,如果将class设置为file,则主体只拥有访问客体file的权限。
    • 许可(permission):主体可以对客体执行的操作的种类,SELinux定义的许可种类可以参考system/sepolicy/access_vectors

      SELinux的安全策略的实现是通过比较安全上下文中定义的类型来完成的,这种方式称为类型强制,是非常细粒度的权限管理方式。SELinux还提供了一种角色访问控制(RBAC),这是一种简化的权限管理方式,系统中先创建不同的角色,角色间拥有不同的权限,通过为用户指定不同的角色来赋予不同的权限。但是这种权限管理方式还没有应用到android,有需要的可以深入了解一下。

      1.6 域转移

      1.7 常用命令

      setenforce:切换系统enforcing状态和permissive状态,如setenforce 0表示系统切入permissive状态
      getenforce:获取系统enforcing状态和permissive状态
      id:显示当前用户的uid,gid和安全上下文
      chcon:改变文件或目录的安全上下文
      restorecon:恢复系统原始的安全上下文设置

    2 SEAndroid

    2.1 SEAndroid组成

    SEAndroid主要有两部分构成:

    • SELinux安全模块:位于kernel/security/selinux下。
    • 用户态工具:用于产生SELinux的策略文件(规则文件),位于system/sepolicy下,这个目录保存了系统初始的规则文件。另外,external/libselinux下存放了libselinux的源码,它提供了帮助用户进程使用SELinux的一些函数。
      在system/sepolicy下有几个很重要的文件:
      • file_contexts:系统中所有文件的安全上下文;
      • property_contexts:系统中所有属性的安全上下文;
      • seapp_contexts:定义用户、seinfo和域之间的关系,用于确定用户进程的安全上下文;
      • sepolicy:二进制文件,保存系统策略,系统初始化时会把它设置到内核中;
        SELinux虚拟文件系统在sys/fs/selinux下,该目录下的文件是SELinux内核和用户进程进行同行的接口。

    2.2 策略文件

    1.system/sepolicy/roles
    角色定义文件,SEAndroid中之定义了r。
    2.system/sepolicy/users
    用户定义文件,SEAndroid中之定义了u。
    3.system/sepolicy/attributes
    属性定义文件,SELinux中已经提到。
    4.system/sepolicy/security_classes
    class定义文件,定义客体的类别。
    5.system/sepolicy/access_vectors
    操作种类定义文件,定义了主体对客体的所有操作种类。
    6.system/sepolicy/*.te
    类型强制规则定义文件。
    7.system/sepolicy/te_macros
    定义了te文件中的各种宏。
    8.system/sepolicy/file_contexts
    系统中所有文件的安全上下文。
    9.system/sepolicy/property_contexts
    系统中所有属性的安全上下文。

    展开全文
  • SEAndroid概括

    2018-07-11 23:07:29
    引言本文是对SEAndroid方面知识拾人牙慧后的一些总结。SEAndroid是一套以SeLinux为核心的系统安全机制。 SELinux是一种基于域-类型(domain-type)模型的强制访问控制(MAC)安全系统,其原则是任何进程想在SELinux...

    引言

    本文是对SEAndroid方面知识拾人牙慧后的一些总结。

    SEAndroid是一套以SeLinux为核心的系统安全机制。 

     SELinux是一种基于域-类型(domain-type)模型的强制访问控制(MAC)安全系统,其原则是任何进程想在SELinux系统中干任何事,都必须先在安全策略的配置文件中赋予权限。凡是没有在安全策略中配置的权限,进程就没有该项操作的权限。在SELinux出现之前,Linux的安全模型是DACDiscretionaryAccess Control),译为自主访问控制。其核心思想是进程理论上所拥有的权限与运行它的用户权限相同。比如,以root用户启动shell,那么shell就有root用户的权限,在Linux系统上能干任何事。这种管理显然比较松散。

             SELinux中,如果需要访问资源,系统会先进行DAC检查,不通过则访问失败,然后再进行MAC权限检查。

    SEAndroid框架

             回到SEAndroidSEAndroid的框架图如下:

     

     


    主要分为两部分:用户空间和内核空间,两者以SELinux文件系统的接口为界。libselinux中封装了访问Security Context、加载资源安全策略和访问SELinux内核文件的接口。

    先来看内核空间,在内核空间中,存在一个SELinux LSM模块,这个模块包含有一个访问向量缓冲(Access Vector Cache)和一个安全服务(Security Server)。Security Server负责安全访问控制逻辑,即由它来决定一个主体访问一个客体是否是合法的。这里说的主体一般就是指进程,而客体就是主体要访问的资源,例如文件。

    在实际系统中,以/sys/fs/selinux为安装点,安装一个类型为selinuxfs的文件系统,也就是SELinux文件系统,用来与内核空间的SELinux LSM模块通信。

    LSM,全称是Linux Security ModelLSM可以说是为了SELinux而设计的,但是它是一个通用的安全模块,SELinux可以使用,其它的模块也同样可以使用。这体现了Linux内核模块的一个重要设计思想,只提供机制实现而不提供策略实现。在我们这个例子中,LSM实现的就是MAC机制,而SELinux就是在这套机制下的一个策略实现。也就是说,你也可以通过LSM来实现自己的一套MAC安全机制。

    SELinuxLSM和内核中的子系统是如何交互的呢?首先,SELinux会在LSM中注册相应的回调函数。其次,LSM会在相应的内核对象子系统中会加入一些Hook代码。例如,我们调用系统接口read函数来读取一个文件的时候,就会进入到内核的文件子系统中。在文件子系统中负责读取文件函数vfs_read就会调用LSM加入的Hook代码。这些Hook代码就会调用之前SELinux注册进来的回调函数,以便后者可以进行安全检查。

    SELinux在进行安全检查的时候,首先是看一下自己的Access Vector Cache是否已经有缓存。如果有的话,就直接将结果返回给相应的内核子系统就可以了。如果没有的话,就需要到Security Server中去进行检查。检查出来的结果在返回给相应的内核子系统的同时,也会保存在自己的Access Vector Cache中,以便下次可以快速地得到检查结果。

    流程图如下:

     

    允许访










    从图中可以看到,内核中的资源在访问的过程中,一般需要获得三次检查通过:

          1. 一般性错误检查,例如访问的对象是否存在、访问参数是否正确等。

         2. DAC检查,即基于Linux UID/GID的安全检查。

          3. SELinux检查,即基于安全上下文和安全策略的安全检查。

     

    再来看用户空间,分三部分:Security ContextSecurity ServerSEAndroid Policy

    Security Context里保存着资源的安全上下文,整套SEAndroid系统就是基于这些安全上下文实现的。

    Security Server由应用程序安装服务PackageManagerService、应用程序安装守护进程installd、应用程序进程孵化器Zygote进程以及init进程组成。其中,PackageManagerServiceinstalld负责创建App数据目录的安全上下文,Zygote进程负责创建App进程的安全上下文,而init进程负责控制系统属性的安全访问。它有三个任务:1、在开机时将资源安全访问策略SEAndroid Policy加载进内核空间;2、去Security Context中查找安全上下文;3、获取内核空间中安全上下文对应的资源访问权限。

    守护进程installd负责创建App数据目录。在创建App数据目录的时候,需要给它设置安全上下文,使得SEAndroid安全机制可以对它进行安全访问控制。Installd根据PackageManagerService传递过来的seinfo,并且调用libselinux库提供的selabel_lookup函数到前面我们分析的seapp_contexts文件中查找到对应的Type。有了这个Type之后,installd就可以给正在安装的App的数据目录设置安全上下文了,这是通过调用libselinux库提供的lsetfilecon函数来实现的。

    Android系统中,Zygote进程负责创建应用程序进程。应用程序进程是SEAndroid安全机制中的主体,因此它们也需要设置安全上下文,这是由Zygote进程来设置的。组件管理服务ActivityManagerService在请求Zygote进程创建应用程序进程之前,会到PackageManagerService中去查询对应的seinfo,并且将这个seinfo传递到Zygote进程。于是,Zygote进程在fork一个应用程序进程之后,就会使用ActivityManagerService传递过来的seinfo,并且调用libselinux库提供的selabel_lookup函数到前面我们分析的seapp_contexts文件中查找到对应的Domain。有了这个Domain之后,Zygote进程就可以给刚才创建的应用程序进程设置安全上下文了,这是通过调用libselinux库提供的lsetcon函数来实现的。

        Android系统中,属性也是一项需要保护的资源。Init进程在启动的时候,会创建一块内存区域来维护系统中的属性,接着还会创建一个Property服务。这个Property服务通过socket提供接口给其它进程访问Android系统中的属性。其它进程通过socket来和Property服务通信时,Property服务可以获得它的安全上下文。有了这个安全上下文之后,Property服务就可以通过libselinux库提供的selabel_lookup函数到前面我们分析的property_contexts去查找要访问的属性的安全上下文了。有了这两个安全上下文之后,Property服务就可以决定是否允许一个进程访问它所指定的属性了。

    SEAndroid Policy就是SEAndroid的安全策略,实际是在系统编译时生成的一个sepolicy文件,在init进程中被加载到SELinux内核中。

     

     

    机制实现

    要想理解SEAndroid,就先要了解它的基础——对象。主体通常是进程,是访问者,客体就是指进程被访问的资源,例如文件、系统属性等。

    安全上下文实际上是一个附加在对象上的标签(Tag)。这个标签实际上就是一个字符串,它由四部分内容组成,分别是SELinux用户、SELinux角色、类型、安全级别,,每一个部分都通过一个冒号来分隔,格式为“user:role:type:sensitivity”。

    例如,在开启了SEAndroid安全机制的设备上执行带-Z-ef选项的ls命令,就可以看到一个文件的安全上下文:

    -rwxr-x---root     root     u:object_r:rootfs:s0 init.rc

     

    上面的命令列出文件/init.rc的安全上下文为“u:object_r:rootfs:s0”,这表明文件/init.rcSELinux用户、SELinux角色、类型和安全级别分别为uobject_rrootfss0

    又如,在开启了SEAndroid安全机制的设备上执行带-Z选项的ps命令,就可以看到一个进程的安全上下文:

    LABEL                          USER     PID  PPID  NAME

    u:r:init:s0                    root      1    0     /init

    ......

     

    上面的命令列出进程init的安全上下文为“u:r:init:s0”,这表明进程initSELinux用户、SELinux角色、类型和安全级别分别为urinits0

             SEAndroid中,用户、角色和安全级别都分别只有一个,故安全上下文中最重要的是类型这一属性。

             对于进程来说,SELinux用户和SELinux角色只是用来限制进程可以标注的类型。而对于文件来说,SELinux用户和SELinux角色就可以完全忽略不计。为了完整地描述一个文件的安全上下文,通常将它的SELinux角色固定为object_r,而将它的SELinux用户设置为创建它的进程的SELinux用户。

    SEAndroid中,只定义了一个SELinux用户u,因此我们通过ps -Zls -Z命令看到的所有的进程和文件的安全上下文中的SELinux用户都为u。同时,SEAndroid也只定义了一个SELinux角色r,因此,我们通过ps -Z命令看到的所有进程的安全上下文中的SELinux角色都为rSELinux的配置文件有:

    device/ mediate/common/BoardConfig.mk->TE环境的一些配置,te文件的路径

    system/sepolicy/public/attributes-> 所有定义的attributes都在这个文件

    system/sepolicy/private/access_vectors-> 对应了每一个class可以被允许执行的命令

    system/sepolicy/public/roles-> Android中只定义了一个role,名字就是r,并将rattribute domain关联起来

    system/sepolicy/private/users-> 其实是将userroles进行了关联,设置了user的安全级别,s0为最低级是默认的级别,s15是最高的级别

    system/sepolicy/private/security_classes->这个class的内容是指在android运行过程中,程序或者系统可能用到的操作的资源类型,它们在*.te文件中会用到。

    system/sepolicy/public/te_macros-> 系统定义的宏全在te_macros文件

    system/sepolicy/public目录和private目录、device/sepolicy/mediate/,以及device/sepolicy/mediate/[platformcode]中的te文件 -> 一些配置的文件,包含了各种运行的规则

    以上文件路径均是在MTK平台的Android 8.0项目中。以上配置文件,userroles都比较好理解,BoardConfig.mk配置了te文件的路径:

    BOARD_SEPOLICY_DIRS:= \

            device/mediatek/sepolicy/basic/non_plat\

            device/mediatek/sepolicy/bsp/non_plat \

            device/mediatek/sepolicy/full/non_plat

    BOARD_PLAT_PUBLIC_SEPOLICY_DIR:= \

           device/mediatek/sepolicy/basic/plat_public \

           device/mediatek/sepolicy/bsp/plat_public \

            device/mediatek/sepolicy/full/plat_public

    BOARD_PLAT_PRIVATE_SEPOLICY_DIR:= \

           device/mediatek/sepolicy/basic/plat_private \

           device/mediatek/sepolicy/bsp/plat_private \

           device/mediatek/sepolicy/full/plat_private

    BOARD_PREBUILTS_FULL_PUBLIC_PLAT_DIRS:= \

           device/mediatek/sepolicy/basic/prebuilts/api/26.0/plat_public \

           device/mediatek/sepolicy/bsp/prebuilts/api/26.0/plat_public \

           device/mediatek/sepolicy/full/prebuilts/api/26.0/plat_public

    BOARD_PREBUILTS_FULL_PRIVATE_PLAT_DIRS:= \

           device/mediatek/sepolicy/basic/prebuilts/api/26.0/plat_private \

           device/mediatek/sepolicy/bsp/prebuilts/api/26.0/plat_private \

           device/mediatek/sepolicy/full/prebuilts/api/26.0/plat_private

    BOARD_COMPAT_MAPPING_CIL_DIRS:= \

           device/mediatek/sepolicy/full/private/compat/26.0/26.0.cil

    BOARD_COMPAT_MAPPING_IGNORE_CIL_DIRS:= \

           device/mediatek/sepolicy/full/private/compat/26.0/26.0.ignore.cil

    BOARD_26.0_NONPLAT_FILE:= \

            device/mediatek/sepolicy/full/prebuilts/api/26.0/nonplat_sepolicy.cil

    对应路径下就是各种te文件,当然,BoardConfig.mk文件不止配置了SEAndroid。经试验,系统服务的安全上下文声明要放在BOARD_PLAT_PRIVATE_SEPOLICY_DIR中的目录下,否则不生效,SEAndroid编译生成的文件在手机系统中的system/etc/selinux目录下。

    SEAndroid中,所有的东西都被抽象成类型。进程,抽象成类型;资源,抽象成类型。属性,是类型的集合。所以,TE规则中的最小单位就是类型。一般来说,资源的类型,都定义在了security_classes文件中,句式如下:

    class XXX

    type则可由开发者自己定义,可定义在一些te文件中,句式如下:

    type xxx

    类型又可集合成属性,属性的出现简化了TE规则的配置,例如,如果要配置m个进程对同一组资源(n个)的访问权限,没有属性的话需要一个一个去设置,要m*n行代码,而设置这n个资源为同一个属性的话,只需要m+1行代码,声明X类型有YZ属性句式如下:

    type X,YZ; 

    在主体对客体,又有不同的操作类型,如读、写和创建等,这些操作类型定义在access_vectors中,如:

    common file

    {

             ioctl

             read

             write

             create

             getattr

             setattr

             lock

             relabelfrom

             relabelto

             append

             map

             unlink

             link

             rename

             execute

             quotaon

             mounton

    }

    以上的配置文件都是为了服务于te文件中的规则。te文件中除了声明类型,并关联属性之外,主要就是声明一些类型的安全权限。举个例子:

     

    allow zygoteappdomain system_app:process { getpgid setpgid };

     

      允许zygote类型的进程对appdomainsystem_app类型的进程执行getpgidsetpgid操作;

     

      rule_nameallow

     

      soruce_typezygote

     

      target_typeappdomainsystem_app

     

      objectsecurityclassprocess

     

      accessvectorgetpgid  setpgid

     

    {}”可以用以表示一组type或操作集,简化了te语句的书写。除了“{}”还有其他的语法,如“~getpgid”表示process相关操作除了getpgid的操作集;“file_type -system_file”表示拥有file_type属性中除了system_file的类型集;“*”表示所有内容。

    之前的例子中还要说明一下rule_name,它不止有一个allow(赋予权限),还有:

    neverallow:检查安全策略文件中是否有违反该项操作的allow语句,用来阻止某些操作,allowneverallowe不可冲突,否则会编译报错,且不可随意更改,否则可能导致CTS测试失败;

    allowauditaudit含义就是记录某项操作,默认情况下SELinux只记录那些权限检查失败的操作。allowaudit则使得权限检查成功的操作也被记录。注意:allowaudit只是允许记录,它和赋予权限没有关系。赋予权限必须且只能使用allow语句。

    dontaudit:对那些权限检查失败的操作不做记录;

     

    看到这里,思考一下,绝大多数文件总会归属于某一个目录,即使文件数量庞大,只有声明了目录的权限即可,那进程呢?Android系统中的重要固有进程应该都已经设置了权限,那么应用呢?原生的系统并不知道会有什么其他应用会运行在系统中,那怎么定义这些应用进程的权限呢?

    答案是根据它们的特点归类。这个归类方案定义在seapp_context中:

    isSystemServer=truedomain=system_server

    user=systemseinfo=platform domain=system_app type=system_app_data_file

    user=bluetoothseinfo=platform domain=bluetooth type=bluetooth_data_file

    user=nfcseinfo=platform domain=nfc type=nfc_data_file

    user=radioseinfo=platform domain=radio type=radio_data_file

    user=shared_relrodomain=shared_relro

    user=shellseinfo=platform domain=shell type=shell_data_file

    user=_isolateddomain=isolated_app levelFrom=user

    user=_appseinfo=media domain=mediaprovider name=android.process.media type=app_data_filelevelFrom=user

    user=_appseinfo=platform domain=platform_app type=app_data_file levelFrom=user

    user=_appisV2App=true isEphemeralApp=true domain=ephemeral_app type=app_data_filelevelFrom=user

    user=_appisPrivApp=true domain=priv_app type=app_data_file levelFrom=user

    user=_appminTargetSdkVersion=26 domain=untrusted_app type=app_data_file levelFrom=user

    user=_appdomain=untrusted_app_25 type=app_data_file levelFrom=user

     

    如这一行:

    user=_appseinfo=platform domain=platform_app type=app_data_file levelFrom=user

     

    意思是seinfoplatformapp的属性为platform_app,其进程的权限与platform_app相同(权限定义在platform_app.te中),产生的文件类型为app_data_file,其安全权限与app_data_file相同。Seinfo的定义在mac_permissions.xml中,主要是根据app签名区分。

    还有一些语法规则如type_transition(声明主体新建某些进程或文件时,这些进程或文件会转变为另一个类型,不与主体相同)、type_changealias等,使用不多。

     

     

    了解了SEAnroid的基本原理,接下来看一下如何定制符合项目需求的安全策略,想象一下该情景,某个进程需要访问某个目录,进行操作,发现操作失败,输出log如下:

    type=1400audit(1882976.149:5): avc: denied { write } for pid=3194comm="BluetoothAdapte"name="aplog" dev="mmcblk0p22" ino=88 scontext=u:r:bluetooth:s0tcontext=u:object_r:system_data_file:s0tclass=dir

    这句log是违反SEAndroid  MAC访问策略的一个访问记录。scontext表示进程的SContextu:r:bluetooth:s0,属于bluetooth域;

      tcontext表示目标的SContextu:r:system_data_file:s0,属于system_data_file类型;

      tclass表示进程要操作的ObjectClassdir表示目录;

      mmcblk0p22userdata分区,write表示写操作。

      连起来就是bluetooth域的进程(BluetoothAdapte),对system_data_file类型的dir执行write操作失败。明确了失败原因,我们就可以在安全策略配置文件中定制我们自己的策略了:

      bluetooth.te文件中

      allow bluetooth system_data_file:dirw_dir_perms;

      w_dir_perms是一个宏,其定义在global_macros中,包含了write相关操作:

      define(`w_dir_perms', `{ open search write add_nameremove_name }')

     

     

     

    在项目开发中,我们在/dev目录下建立了一个新的设备文件tfa98xx,这是一个音频相关的设备文件,但是在集成framework层的代码后,总是出现下面的访问错误,应该如何处理呢?

      type=1400 audit(3635791.670:21): avc: denied{ read write } for pid=273 comm="mediaserver"name="tfa98xx" dev="tmpfs" ino=9770 scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0 tclass=chr_file

      首先,我们先看一下访问失败的原因:从log看,应该是mediaserver域的进程没有权限读写device类型的字符设备文件。那么我们能不能在mediaserver.te中加入访问权限呢?

      domain.te中有如下定义:

      [external/sepolicy/domain.te]

      neverallow { domain -unconfineddomain -ueventd} device:chr_file { open read write };

      也就是说除了unconfineddomainuevented域外,所有在domain域中的进程都不能对device类型的字符设备文件执行openreadwrite操作。

    mediaserver也属于domain域,所以肯定不能通过添加策略来设置访问权限,怎么办呢?

      mediaserver.te中,我们发现mediaserver域是可以对audio_device类型的字符设备执行读写的:

      allow mediaserver audio_device:chr_filerw_file_perms;

      那么,能不能通过打标签的方法,把/dev/tfa98xx设置为audio_device类型呢?答案是肯定的。

      file_context文件中设置/dev/tfa98xx的安全属性,问题解决了:

      /dev/tfa9890      u:object_r:audio_device:s0


    展开全文
  • SEAndroid策略

    2017-03-15 17:07:14
    http://blog.csdn.net/l173864930/article/details/17194899基础知识...SEAndroid的安全检查覆盖了所有重要的方面包括了域转换、类型转换、进程相关操作、内核相关操作、文件目录相关操作、文件系统相关操作、对设备

    http://blog.csdn.net/l173864930/article/details/17194899

    基础知识

    SEAndroid在架构和机制上与SELinux完全一样,考虑到移动设备的特点,所以移植到SEAndroid的只是SELinux的一个子集。SEAndroid的安全检查覆盖了所有重要的方面包括了域转换、类型转换、进程相关操作、内核相关操作、文件目录相关操作、文件系统相关操作、对设备相关操作、对app相关操作、对网络相关操作、对IPC相关操作。
    Policy

    policy是整个SEAndroid安全机制的核心之一,除了有好的安全架构外还必须有好的安全策略以确保让访问主体只拥有最小权限,使程序既能顺利执行基本功能又能防止被恶意使用。
    在SEAndroid中主要采用了两种强制访问方法:
    TE
    MLS
    这两种方法都在policy中得以实现,以下内容会先对policy规则的执行对象安全上下文有一个详细的介绍,然后再分别对SEAndroid中的TE机制和MLS机制做详细介绍。
    标记安全上下文

    SEAndroid中的安全上下文
    SEAndroid的安全上下文与SELinux基本一致(除了MLS检测在SEAndroid中被强制执行),共有4个部分组成分别为user、role、type、sensitivity,以u:object_r:system_data_file:s0为例:
    user:安全上下文的第一列为user,在SEAndroid中的user只有一个就是u。
    role:第二列表示role,在SEAndroid中的role有两个,分别为r和object_r。
    type:第三列为type,SEAndroid中共定义了139种不同的type。
    security level:第四列是专为MLS访问机制所添加的安全上下文的扩展部分,格式为sensitivity[:category list][- sensitivity[:category list]],例如s0 - s15:c0.c1023,其中s0之后的内容可以不需要,冒号后面的内容是category,sensitivity和category组合一起声明了当前的安全级别(security level),“-”号左右分别标识了安全级别的最低和最高,这一列的参数将在MLS约束检查时用到,“15”、“1023”表示了sensitivity和category的最大值,这一参数可在Android.mk中定义。
    安全上下文中最重要的部分就是第三列的type了,对于进程type被称为domain,type是整个SEAndroid中最重要的一个参量,所有的policy都围绕这一参量展开,所以为系统中每个文件标记上合适的type就显得极为重要了。在SEAndroid中关于安全上下文配置的核心文件主要是file_contexts文件、seapp_contexts文件和ocontexts文件。
    安全上下文标记的四种方式
    基于策略语句标记
    在SEAndroid的策略语言type_transition规则可以指定新创建的文件或目录的标签(安全上下文),通常情况下新创建文件的标签和其父目录的标签一致,但是可以使用type_transition规则为其指定特定的标签,有关transition的内容将在之后更详细地说明。
    默认标记
    默认的标记行为在有关的策略标记规则不存在时使用,以及那些根本就没有关联策略标记规则的客体类别使用,大部分客体类别的默认标记都继承了创建它的进程/或包括客体的容器的安全上下文。
    程序请求标记
    对于某些客体类别,SELinux提供了许多API允许程序明确地请求标记,这对于新创建的和已经存在的客体实例都一样。对于那些存储在支持标记的文件系统上的与文件有关的客体,SEAndroid通过调用相应API既能在创建文件时设置安全上下文,也能对与文件有关的客体进行重新标记,只需要适当的relabelfrom 和relabelto许可就可以明确地改变一个客体的标记,这些许可由policy进行严密控制。
    初始SID标记
    安全上下文在用户态通过字符串来描述,而在内核中使用context数据结构来表示它。给每个context数据结构都分配一个u32 sid,该sid保存在描述内核数据结构的安全上下文中。内核驱动使用sidtab哈希表来描述所有已经分配了sid的context数据结构,通过查询该哈希表即可得到一个安全上下文所对应的sid。
    几乎所有sid的分配和注册都是在运行时完成的,但是在refpolicy中定义了27个“Initial SID”,用于在内核驱动初始化时、由init进程通过selinuxfs接口加载policy之前,描述相应内核设施的初始安全属性。
    初始SID提供了一种特殊的默认标记行为,初始SID适用于两种环境:在系统初始化策略还没有载入前对一部分内核相关的客体进行标记,以及当客体的安全上下文无效或安全上下文丢失时使用。初始sid的内容被定义在了initial_sids文件中,在ocontexts文件中同时声明了初始sid相应的安全上下文。

    为文件系统和文件系统中的文件标记安全上下文
    在SEAndroid中存在两种文件系统,一种是常见的文件系统包括传统的、本地文件系统都是用来在磁盘上或可移动介质上存储数据(如ext3和XFS),和为了兼容其它操作系统的非本地文件系统(如iso9660和vfat),另一种是存在于内存中被称为伪文件系统,它是用于内核和用户空间之间的通讯(如proc和sysfs),通过selinux库中提供的API函数完成。
    文件系统的初始安全上下文的标记是在文件系统挂载时完成,另外普通文件系统上的文件在文件创建时就标记好了安全上下文并和文件一起存储在磁盘上,而伪文件系统只在运行时才会为其中的文件标记安全上下文。
    为文件系统标记安全上下文是对该文件系统的所有inode节点进行安全上下文的标记,这些标记是最原始的标记,之后如有新的文件被创建并赋予了相应的安全上下文标记则将会执行覆盖操作保留最新的安全上下文。

    对于文件系统的标记SEAndroid依据各文件系统的不同属性拥有不同的机制:
    基于支持扩展属性的文件系统标记(即允许保存安全上下文这一扩展属性的文件系统)(fs_use_xattr)
    这一类文件系统包括yaffs2、jffs2、ext2、ext3、ext4、xfs、btrfs,它们的一个共性是都支持在磁盘上永久保存安全上下文这一扩展属性信息。它们都用同一个安全上下文u:object_r:labeledfs:s0被统一标记,这些都在ocontexts文件中被声明,使用fs_use_xattr语法实现。
    另外对于这些有唯一且永久的节点号的传统文件系统来说,SEAndroid会用一个永久的标记映射来决定文件系统内的节点的安全上下文和文件系统本身的安全上下文,这个永久的标记映射是由一个或多个配置文件组成,在SEAndroid中就是file_contexts文件和seapp_contexts文件,这两个文件会和policy二进制文件一起构成整个SEAndroid的安全策略体系。
    file_contexts文件对相应目录的使用正则表达式进行匹配,被匹配到的目录或文件都将被标记上相应的安全上下文,这个过程发生在文件系统标记完成之后执行。

    基于任务的文件系统标记(fs_use_task)
    使用基于任务的标记时,在SEAndroid中使用 fs_use_task 规则声明新的与文件有关的客体继承创建它们的进程的安全上下文。使用基于任务的标记的文件系统不支持程序请求的标记,这种类型的标记行为多用于对于不真实存储用户数据但支持某种类型的内核资源的伪文件系统上。在SEAndroid中sockfs,pipefs都是基于这一方式进行安全上下文的标记,具体被标记的安全上下文内容都在ocontexts文件中有详细声明。

    基于转换的文件系统标记(fs_use_trans) 基于转换的文件系统标记与基于任务的文件系统标记非常类似,都使用的是伪文件系统,不同的是基于转换的安全上下文标记是基于类型转换规则(type_transition)实现的。在这样的文件系统上创建的文件都需要有一套相关的type_transition规则来完成。如果没有找到相应的type_transition规则,文件就会使用文件系统的初始安全上下文,文件系统的初始安全上下文被定义在了ocontexts文件中, 在SEAndroid中有devpfs、tmpfs、devtmpfs、shm、mqueue这些伪文件系统使用这一机制进行安全上下文标记。

    一般方式标记安全上下文(genfscon)
    genfscon语句用于运行时标记伪文件系统和不支持扩展属性的传统文件系统。在SEAndroid中文件系统rootfs、proc、selinuxfs、cgroup、sysfs、inotifyfs、vfat、debugfs、fuse,都是采用这一方式进行安全上下文的标记,在ocontexts文件中定义了这些文件系统相应的安全上下文内容。

    TE(Type Enforcement)

    TE强制访问方式是SEAndroid中的最主要的安全手段,所有关于TE的强制访问规则都被定义在了后缀为te的文件中,在te文件中基本能总结为完成如下操作:
    对type类型的定义和将type归到相应的attribute中
    SEAndroid在te文件中定义了安全策略中最基本的参量type,同时将具有共性的type归在一起构成一个称为attribute的集合,policy的规则执行也能以attribute作为执行对象。
    SEAndroid为所有type共定义了17个attribute:
    dev_type:
    这一attribute包含了所有关于设备的type。
    domain:
    这一attribute包含了如下所列的所有关于进程的type,通常策略中的访问主体也就是进程所在的domain都包含在了这一attribute中。
    adbd
    trusted_app
    browser_app
    untrusted_app
    bluetoothd
    dbusd
    debuggerd
    drmserver
    gpsd
    init
    installd
    kernel
    keystore
    mediaserver
    netd
    nfc
    qemud
    radio
    rild
    servicemanage
    shell
    surfaceflinger
    su
    system_app
    system
    ueventd
    vold
    wpa
    zygote
    fs_type:
    这一attribute包含了所有与文件系统相关的type。如下所列,大多是虚拟文件系统。
    device
    labeledfs
    pipefs
    sockfs
    rootfs
    proc
    selinuxfs
    cgroup
    sysfs
    sysfs_writable
    inotify
    devpts
    tmpfs
    shm
    mqueue
    sdcard
    debugfs
    file_type:
    这一attribute包含了所有存在于非伪文件系统的相关文件的type,数量过多不再列举。
    exec_type:
    这一attribute包含了所有关于domian接入点的type,多被用在domain transition中,如下所列。
    bluetoothd_exec
    dbusd_exec
    debuggerd_exec
    drmserver_exec
    gpsd_exec
    installd_exec
    keystore_exec
    mediaserver_exec
    netd_exec
    qemud_exec
    rild_exec
    servicemanager_exec
    surfaceflinger_exec
    vold_exec
    wpa_exec
    zygote_exec
    data_file_type:
    这一attribute包含了所有在/data目录下的文件type,如下所列。
    system_data_file
    anr_data_file
    tombstone_data_file
    apk_data_file
    dalvikcache_data_file
    shell_data_file
    gps_data_file
    bluetoothd_data_file
    bluetooth_data_file
    keystore_data_file
    vpn_data_file
    systemkeys_data_file
    wifi_data_file
    radio_data_file
    nfc_data_file
    app_data_file
    sysfs_type:
    这一attribute包含了在sysfs文件系统下的所有文件的type,在SEAndroid中只有sysfs_writable包含在这个attribute中。
    node_type:
    这一attribute包含了所有与nodes/hosts有关的type,在SEAndroid中只有node包含在这个attribute中。
    netif_type:
    这一attribute包含了所有与网络接口相关的type,在SEAndroid中只有netif包含在这个attribute中。
    port_type:
    这一attribute包含了所有与网络端口相关的type,在SEAndroid中只有port包含在这个attribute中。
    mlstrustedsubject:
    这一attribute包含了所有能越过MLS检查的主体domain。
    mlstrustedobject:
    这一attribute包含了所有能越过MLS检查的客体type。
    unconfineddomain:
    这一attribute包含了所有拥有无限权限的type。
    appdomain:
    这一attribute包含了所有与app相关的type,如下所列。
    trusted_app
    browser_app
    untrusted_app
    nfc
    radio
    shell
    system_app
    netdomain:
    这一attribute包含了所有与需要访问网络的app相关的type,如下所列。
    trusted_app
    browser_app
    gpsd
    mediaserver
    radio
    rild
    system
    bluetoothdomain:
    这一attribute包含了所有与需要访问bluetooth的app相关的type,如下所列。
    trusted_app
    radio
    system
    binderservicedomain:
    这一attribute包含了所有与binder服务相关的type,如下所列。
    mediaserver
    surfaceflinger
    system

    通过allow语句制定主体客体强制访问规则(白名单规则,不再规则中的都默认为非法操作)
    通过type_transition语句制定tpye类型转换规则
    通过dontaudit语句声明对一些被安全策略拒绝的访问不再进行审核。
    审核是对于发生了访问违规或出现了被系统安全规则拒绝的行为进行日志记录的过程,审核可以帮助系统管理员发现bug和可能的入侵尝试。
    默认情况下,SEAndroid会记录被拒绝的访问检查,但策略语言dontaudit允许我们取消这些默认的预料之中的拒绝审核消息。

    SEAndroid为系统定义了33个te策略文件,这33个策略文件是:
    adbd.te、file.te、su.te、app.te、gpsd.te、netd.te、system.te、bluetoothd.te、init.te、net.te、ueventd.te、bluetooth.te、installd.te、nfc.te、unconfined.te、cts.te、kernel.te、qemud.te、vold.te、dbusd.te、keystore.te、radio.te、wpa_supplicant.te、debuggerd.te、mediaserver.te、rild.te、zygote.te、device.te、servicemanager.te、domain.te、shell.te、drmserver.te、surfaceflinger.te。

    对上述33个文件根据其策略规则针对的对象可分为三类:
    针对attribute的策略制定:
    attribute是多个具有共性的type的集合,以下六个文件主要是直接针对attribute制定的策略,这种针对attribute制定的策略也就是同时对多个type制定策略一样。
    unconfined.te
    主要是为unconfineddomain属性制定策略,这些策略基本就是对各种访问客体拥有所有的权限。
    domain.te
    主要是为domain属性制定策略,为所有归在其中的访问主体制定一些公共的策略。
    CTS.te
    主要是为appdomain制定策略,这些策略一般是在对app进行CTS测试时用到。
    bluetooth.te
    主要是为bluetoothdomain制定策略。
    net.te
    主要是为netdomain制定策略,这些策略主要是关于对sockets、ports的访问以及与netd的通信。
    file.te
    这个文件主要定义了各文件系统的type,各文件的type,socket的type,以及制定了在不同文件系统中创建文件的规则。

    针对daemon domain的策略制定:
    adbd.te、gpsd.te、netd.te、bluetoothd.te、zygote.te、ueventd.te、installd.te、vold.te、dbusd.te、keystore.te、debuggerd.te、mediaserver.te、rild.te、drmserver.te、surfaceflinger.te、qemud.te、servicemanager.te、su.te、shell.te、wpa_supplicant.te
    这些文件都是为系统中的daemon进程进行策略的制定,它们都有着相应的daemon domain。

    针对系统其他模块的策略制定:
    最后的7个文件分别对系统的其他模块进行策略制定。
    app.te
    在这一文件里将安装在系统上的第三方app分类为受信任的app和不受信任的app,分别用不同的type表示,
    再分别为这两种app在访问网络,bluetooth,sdcard,数据,缓存,binder等等名感位置时设置相应权限。
    system.te
    这一文件主要针对的是系统app和system server进程。对系统app访问binder、system data files、dalvikcatch、keystone等进行权限控制,
    对system server访问网络、bluetooth、netlink、app、binder、device、data files、socket、cache files等进行权限控制。
    init.te
    在这一文件中声明了init拥有无限权限。
    nfc.te
    在这一文件中制定了nfc domain对nfc设备和相关数据文件的访问权限。
    kernel.te
    在这一文件中声明了kernel拥有无限权限。
    radio.te
    在这一文件中制定了radio domain对init、rild和相关数据文件的访问权限。
    device.te
    在这一文件中定义了所有跟设备相关的type,并将这些type都归到了dev_type属性中。

    接下来对SEAndroid中制定的各种繁多的策略做一个简单分类:
    转换(transition)
    domain transition
    某个程序被执行时,其相应的进程会处在相应的domain中,但当程序根据需要又执行了另一个程序时,进程就需要根据type transition规则进行domain transition以获得必要的权限从而使新进程能顺利访问到相关文件。另一个transition的原因是原有的domain权限过大,为了不让新启动的进程也继承过大的权限,因此需要domain transition。 在SEAndroid中几乎全部daemon进程都需要从init进程中启动,这就需要从init domian转换到daemon domain这一操作。
    需要从init domain转换到daemon domain的进程有bluetoothd、dbusd、debuggerd、drmserver、gpsd、installd、keystore、mediaserver、netd、qemud、rild、servicemanager、surfaceflinger、vold、wpa_supplicant、zygote。
    除了从init domain转换到其他daemon domain外,还有从adbd domain转换到shell domain,从shell domain转换到su domain,以及从zygote domain转换到system和appdomain,这主要是因为Android中的大部分进程都是由zygote创建。
    type transition
    type_transition 规则被用在Domain Transition中 或者确定新创建对象的标签,以重载其默认的、从父目录(containing directory)所继承的标签。通常情况下新创建文件的标签和其父目录的标签一致,但是可以使用type_transition规则为其指定特定的标签。
    例如在SEAndroid中gpsd domain在以gps_data_file为type的目录下创建socket文件时,这些文件的type将会依照在策略中设定的type_transition规则而转换为gps_sokcket。
    system domain在以wifi_data_file为type的目录下创建socket文件时,文件的type将会依照type_transition规则转变为system_wpa_socket。

    文件和目录
    在许多主体访问客体的情况中都需要对相关文件进行操作,SEAndroid对于牵涉到blk_file,chr_file,fd,fifo_file,lnk_file,sock_file和一般的file都进行了相关的策略制定。
    还制定了一些domain指定type的目录、一般文件和链接文件只有读的权限的策略,例如dbusd domain对system type和bluetoothd type的目录和文件只有读的权限,domain attribute对proc、sysfs、inotify、cgroup这些虚拟文件系统中的文件和目录也只有读的权限,另外还有mediaserver domain对sdcard type的目录和文件只有读的权限,shell domain对apk_data_file的目录和文件只有读的权限、system domain对mediaserver和appdomain的目录和文件只有读的权限。
    也制定了主体domain对不同文件系统的相关操作权限,以及当某个domain需要创建tmpfs、shmem、ashmem文件时,根据主体domain定义一个独特的type并对新创建的文件进行标记的策略。在SEAndroid里这条策略被用在了init、system、ueventd中。
    无限权限
    在SEAndroid中共定义了三个拥有巨大权限的attribute分别是mlstrustedsubject、mlstrustedobject、unconfineddomain,被分类到mlstrustedsubject的type在充当主体domain是可以越过MLS检查,被分类到mlstrustedobject的type在充当客体时可以越过MLS检查,被分到unconfineddomain的type则拥有所有权限可对客体进行任意操作。
    在SEAndroid中被分在mlstrustedsubject attribute中的type有adbd、debuggerd、drmserver、init、installd、kernel、mediaserver、netd、surfaceflinger、su、system、vold、zygote。
    被分在mlstrustedobject attribute中的type有alarm_device、ashmem_device、binder_device、log_device、mtp_device、nv_device、powervr_device、ptmx_device、null_device、cgroup、sysfs、sysfs_writable、sysfs_writable、sysfs_writable、debugfs、apk_data_file、cache_file、dnsproxyd_socket。
    被分在unconfineddomain的type有init、kernel、su。
    设备
    关于设备这里重点提一下bluetooth,在SEAndroid中只对三个type提供bluetooth访问权限分别是trusted_app、radio、system。
    App
    在SEAndroid中指定了trusted_app、browser_app、untrusted_app、nfc、radio、shell、system_app这些type对系统中的所有app拥有适当的访问权限,并能对ashmem objects使用独特的type进行标记。
    网络
    SEAndroid对trusted_app、browser_app、gpsd、mediaserver、mediaserver、rild、system这些type授予了访问网络的权限。
    在SEAndroid中系统对各类socket都制定了相应的策略,这些socket包括appletalk_socket(转为apple公司产品通信而设)、dccp_socket、netlink_audit_socket、netlink_dnrt_socket、netlink_firewall_socket、netlink_ip6fw_socket、netlink_kobject_uevent_socket、netlink_nflog_socket、、etlink_route_socket、netlink_selinux_socket、netlink_socket、netlink_tcpdiag_socket、netlink_xfrm_socket、packet_socket、rawip_socket、tcp_socket、tun_socket、udp_socket、unix_dgram_socket、unix_stream_socket。
    SEAndroid还指定了如下策略允许一个本地socket从指定的客户端domain通过指定的socket连接到指定的服务端domain,第一列是客户端domain,第二列是指定的socket,第三列是服务端domain。
    adbd, vold, vold
    adbd, property, init
    untrusted_app, dnsproxyd, netd
    bluetoothd, dbus, dbusd
    netdomain, dnsproxyd, netd
    radio, property, init
    radio, rild, rild
    rild, property, init
    rild, qemud, qemud
    surfaceflinger, property, init
    system_app, keystore, keystore
    system, property, init
    system, qemud, qemud
    system, installd, installd
    system, netd, netd
    system, vold, vold
    system, zygote, zygote
    system, keystore, keystore
    system, dbus, dbusd
    system, gps, gpsd
    system, bluetooth, bluetoothd
    vold, property, init

    另外SEAndroid只允许system和wpa这两个domain可以让一个本地socket以system和wpa任何一方为客户端另一方为服务端并通过某个socket进行数据包的发送。 运行一个本地socket从客户端domain通过发送数据包到服务端domain。
    IPC
    SEAndroid只允许adbd、appdomain、drmserver、mediaserver、surfaceflinger、system这些type或attribute通过servicemanager使用binder IPC。
    SEAndroid只允许指定的客户端domain对指定的服务端domain使用binder IPC,如以下所列,第一列是指定的客户端domain,第二列是指定的服务端domain。
    adbd, surfaceflinger
    trusted_app, appdomain
    appdomain, binderservicedomain
    appdomain, trusted_app
    drmserver, system
    mediaserver, binderservicedomain
    mediaserver, appdomain
    surfaceflinger, system
    system_app, appdomain
    system, binderservicedomain
    system, appdomain

    SEAndroid只允许指定的客户端domain传送由服务端创建的binder references,如以下所列,第一列是指定的客户端domain,第二列是指定的服务端domain。
    trusted_app, appdomain
    appdomain, binderservicedomain
    appdomain, trusted_app
    system_app, appdomain
    system, binderservicedomain
    system, appdomain

    MLS(Multi-Level Security)

    什么是MLS,为何要引入MLS
    MLS称为多级别安全是另一种强制访问控制方法,特别适合于政府机密数据的访问控制,早期对计算机安全的研究大多数都是以在操作系统内实现MLS访问控制为驱动的。所有MLS的使用都是建立在TE安全的基础之上。在SELinux中MLS是一个可选访问控制方式,而在SEAndroid中则是被作为安全访问方式的其中之一。

    MLS中的相关参量
    在SEAndroid中mls的相关参量就是安全上下文的第四列称为security level,在安全上下文第四列中可以有一个或者两个security level,第一个表示低安全级别,第二个表示高安全级别。
    每个security level由两个字段组成:
    sensitivity
    sensitivity有着严格的分级,它反应了一个有序的数据灵敏度模型,如政府分类控制中的绝密,机密和无密级。
    category
    category是无序的,它反应的是数据划分的需要。

    基本思路是对于要访问的数据你同时需要足够的sensivity和正确的category。

    在SEAndroid中sensitivity只有一个级别即s0,category共有1024个,因此最低安全级别就是s0,最高安全级别就是s0:c0.c1023。
    security level之间的三种运算关系:
    dom
    需要主体sensitiviety大于客体,同时客体的category是主体的一个子集。
    domby
    与dom完全相反
    eq
    主体客体的sensitivity和category分别相同。

    高的security level对低的security level拥有dom,低的security level对高的security level关系为domby(与dom相反),同级的security关系是eq,这三种关系运算符是SEAndroid中特有的。

    MLS对进程的约束
    限制进程的domain转换
    对于从一个domain转换到另一个domain的操作要求两个domain的高级别security level和低级别security level同时相等才能许可转换,除非是待转换的domain属于对mls无限权限的type。
    限制进程读操作
    只有当主体domain的低级别security level对客体domain的低级别security level具有dom关系时,或者主体domian是属于对mls无限权限的type,主体才能对客体具有读操作的许可。
    这一读操作具体是指:
    能获取进程优先权
    能获取另一进程的session id
    能获取到进程的group id
    能获取到系统的capabilities
    能获取文件的属性信息
    能追踪父程序或子程序的执行
    允许通过clone或fork进程实现状态信息共享
    总结一下就是MLS限制了低级别进程向高级别进程进行读的操作,即不能上读。
    限制进程写操作
    只有当主体domain的低级别security level对客体domain的低级别security level具有domby关系时,或者主体domain是属于对mls无限权限的type,主体才能对客体具有写操作的许可。
    写操作具体是指:
    能发送SIGKILL信号
    能发送SIGSTOP信号
    能发送一个非SIGKILL、SIGSTOP、SIGCHLD的信号
    能设置进程优先级
    能设置进程group id
    能设置系统的capabilities
    能改变进程hard limits
    能追踪父程序或子程序的执行
    允许通过clone或fork进程实现状态信息共享
    总结一下就是MLS限制了高级别进程对低级别进程写的操作,即不能下写。
    MLS对socket的约束
    进程对local socket的访问限制
    只有当主体进程的domain的高级别security level和低级别security level分别与客体local socket的type的security level相同时即满足eq关系时,或者主体客体任何一个具有对mls无限权限的type时,主体进程才对local socket拥有了某些访问权限。
    这些访问权限是指:
    读操作
    写操作
    新建操作
    能获取对象属性信息
    能设置对象的属性信息
    能对对象重新标记安全上下文
    能进行bind操作
    能发起一个连接请求
    能监听连接事件
    能接受一个连接请求
    能获取到socket options
    能关闭socket连接
    对socket的datagram发送的限制
    只有当发送方的低级别security level与接受方的低级别security level满足domby关系时,或者主体客体任何一个具有对mls无限权限的type时,发送方才对接受方拥有了发送权限。
    对客户端socket和服务端socket建立连接的限制
    只有当客户端的低级别security level与服务端的低级别security level满足eq关系时,或者主体客体任何一个具有对mls无限权限的type时,客户端就能获得连接服务端的权限。
    MLS对文件和目录的约束
    对文件的创建和重新标记的限制
    对文件操作时,要求客体的文件安全上下文只有一个security level即没有低级别和高级别security level或者说是这两个级别相同。 当主体domain的低级别security level对客体文件的低级别security level相同时,或者主体具有对mls有无限权限的type时,主体对客体文件拥有创建、和重新标记安全上下文的权限。
    对目录的读操作的限制
    只有当主体的低级别security level对客体目录的低级别security level满足dom关系时,或者主体客体任何一个具有对mls无限权限的type时,主体能对目录拥有如下权限:
    能读目录
    能获得目录的属性信息
    能获得某个正在被访问文件的所有上层目录访问权(search权限)
    总结一下就是对目录的访问不能上读。
    对文件的读操作的限制
    只有当主体的低级别security level对客体文件的低级别security level满足dom关系时,或者主体客体任何一个具有对mls无限权限的type时,主体能对文件拥有如下权限:
    能读文件
    能获得文件的属性信息
    能执行该文件
    总结一下就是对文件的访问不能上读。
    对目录的写操作的限制
    只有当主体的低级别security level对客体目录的低级别security level满足domby关系时,或者主体客体任何一个具有对mls无限权限的type时,主体能对目录拥有如下权限:
    能对目录写操作
    能设置属性信息
    能重命名目录
    能添加一个文件到目录中
    能从目录中删除一个文件
    能改变父目录
    能删除一个空目录
    总结一下就是对目录访问不能下写。
    对文件的写操作的限制
    只有当主体的低级别security level对客体文件的低级别security level满足domby关系时,或者主体客体任何一个具有对mls无限权限的type时,主体能对文件拥有如下权限:
    能对文件进行写操作
    能设置文件属性信息
    能对文件内容作append操作
    能对文件创建链接
    能删除一个文件的链接
    能对文件重命名
    总结一下就是对文件访问不能下写。
    MLS对IPC的约束
    对IPC创建和销毁的限制
    要求客体的IPC对象只有一个security level。
    只有当主体的低级别security level与客体的低级别security level满足eq关系时,或者主体具有对mls无限权限的type时,主体能对客体IPC拥有创建和销毁的权限。
    对IPC读操作的限制
    只有当主体的低级别security level对客体IPC的低级别security level满足dom关系时,或者主体具有对mls无限权限的type时,主体能对客体IPC拥有如下权限:
    获取文件属性信息
    能对IPC文件执行读操作
    能关联一个key
    能执行由IPC操作要求的读操作
    总结一下就是对IPC访问不能上读。
    对IPC写操作的限制
    只有当主体的低级别security level对客体IPC的低级别security level满足domby关系时,或者主体具有对mls无限权限的type时,主体能对客体IPC拥有如下权限:
    能对文件执行write和append操作
    能执行由IPC操作要求的write和append操作
    总结一下就是对IPC访问不能下写。

    展开全文
  • Seandroid 基础

    2019-01-17 17:33:00
     SEAndroid 是 Google 在 Android 4.4 上正式推出的一套以SELinux 为基础与核心的系统安全机制。而 SELinux 则是由美国 NSA(国安局)和一些公司(RedHat、Tresys)设计的一个针对 Linux的安全加强系统。  ...
  • 为此,NSA针对Android系统,在SELinux基础上开发了SEAndroid。本文就对SEAndroid安全机制框架进行分析,以便后面可以更好地分析其实现细节。SEAndroid安全机制所要保护的对象是系统中的资源,这些资源分布在各个子...
  • SEAndroid app

    2017-03-18 13:47:30
    SELinux app权限配置 untrusted_app ...SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):(1)untrusted_app 第三方app,没有Android平
  • 深入理解Android SEAndroid
  • SEAndroid 问题

    2018-01-08 19:16:46
    在Android的底层开发过程中经常会遇到SEAndroid的avc权限问题: 首先是avc log:   avc: denied { search } forpid=8329 comm="memmst" name="lowmemorykiller"dev="sysfs" ino=...
  • SEAndroid 相关知识

    2019-12-02 16:24:14
    本文图片和内容摘自罗升阳的博客《SEAndroid安全机制框架分析》 如需了解详细内容,请访问原博客。 1. 整体框架 SEAndroid安全机制框架 SEAndroid安全机制包含有内核空间和用户空间两部分支持: 在内核空间,...
  • SEAndroid简介

    千次阅读 2016-03-09 19:17:25
    SEAndroid简介 http://blog.csdn.net/modianwutong/article/details/43114883  SEAndroid是Google在Android4.4上正式推出的一套以SELinux为核心的系统安全机制。而SELinux则是由NSA(美国国安局)在Linux社区的...
  • SEAndroid概述

    千次阅读 2013-05-21 23:21:10
     SEAndroid是将selinux移植到android操作系统,并根据android特性进行改进的操作系统。SEAndroid中加入了SElinux如下访问控制,也开发了android特有的中间 件层访问控制    SE Linux通过事先定义每个...
  • SEAndroid问题解决

    千次阅读 2017-09-29 11:36:39
    Android从4.4版本引入SEAndroid,SEAndroid是一套基于SELinux做的系统安全机制。SEAndroid有三种模式:Enforcing,Permissive,Disabled。Enforcing状态下,所有违反SEAndroid策略的操作都会被禁止执行并显示警告信息,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 753
精华内容 301
关键字:

seandroid