您的位置:首页 > 移动开发 > Android开发

进程的安全上下文----SEAndroid in android 5.x

2015-12-02 15:21 856 查看
SEAndroid使用两种方式为进程设置安全上下文

1.为独立进程静态的设置安全上下文

      这和传统的LInux系统很像。android系统中的每个独立进程都对应着一个可执行文件。

      以init为例,查看init进程的启动脚本system/core/rootdir/init.rc,部分内容如下:

on early-init

   ...........

    # Set thesecurity context for the init process.

    # Thisshould occur before anything else (e.g. ueventd) is started.

    setconu:r:init:s0

这一行的作用是让init进程将自己的安全上下文设为u:r:init:s0。

查看external/sepolicy/init.te中,init这个domain的规则:

# init switches to init domain (via init.rc).

type init, domain;

# init is unconfined.

unconfined_domain(init)

tmpfs_domain(init)

allow init self:capability { sys_rawio mknod };

.........

domain_trans(init, rootfs, adbd)

.........

neverallow { domain -kernel} init:process dyntransition;

..........

首先(除注释以外)第一行,type init, domain;声明init具有domain的属性。这样它就可以和u,r一起,组成合法的安全上下文。

第二行unconfined_domain(init) unconfined_domain是一个宏,定义在external/sepolicy/te_macros文件中,声明init是一个不受限制的domain,它可以访问系统中的大部分资源。宏定义如下:

#####################################

# unconfined_domain(domain)

# Allow the specified domain to perform more privilegedoperations

# than would be typically allowed. Please see the comments atthe

# top of unconfined.te.

#

define(`unconfined_domain', `

typeattribute $1 mlstrustedsubject;

typeattribute $1 unconfineddomain;

')

第三行tmpfs_domain(init) 也是一个宏,也定义在external/sepolicy/te_macros文件中。声明当domain为init的进程在type为tmpfs的目录中创建文件时,该新建文件的type为init_tmpfs,并允许domain为init的进程对这些文件进行读写操作。宏定义如下:

#####################################

# tmpfs_domain(domain)

# Define and allow access to a unique type for

# this domain when creating tmpfs / shmem / ashmem files.

define(`tmpfs_domain', `

type $1_tmpfs, file_type;

type_transition $1 tmpfs:file $1_tmpfs;

allow $1 $1_tmpfs:file { read write };

')

第四行是一个allow语句,关于allow语句的含义,之前写过,这里不重复了。

第五行domain_trans(init, rootfs, adbd) 也是宏,位置也在te_macros文件中。声明domain为init的进程,可以通过执行type为rootfs的文件,进入名为adbd的domain。也就是说init进程可以执行/sbin/adbd(该文件type为rootfs),从而进入adbd。这个过程中涉及到多个许可,具体宏定义如下:

#####################################

# domain_trans(olddomain, type, newdomain)

# Allow a transition from olddomain to newdomain

# upon executing a file labeled with type.

# This only allows the transition; it does not

# cause it to occur automatically - use domain_auto_trans

# if that is what you want.

#

define(`domain_trans', `

# Old domain may exec the file and transition to the newdomain.

allow $1 $2:file { getattr open read execute };

allow $1 $3:process transition;

# New domain is entered by executing the file.

allow $3 $2:file { entrypoint open read execute getattr };

# New domain can send SIGCHLD to its caller.

allow $3 $1:process sigchld;

# Enable AT_SECURE, i.e. libc secure mode.

dontaudit $1 $3:process noatsecure;

# XXX dontaudit candidate but requires further study.

allow $1 $3:process { siginh rlimitinh };

')

第六行neverallow { domain -kernel} init:process dyntransition,neverallow规则主要作用是确保allow规则的正确性。具体含义之前也写过,不重复了。

再看zygote进程,与init进程类似。在system/core/rootdir/init.zygote32.rc中(类似的还有三个文件32,64之类的,应该和处理器有关):

service zygote /system/bin/app_process -Xzygote /system/bin--zygote --start-system-server

    classmain

    socketzygote stream 660 root system

    onrestartwrite /sys/android_power/request_state wake

    onrestartwrite /sys/power/state on

    onrestartrestart media

    onrestartrestart netd

说明zygote进程对应的可执行文件为/system/bin/app_process,查看external/sepolicy/file_contexts,发现/system/bin/app_process的安全上下文是u:object_r:zygote_exec:s0 如下:

/system/bin/app_process32   u:object_r:zygote_exec:s0

/system/bin/app_process64   u:object_r:zygote_exec:s0

查看zygote.te,其中大部分规则都很熟悉,剩下不熟悉的:

第一个,init_daemon_domain(zygote) 是一个宏,声明当一个domain为init的进程创建一个子进程执行一个type为zygote_exec的文件时,将该子进程的domain设置为zygote,而不是继承父进程的domain。并且给与zygote这个domain,所有定义在tmpfs_domain宏中的权限。

第二个,typeattribute zygote mlstrustedsubject; typeattribute和type很类似,都是通过声明属性的方式来获取权限。不过type是得到其他domain的权限。而typeattribute之后跟的mlstrustedsubject,是一个属性,而非domain。另外,所有的attribute都在attributes文件中定义。

第三组,三个跟selinux相关的宏:

# Check validity of SELinux context before use.

selinux_check_context(zygote)

# Check SELinux permissions.

selinux_check_access(zygote)

# Read /seapp_contexts and /data/security/seapp_contexts

security_access_policy(zygote)

宏定义如下:

#####################################

# selinux_check_context(domain)

# Allow domain to check SELinux contexts via selinuxfs.

define(`selinux_check_context', `

allow $1 selinuxfs:file rw_file_perms;

allow $1 kernel:security check_context;

')

#####################################

# selinux_check_access(domain)

# Allow domain to check SELinux permissions via selinuxfs.

define(`selinux_check_access', `

allow $1 selinuxfs:file rw_file_perms;

allow $1 kernel:security compute_av;

allow $1 self:netlink_selinux_socket *;

')

#####################################

# security_access_policy(domain)

# Read only access to all policy files and

# selinuxfs

define(`security_access_policy', `

allow $1 security_file:dir r_dir_perms;

allow $1 security_file:file r_file_perms;

')

2.为应用程序进程设置安全上下文

      按照前面提过的,每个APP都会在mac_permissions.xml中找到一个对应的seinfo,然后在seapp_contexts中找到对应的domain和type。其中,domain就用来给应用程序进程当作安全上下文了。

      详细地说,在android5.x中,为支持多用户,应用程序的UID由两部分组成,User Id和App Id。赋值方法:

    userid = uid/ AID_USER;

    appid = uid% AID_USER;

其中,AID_USER是一个常量,值为100000。

      AppId小于AID_APP(10000)是保留给系统使用的,它们对应的username保存在数组android_ids中,具体可以参考文件system/core/include/private/android_filesystem_config.h。

      AppId大于等于AID_APP(10000)并且小于AID_ISOLATED_START(99000)是分配给应用程序使用的,它们对应的username统一设置为“_app”。      

      AppId大于等于AID_ISOLATED_START(99000)是分配给运行在独立沙箱(没有任何自己的Permission)的应用程序使用的,它们对应的username统一设置为“_isolated”

      再查看external/sepolicy/seapp_contexts文件:
isSystemServer=true domain=system_server
user=system domain=system_app type=system_app_data_file
user=bluetooth domain=bluetooth type=bluetooth_data_file
user=nfc domain=nfc type=nfc_data_file
user=radio domain=radio type=radio_data_file
user=shared_relro domain=shared_relro
user=shell domain=shell type=shell_data_file
user=_isolated domain=isolated_app
user=_app seinfo=platform domain=platform_apptype=app_data_file
user=_app domain=untrusted_app type=app_data_file
      第一行到第七行的user都是系统预设的,可以在android_filesystem_config.h中找到。

      第八行,将运行在独立沙箱的应用程序的domain设为isolated_app。

      第九行的seinfo对应着mac_pernissions.xml文件中设置的seinfo。APP通过签名和包名得到对应的seinfo,并进而得到domain和type。

      第十行对应着那些seinfo是default的APP。他们的domain都是untrusted_app,type都是app_data_file。所有第三方APP和部分系统APP,都会被分到这一部分。

       又有一个地方可以动手脚,为访客用户设置一个新的domain用。

       在external/libselinux/src/android.c的seapp_context_lookup中,可以根据userid来改变访客用户的username为anrom_app。再配合external/sepolicy/seapp_contexts中增加新的条目:

user=anrom_app domain=anrom_app type=anrom_app_data_file

就可以将所有访客用户的app的domain和type改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: