SElinux 使用和配置

之前这篇文章AOSP安全策略SElinux_android以及问题排查思路过于繁琐。因此直接来个相对实用的。

一、SElinux 规则修改

    SDK 中已经配置有一套合理的 SElinux policy。在 SDK 开发过程中,可以根据需要,编辑规则文件,增加自定义规则。规则中由四个部分组成:**用户**、**角色**、**类型**、**敏感度**。
  • 用户:在 SEAndroid 中第一列安全上下文是用户并且只有一个 u

  • 角色:在 SEAndroid 中第二列表示角色 ,分别为 r:主体(Subject)角色,object_r:客体(Object)角色。

    • u:r:type:s0(对进程)及主动实体。
    • u:object_r:type:s0(对文件/资源)及被动资源。
  • 类型:第三列类型, SEAndroid 确定了上百项不同的策略类型,如设备类型进程类型文件系统类型网络类型IPC 类型等。

  • 安全级别:第四列专为多级安全功能(扩展 MLS)而设计, MLS 是一种访问机制,可增加安全上下文和格式敏感度 [: 类别列表] [-敏感度 [: 类别列表]],例如 s0 - s15: c0 - c1023,而在当前 Android 版本中不需要类别。敏感度和类别组合表示当前的安全级别,数字根据最低和最高级别的安全功能进行确定。此列参数被用于查看 MLS 限制,其中 “15” 和 “1023” 表示最大敏感度和类别。此参数范围可以在 Android.mk 中进行确定, Android 中默认配置为 “1”和 “1024”,代表敏感度只定义了 s0,类别列表定义了 c0-c1023。

1.查看违反规则的方法
dmesg | grep avc #或者在串口 log 中查找关键字 denied,即可看到有违反规则的行为。
2.生成规则
  • 自动生成规则:使用 linux 工具 audit2allow 可以将违反规则的 avc 记录生成放行规则 (适合于 dmesg 所有输出,初期的开发阶段)。

  • 手动生成规则: 比如违反 avc 记录如下:

type=1400 audit(1386760471.880:7): avc: denied { entrypoint } for pid=1227 comm=“init” path=“/sbin/healthd” dev=“rootfs” ino=4396 scontext=u:r:healthd:s0 tcontext=u:object_r:rootfs:s0 tclass=file

关键字对应的属性名:

scontext_name: healthd tcontext_name: rootfs tclass_type: file rules: entrypoint

放行公式:

allow scontext_name tcontext_name:tclass_type rules;

生成 rule 如下:

allow healthd rootfs:file entrypoint;
3.添加规则
  • 编辑 device/{vendor-name}/common/sepolicy 目录下面 TE 格式文件,添加 Step 2 中生成的 rule 到以 **scontext_name **命名的 TE 文件(例如:healthd.te)。
  • 重新编译 Android 就可以生成新的 SElinux policy 固件。
  • 重新烧录后可能会多出一些相关的权限警告,一点一点的添加直到没有错误警告为止。
  • 如在编译过程出现类似如下错误,说明添加的规则和 system/sepolicy 设置的规则冲突。
neverallow on line 269 of system/sepolicy/domain.te (or line 5193 of policy.conf)
violated by allow platform_app unlabeled:dir { create };
4.解决规则冲突
    system/sepolicy 定义通用规则,如果出现 device 规则与其冲突的问题,即 system/sepolicy定义 neverallow 规则,但是 device 规则又要允许访问。这种情况初学者本能的认为需要在system/sepolicy 中的 neverallow 中增加例外规则,如下实例。
    实际上这种做法不妥,在添加 selinux 规则的时候尽量不要违背 system/sepolicy 的 neverallow, system/sepolicy 的neverallow 都是 google 工程师经过深思熟虑设置的规则检验关卡,违背了其规则,证明添加的device 规则不合理。这种情况下一般是没有为 scontext 或者 tcontext 定制化标签导致的,请检查 avc 报错中是否有 default 或者 unlabel 字样。  
neverallow all_untrusted_apps {
  hwservice_manager_type
  -same_process_hwservice
  -coredomain_hwservice
  -hal_configstore_ISurfaceFlingerConfigs
  -hal_graphics_allocator_hwservice
  -hal_omx_hwservice
  -untrusted_app_visible_hwservice
  #相应加一条?
}:hwservice_manager find;

二、添加 sepolicy 示例

下面举例说明如何为 Android 的二进制程序 pz制定 sepolicy 规则,相关规则见

device/{vendor-name}/common/sepolicy/pz.te
  1. type pz domain,domain_deprecated;为 pz进程定义专属 type pz,关联属性 domain。

  2. type pz_exec,exec_type,file_type;为 pz 的二进制文件定义 type pz_exec。

  3. init_daemon_domain(pz);进行进程的 domain transition,当 init 进程 fork 并执行pz_exec 标签对应的可执行文件 pz 时,进程的 domain 转为 pz。

  4. 在对 pz 进行 sepolicy 的策略配置时,发现 pz 会创建文件夹/dev/com.koushikdutta.superuser.daemon 和 sock:/dev/com.koushikdutta.superuser.daemon/server 用于通信。因此需要对这两个对象打上自定义标签,防止发生 neverallow 规则冲突。

    • type pz_daemon_device,dev_type 在 device.te 中定义 pz_daemon_device 用于给文件夹打标签。

    • type pz_socket,file_type,mlstrustedobject; 在 pz.te 中定义 pz_sock 用于给 server打标签。

    • file_type_auto_trans(pz,device,pz_daemon_device); 当 pz 在/dev(context: device)目录下创建文件夹 com.koushikdutta.superuser.daemon 时,给该文件夹打上qw_daemon_device 标签。

    • file_type_atuo_trans(pz,pz_daemon_device,qw_socket); 当 pz 在/dev/com.koushikdutta.superuser.daemon/(context:qw_daemon_device) 下创建文件 server 时,给server 打上 qw_socket 标签。

  5. 接下来编译出固件,根据 dmesg 中的一些 avc 报错添加一些 allow 规则,反复编译几次即可。

按照以上规则不出意外的话就可将 pz 的相关 sepolicy 配置起来。但事与愿违,在添加策略进行验证时,发现一些规则,如: allow pz pz_socket:sock_file create_file_perms;。这些规则添加后:

  • 没有编译出错

  • 没有 neverallow 冲突

  • 成功编译进 policy.conf

但是在验证时,仍然报出相关的 avc denied。经过一番查找,发现该规则需要相应的 mls 权限才可以被授予对应权限。 mls 中:

mlsconstrain{sock_file} {write setattr...}(t2==app_data_file or l1 eq l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject)

简单起见,在定义 pz 时,加上 type qw,domain,domain_deprecated,mlstrustedsubject.注: mlstrustedsubject 和 mlstrustedobject 在 mls 权限控制中拥有至高无上的权利。

三、SElinux 中的特殊符号

  1. te 文件每行末尾以分号 “;” 结束

  2. contexts 文件每行末尾没有分号 “;”

  3. 通配符• *:对应集合内的所有内容。• -:表示集合 A 内去除某项内容 b• ~:表示 ~ 后元素所在集合去除 ~ 后元素剩余的子集

注意:想要在深入了解的请移步至AOSP安全策略SElinux_android以及问题排查思路

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容