当前位置:   article > 正文

Android App Selinux seapp权限详解_android 添加selinux权限

android 添加selinux权限

目录

一、 系统原理详解

二、代码流程分析

 三、其他


一、 系统原理详解

      经常修改和增加一般是内核态的进程,设备节点,但对Android App加权限的介绍并

不多见,同时在原理方面介绍的比较少。 Android 在App上首先通过签名划分第一大类,

platform,system,media,share等等,然后是在同一类key下,建立不同的uid,gid来

进一步区分。                              签名key   ---------------    顶层根

                                               /        |         \

                                           /            |           \

                               Platform       System      media    share  ....    device/mediatek/common/security

                             /        |      \         media.pk8   platform.pk8   shared.pk8

                           /         |          \

              user=system  bluetooth  nfc   radio  shell   _app _isolated 

          system_app -> external\sepolicy\system_app.te
          untrusted_app -> external\sepolicy\untrusted_app.te
          platform_app -> external\sepolicy\platform_app.te          

二、代码流程分析

1.   system\sepolicy\private  keys.conf

           [@TESTSEC]
           ALL : $DEFAULT_SYSTEM_DEV_CERTIFICATE/testsec.x509.pem

           device/mediatek/common/security/testsec.x509.pem

       The keys.conf file is used for controlling the mapping of "tags" found in
        the mac_permissions.xml signature stanzas with actual public keys found in
        pem files. 

       增加一对RSA公私秘钥对,证书,给apk签名使用

2.  添加mac_permissions.xml

 <!-- testsec key in AOSP -->
    <signer signature="@TESTSEC" >
      <seinfo value="testsec" />
    </signer>

3.  Android.mk

$(HOST_OUT_EXECUTABLES)/insertkeys.py -t $(TARGET_BUILD_VARIANT) -c $(TOP) $< -o $@ $(PRIVATE_MAC_PERMS_FILES)

4.  system/sepolicy/public/te_macros

#####################################
# app_domain(domain)
# Allow a base set of permissions required for all apps.
define(`app_domain', `
typeattribute $1 appdomain;
# Label ashmem objects with our own unique type.
tmpfs_domain($1)
# Map with PROT_EXEC.
allow $1 $1_tmpfs:file execute;
neverallow { $1 -shell } { domain -$1 }:file no_rw_file_perms;
neverallow { appdomain -shell -$1 } $1:file no_rw_file_perms;
')

#####################################
# untrusted_app_domain(domain)
# Allow a base set of permissions required for all untrusted apps.
define(`untrusted_app_domain', `
typeattribute $1 untrusted_app_all;
')

#####################################
# net_domain(domain)
# Allow a base set of permissions required for network access.
define(`net_domain', `
typeattribute $1 netdomain;
')
 

5.   system/sepolicy/private/seapp_contexts  注意下顺序,这是脚本文件,添加一个新seinfo时,

要优先放前面。

user=_isolated domain=isolated_app levelFrom=all
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=all
user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user

6.  selinux/libselinux/src/android/android.c seapp_context_cmp()

7.   packages\apps  自定义uid,配置一组apk权限; UID 通过和AID建立对应联系

      include/private/android_filesystem_config.h

      android:sharedUserId="android.uid.testuid"

#define AID_RADIO 1001           /* telephony subsystem, RIL */
#define AID_BLUETOOTH 1002       /* bluetooth subsystem */
#define AID_GRAPHICS 1003        /* graphics devices */
#define AID_INPUT 1004           /* input devices */
#define AID_AUDIO 1005           /* audio devices */
#define AID_CAMERA 1006          /* camera devices */
#define AID_LOG 1007             /* log devices */
#define AID_COMPASS 1008         /* compass device */
#define AID_MOUNT 1009           /* mountd socket */
#define AID_WIFI 1010            /* wifi subsystem */

static const struct android_id_info android_ids[] = {
    { "root",          AID_ROOT, },
    { "system",        AID_SYSTEM, },
    { "radio",         AID_RADIO, },
    { "bluetooth",     AID_BLUETOOTH, },
    { "graphics",      AID_GRAPHICS, },
    { "input",         AID_INPUT, },
    { "audio",         AID_AUDIO, },
    { "camera",        AID_CAMERA, },
    { "log",           AID_LOG, },
    { "compass",       AID_COMPASS, },
    { "mount",         AID_MOUNT, },
    { "wifi",          AID_WIFI, },
    { "adb",           AID_ADB, },


/*
 * android_ids has moved to pwd/grp functionality.
 * If you need to add one, the structure is now
 * auto-generated based on the AID_ constraints
 * documented at the top of this header file.
 * Also see build/tools/fs_config for more details.
 */  ----------最新版本说明

build/make/tools/fs_config/fs_config_generator.py

@generator('aidarray')
class AIDArrayGen(BaseGenerator):
    """Generates the android_id static array."""

 _OPEN_ID_ARRAY = 'static const struct android_id_info android_ids[] = {

测试了下脚本:

python  build/tools/fs_config/fs_config_generator.py aidarray  system/core/libcutils/include/private/android_filesystem_config.h   

8. MLS(Multi-Level Security)  什么是MLS,为何要引入MLS

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

本质问题: MLS在安全策略上有一个形象的描述叫no write down和no read up

    1  低级别的东西只能往高级别的东西里边写数据

    2  低级别的东西不能从高级别的东西那边读数据

  -----这个经典的解释就是:

      员工必须向领导汇报问题,讲报告写在领导给你分配的目录下。

      领导可以查看员工所有的一切信息,无需去写员工的数据,只需要结果就好,然后分析,判断

在SEAndroid中sensitivity只有一个级别即s0,category共有1024个,因此最低安全级别就是s0,最高安全级别就是s0:c0.c1023。

sensitivity和category组合一起声明了当前的安全级别(security level),“-”号左右分别标识了安全级别的最低和最高,这一列的参数将在MLS约束检查时用到,“15”、“1023”表示了sensitivity和category的最大值,这一参数可在Android.mk中定义。

 type testmetad, domain, mlstrustedsubject;  忽略这个c512, c600问题

 typeattribute teei_client_device mlstrustedobject;

 type usb_device, dev_type, mlstrustedobject;

 type devpts, fs_type, mlstrustedobject;

9.  添加默认权限system/core/libcutils/fs_config.cpp 

static const struct fs_path_config android_dirs[] = {
    // clang-format off
    { 00770, AID_SYSTEM,       AID_CACHE,        0, "cache" },
    { 00555, AID_ROOT,         AID_ROOT,         0, "config" },
    { 00771, AID_SYSTEM,       AID_SYSTEM,       0, "data/app" },

10.所有的Android App或用户程序,Server都只是是Selinux的使用者,上层所有的.te等文件

仅仅只是规则的编写而已,所以只要遵循规则便可定制,无需修改代码。

11.  neverallow { appdomain -nfc } nfc_device:chr_file

     neverallow { domain -system_server -vdc -vold } vold_service:service_manager find;

     -表示排除对应的进程,不在范围内。

12 编译错误

         SELinux: The following types were found added to the policy without an entry into the compatibility mapping file(s) found in private/compat/26.0/26.0[.ignore].cil/nlid_service

         需要在prebuilts目录下的sepolicy中添加相同的内容

         参考Android 源代码:  注意其中的细微差别

               device\mediatek\common\BoardConfig.mk

              关键宏   BOARD_SEPOLICY_DIRS    BOARD_PLAT_PUBLIC_SEPOLICY_DIR    BOARD_PLAT_PRIVATE_SEPOLICY_DIR

    BOARD_PREBUILTS_FULL_PUBLIC_PLAT_DIRS    BOARD_PREBUILTS_FULL_PRIVATE_PLAT_DIRS   

    BOARD_COMPAT_MAPPING_CIL_DIRS     BOARD_COMPAT_MAPPING_IGNORE_CIL_DIRS   

    BOARD_26.0_NONPLAT_FILE            BOARD_PLAT_PUBLIC_SEPOLICY_DIR   BOARD_PLAT_PRIVATE_SEPOLICY_DIR

13.  Log:

system/sepolicy/Android.mk:410: warning: "PLAT_PUBLIC_POLICY is " system/sepolicy/public device/mediatek/sepolicy/basic/plat_public device/mediatek/sepolicy/bsp/plat_public
system/sepolicy/Android.mk:411: warning: "sepolicy build files" security_classes initial_sids access_vectors global_macros neverallow_macros mls_macros mls_decl mls policy_capabilities te_macros attributes ioctl_defines ioctl_macros *.te roles_decl roles users initial_sid_contexts fs_use genfs_contexts port_contexts

 三、其他

type hal_camera_default, domain;
hal_server_domain(hal_camera_default, hal_camera)

### add for 
vndbinder_use(hal_camera_default)
hwbinder_use(hal_camera_default)

#allow hal_camera_default vndbinder_device:chr_file { open read write ioctl};
#allow hal_camera_default binder_device:chr_file { open read write ioctl};

full_treble_only(`
  neverallow {
    domain
    -coredomain
    -appdomain
    -hal_camera
    -binder_in_vendor_violators # TODO(b/35870313): Remove once all violations are gone
  } binder_device:chr_file rw_file_perms;
')

输入命令ps -Z -A能够查询当前所有进程的安全属性

进程SContext的type字段代表该进程所属的Domain(域名),个人理解domain就跟tcp协议栈里面的域名一样,它对应于一类进程,

后文将要讲解的安全策略就会应用于该类的所有进程,即相同type的进程具有相同的访问权限。

在Android系统根目录执行ls -l  -Z命令,能够查看根目录文件的SContext。大多数资源的SContext的user值为u代表SEAndroid用户;

role值为object_r代表文件;range值为s0。

SEAndroid世界将所有事物都打上了标签(每个事物都有自己的SContext),那么SEAndroid就能根据这些SContext来进行统一管理。

SEAndroid就是通过一系列的te文件来管理所有进程和资源的权限,每个te文件里面都有无数条te语句,每条te语句对应一条安全策略。

  • 主体:主体和客体只是一个逻辑上的概念,就跟主谓宾语句:小红在吃米饭,其中主语是小红(活的),宾语是米饭(死的)。同理在Linux世界中,
  • 活的东西只有进程,死的东西是资源。即资源是被使用的东西,进程是使用者,这里的主体就是指使用者。SEAndroid中的主体就是指的进程,
  • 当然可能是单一的进程,也可以是一组具有相同权限的进程,但是它们都对应一个type。
  • 客体:同上客体就是这个被使用者。SEAndroid中的客体就是指的资源(包括普通文件/特殊文件/套接字),当然可能是单一的资源,也可以是一组
  • 相同类型的资源,但是他们都对应一个type。
  • 客体类别:客体与客体类别的概念就类似于Java语言中的object和class,其中class表示一个类,object表示一个实例对象。同样客体和客体类别也是这样
  • 的关系,例如小红在吃米饭,小红在吃鱼肉,米饭和鱼肉都是具体的事物(客体),但是他们却是不一样的类别(客体类别)。SEAndroid中已经为资源
  • 定义了一些客体类别,我们也可以自定义。例如/etc/password是一个普通文件,/atv/socket_0是一个套接字。
  • 访问许可:这个比较好理解,代表对客体的访问权限,例如读写权限,查询发送等权限。这个也是可以自定义的。
  • AV规则:既然已经有了主体和客体,那么就有对应访问规则,又叫AV规则。属于SElinux策略语言的控制部分,即te文件中每一条AV规则语句都需要能够
  • 描述清楚:主体 对 客体 是否具有 访问许可。其实就是te文件里面的allow、neverallow、dontaudit、auditallow等语句。

参考Android安全策略SELinux_诸神黄昏EX的博客-CSDN博客_android selinux配置

注意:在任何情况下,都不应该直接允许域(domain)访问以下通用标签;而应为一个或多个对象创建一个更具体的类型;

  1. socket_device
  2. device
  3. block_device
  4. default_service
  5. system_data_file
  6. tmpfs
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/220432?site
推荐阅读
相关标签
  

闽ICP备14008679号