SELinux的标签

作者: 杰杰_88 | 来源:发表于2020-02-24 18:08 被阅读0次

    进程和文件/目录的标签查看

    在支持SELinux的系统中,所有的进程都有一个SELinux的标签,查看进程的标签可以用下面的命令:

    adb shell ps -Z

    下面是Android 8.1.0模拟器上执行这个命令的结果(去掉了kernel、init等开发中很少有需要修改的进程):

    LABEL                          USER           PID  PPID     VSZ    RSS WCHAN            ADDR S NAME
    u:r:logd:s0                    logd          1367     1   16840   6808 sigsuspend   ed3c3af0 S logd
    u:r:servicemanager:s0          system        1368     1    7268   3436 binder_thread_read f4944af0 S servicemanager
    u:r:hwservicemanager:s0        system        1369     1   11840   5956 ep_poll      f260baf0 S hwservicemanager
    u:r:vndservicemanager:s0       system        1370     1    7036   2916 binder_thread_read f70c4af0 S vndservicemanager
    u:r:hal_sensors_default:s0     system        1432     1   11012   4444 goldfish_pipe_wait_event f1a1daf0 S android.hardware.sensors@1.0-service
    u:r:hal_wifi_default:s0        wifi          1433     1   13408   7140 binder_thread_read eb6b4af0 S android.hardware.wifi@1.0-service
    u:r:surfaceflinger:s0          system        1439     1   95676  14016 ep_poll      f2bffaf0 S surfaceflinger
    u:r:zygote:s0                  root          1521     1  938536 111344 poll_schedule_timeout ece25af0 S zygote
    u:r:audioserver:s0             audioserver   1522     1  111216  23716 binder_thread_read ecc8daf0 S audioserver
    u:r:cameraserver:s0            cameraserver  1523     1   34264  13024 binder_thread_read f37d6af0 S cameraserver
    u:r:installd:s0                root          1525     1   15216   5384 binder_thread_read ebcf0af0 S installd
    u:r:mediaserver:s0             media         1530     1   59748  16252 binder_thread_read f210daf0 S mediaserver
    u:r:system_server:s0           system        1648  1521 1194488 188812 ep_poll      ece25af0 S system_server
    u:r:untrusted_app:s0:c512,c768 u0_a60        1771  1521 1129228 162444 ep_poll      ece25af0 S com.google.android.inputmethod.latin
    u:r:platform_app:s0:c512,c768  u0_a29        1786  1521 1160968 151208 ep_poll      ece25af0 S com.android.systemui
    u:r:radio:s0                   radio         1897  1521 1054988 104428 ep_poll      ece25af0 S com.android.phone
    u:r:priv_app:s0:c512,c768      u0_a13        2222  1521 1176236 157432 ep_poll      ece25af0 S com.google.android.gms.persistent
    u:r:priv_app:s0:c512,c768      u0_a13        2594  1521 1279688 165100 ep_poll      ece25af0 S com.google.android.gms
    u:r:su:s0                      root          5396     1   67840   2584 0            edb8caf0 R adbd
    u:r:untrusted_app:s0:c512,c768 u0_a80       11407  1521 1027772  64308 ep_poll      ece25af0 S personal.jayhou.mydemos
    u:r:untrusted_app:s0:c512,c768 u0_a80       11433  1521 1015452  49760 ep_poll      ece25af0 S personal.jayhou.mydemos:remote
    u:r:untrusted_app:s0:c512,c768 u0_a89       27497  1521 1044488  70976 ep_poll      ece25af0 S com.chehejia.car.binderobjectdemo
    u:r:untrusted_app:s0:c512,c768 u0_a89       27527  1521 1015420  49684 ep_poll      ece25af0 S com.chehejia.car.binderobjectdemo:remote
    u:r:untrusted_app:s0:c512,c768 u0_a69       31743  1521 1044024  88188 ep_poll      ece25af0 S com.google.android.apps.messaging
    u:r:untrusted_app:s0:c512,c768 u0_a69       31770  1521 1085220  92980 ep_poll      ece25af0 S com.google.android.apps.messaging:rcs
    u:r:priv_app:s0:c512,c768      u0_a13       32075  1521 1077256 101724 ep_poll      ece25af0 S com.google.android.gms.unstable
    u:r:priv_app:s0:c512,c768      u0_a20       32138  1521 1015476  51544 ep_poll      ece25af0 S com.google.android.partnersetup
    u:r:untrusted_app:s0:c512,c768 u0_a70       32195  1521 1057228  76832 ep_poll      ece25af0 S com.google.android.apps.photos
    u:r:untrusted_app:s0:c512,c768 u0_a47       32377  1521 1041400  72796 ep_poll      ece25af0 S com.google.android.calendar
    u:r:priv_app:s0:c512,c768      u0_a3        32394  1521 1014252  57424 ep_poll      ece25af0 S com.android.providers.calendar
    u:r:untrusted_app:s0:c512,c768 u0_a68       32425  1521 1030692  67892 ep_poll      ece25af0 S com.google.android.deskclock
    u:r:mediaprovider:s0:c512,c768 u0_a9        32451  1521 1016188  59392 ep_poll      ece25af0 S android.process.media
    u:r:priv_app:s0:c512,c768      u0_a31       32490  1521 1019140  57968 ep_poll      ece25af0 S com.google.android.apps.wallpaper
    

    可以看到,主要的进程有这么几类

    native进程如 logd 其SELinux标签为 u:r:logd:s0,servicemanager 其SELinux标签为 u:r:servicemanager:s0 等

    hal服务进程 如android.hardware.sensors@1.0-service 进程的SELinux标签为 u:r:hal_sensors_default:s0,android.hardware.wifi@1.0-service 进程的SELinux标签为 u:r:hal_wifi_default:s0 等。

    native 服务 如surfaceflinger 其SELinux标签为u:r:surfaceflinger:s0 以及zygote、audioserver、cameraserver、mediaserver等

    java服务进程 system_server 其SELinux标签为 u:r:system_server:s0

    有platform签名的app 如com.android.systemui 的SELinux标签为 u:r:platform_app:s0:c512,c768

    priv-app 如 com.google.android.gms.persistent 的SELinux标签是 u:r:priv_app:s0:c512,c768

    普通三方app 我自己写的demo app personal.jayhou.mydemos 的SELinux标签为 u:r:untrusted_app:s0:c512,c768

    然后去/data/data目录下看看文件/目录的SELinux标签:

    adb shell进入设备,在/data/data/目录下执行 ls -Z

    u:object_r:system_app_data_file:s0    android
    u:object_r:app_data_file:s0:c512,c768 personal.jayhou.mydemos
    

    基本上就是这么两类,一些特殊的目录有特殊的标签。(其他目录的标签很多,看这个目录下的标签主要是app目录带有c512,c768不同于其他目录的标签段)

    标签字段及含义如下:
    [user]:[role]:[type]:[sec-level]
    user:表示selinux中定义的用户名,android中只有一个用户定义为u
    role:表示selinux中定义的角色名,android中进程都定义为r,文件都定义为object_r
    domain:文件/进程所属的域,file_contexts定义了文件/目录所属的域,进程所属的域Android中分为了几个文件来定义
    seapp_contexts定义了大部分android app 根据各种条件以及签名来确定进程所属的域类型
    sec-level:安全等级
    注意到三方app目录、进程都有c512,c768的额外标签字段,这个是SELinux的MCS(多类别强制执行模型)参考这个文章的第二部分。

    SEAndroid中标签的定义

    这些标签都是由SELinux安全上下文文件定义,在如下文件中,定义了相关文件、设备、服务(名)等非进程类的对象标签

    file_contexts、property_contexts、service_contexts、hwservice_contexts等

    java世界进程的SELinux标签由seapp_contexts文件定义,zygote根据启动java进程的相关信息,结合seapp_contexts中的条件来给java进程打SELinux TAG

    frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

      if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
        fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
                             uid, is_system_server, se_info_ptr, nice_name_ptr));
      }
    

    android/system/sepolicy/private/seapp_contexts

    这个文件定义了android默认的app安全上下文的标签设置策略:

    isSystemServer=true domain=system_server
    user=system seinfo=platform domain=system_app type=system_app_data_file
    user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
    user=nfc seinfo=platform domain=nfc type=nfc_data_file
    user=radio seinfo=platform domain=radio type=radio_data_file
    user=shared_relro domain=shared_relro
    user=shell seinfo=platform domain=shell type=shell_data_file
    user=_isolated domain=isolated_app levelFrom=user
    user=_app seinfo=media domain=mediaprovider name=android.process.media type=app_data_file levelFrom=user
    user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
    user=_app isV2App=true isEphemeralApp=true domain=ephemeral_app type=app_data_file levelFrom=user
    user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user
    user=_app minTargetSdkVersion=26 domain=untrusted_app type=app_data_file levelFrom=user
    user=_app domain=untrusted_app_25 type=app_data_file levelFrom=user
    

    这些配置都会在Zygote fork出app进程时,调用selinux_android_setcontext的过程中去匹配
    如随便写个minTargetSdkVersion>=26的hello world apk安装进去启动,显然其user=_app seinfo!=platform(根据签名判断),根据编译app TargetSdkVersion是否>=26 (没有 minTargetSdkVersion=26 这个配置则表示minTargetSdkVersion=0 )最后会匹配到这一条:

    user=_app minTargetSdkVersion=26 domain=untrusted_app type=app_data_file levelFrom=user

    那么该进程就被设置安全上下文标签为u:r:untrusted_app:s0:c512,c768(c512,c768这个字段是根据levelFrom=user打的)
    具体每个字段意思可以仔细阅读seapp_contexts前面的注释

    其中有的配置项包含seinfo=platform这样的,这个表示要匹配到这一条的进程,必须拥有platform签名,具体platform匹配什么签名在如下文件中定义

    android/system/sepolicy/private/mac_permissions.xml

    还可以自定义其他的seinfo对应不同的签名来配置seapp_contexts。

    其他上面提到的native进程如logd、servicemanager,native服务hal service,Android其他native 服务进程如surfaceflinger mediaserver等进程的标签,主要由以下两个方式设置:

    init.rc中可以由类似 seclabel u:r:shell:s0 的配置来定义init启动的进程的SELinux 标签

    另一种拿surfaceflinger进程为例,其对应的策略文件:

    android/system/sepolicy/private/surfaceflinger.te

    有如下定义:

    init_daemon_domain(surfaceflinger)
    

    根据其宏定义展开

    android/system/sepolicy/public/te_macros

    #####################################
    # init_daemon_domain(domain)
    # Set up a transition from init to the daemon domain
    # upon executing its binary.
    define(`init_daemon_domain', `
    domain_auto_trans(init, $1_exec, $1)
    ')
    
    #####################################
    # domain_auto_trans(olddomain, type, newdomain)
    # Automatically transition from olddomain to newdomain
    # upon executing a file labeled with type.
    #
    define(`domain_auto_trans', `
    # Allow the necessary permissions.
    domain_trans($1,$2,$3)
    # Make the transition occur by default.
    type_transition $1 $2:process $3;
    ')
    
    #####################################
    # 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 new domain.
    allow $1 $2:file { getattr open read execute map };
    allow $1 $3:process transition;
    # New domain is entered by executing the file.
    allow $3 $2:file { entrypoint open read execute getattr map };
    # New domain can send SIGCHLD to its caller.
    ifelse($1, `init', `', `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 };
    ')
    

    所以编译后的init_daemon_domain(surfaceflinger)
    第一次展开为:

    domain_auto_trans(init, surfaceflinger_exec, surfaceflinger)
    

    第二次展开为:

    domain_trans(init,surfaceflinger_exec,surfaceflinger)
    type_transition init surfaceflinger_exec:process surfaceflinger;
    

    最终展开为:

    # Old domain may exec the file and transition to the new domain.
    allow init surfaceflinger_exec:file { getattr open read execute map };
    allow init surfaceflinger:process transition;
    # New domain is entered by executing the file.
    allow surfaceflinger surfaceflinger_exec:file { entrypoint open read execute getattr map };
    # New domain can send SIGCHLD to its caller.
    ifelse(init, `init', `', `allow surfaceflinger init:process sigchld;')
    # Enable AT_SECURE, i.e. libc secure mode.
    dontaudit init surfaceflinger:process noatsecure;
    # XXX dontaudit candidate but requires further study.
    allow init surfaceflinger:process { siginh rlimitinh };
    
    type_transition init surfaceflinger_exec:process surfaceflinger;
    

    init_daemon_domain(surfaceflinger) 展开后,前面一大堆是为后面一句做的权限准备,最后一句type_transition init surfaceflinger_exec:process surfaceflinger; 是说 init 域的进程在执行type为surfaceflinger_exec的可执行文件时,将其(process)转换到surfaceflinger域,从标签来说就是,init进程启动surfaceflinger时,不允许surfaceflinger继承其标签 u:r:init:s0 而是要将surfaceflinger的标签变成 u:r:surfaceflinger:s0。

    所以类似surfaceflinger这种由init启动的native进程/服务,其标签要么是init.rc中由seclable 命令指定 ,要么是其对应的.te文件中由规则init_daemon_domain()宏声明,由init进程域转到了init_daemon_domain()声明的域中。

    相关文章

      网友评论

        本文标题:SELinux的标签

        本文链接:https://www.haomeiwen.com/subject/fbehqhtx.html